/* --sheet is the table's own surface, and it is the page's: the vendor paints .tabulator-table
   a light grey of its own, which made the table a panel sitting on the page instead of the page
   itself. a frozen column still needs it opaque — the rows slide under it. */
:root { --kt: #c0392b; --ok: #1e8449; --bad: #c0392b; --okbg: #d4efdf; --badbg: #f5b7b1; --grid: #000;
        --sheet: var(--pico-background-color); }
body { padding-bottom: 4rem; }
main { width: 100%; max-width: none; padding: 0; margin: 0; }
header.bar, .stats, .hint { padding: .5rem .75rem; }
/* one line, and it scrolls sideways rather than wrapping. nothing in here shrinks: a squeezed
   control is harder to hit than one you scroll to. */
header.bar { display: flex; align-items: center; gap: 1rem; flex-wrap: nowrap; margin: 0;
             overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin;
             scroll-behavior: smooth; }
header.bar > * { flex: 0 0 auto; }
header.bar::-webkit-scrollbar { height: 4px; }
header.bar::-webkit-scrollbar-thumb { background: var(--kt); border-radius: 2px; }

/* ONE control style for the whole bar: every menu, the scope box, пароль, выход and the scroll
   chevrons are the same pill. they are all the same kind of thing to a thumb, so a second style
   would only say they behave differently. */
.bar .nudge,
.controls .menu > summary {
  display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
  height: 2.2rem; padding: 0 1rem; box-sizing: border-box;
  /* pico puts margins on labels and inputs; in a centred row those become four different
     vertical positions for controls that are all the same height */
  margin: 0; vertical-align: middle;
  border: 1px solid rgba(255, 255, 255, .35); border-radius: 999px; background: transparent;
  color: var(--color); font-size: .9rem; line-height: 1; white-space: nowrap;
  text-decoration: none; cursor: pointer;
}
.bar .nudge:hover, .controls .menu > summary:hover { border-color: var(--kt); }

/* the chevrons stay pinned to whichever edge still has something past it — the only hint a
   touch device gets that the bar scrolls — but they are the same pill as everything else */
.bar .nudge { position: sticky; z-index: 15; width: 2.4rem; padding: 0; font-weight: 700;
              background: var(--kt); border-color: var(--kt); color: #fff; }
.bar .nudge.left  { left: 0;  margin-right: -1rem; }
.bar .nudge.right { right: 0; margin-left: -1rem; }
.bar .nudge[hidden] { display: none; }

.tabs { display: flex; gap: .25rem; width: 100%; }
.tabs a { flex: 1; text-align: center; padding: .5rem; text-decoration: none;
          color: var(--color); border: 1px solid var(--muted-border-color); border-radius: var(--border-radius); }
.tabs a.on { background: var(--kt); color: #fff; border-color: var(--kt); }

.controls { display: flex; gap: .4rem; }

/* pico margins and borders a <details>, which lifts the summary inside its own taller box */
.controls .menu { flex: 0 0 auto; margin: 0; padding: 0; border: 0; }
.controls .menu > summary { list-style: none; }
.controls .menu > summary::-webkit-details-marker { display: none; }
.controls .menu > summary::marker { content: ""; }
.controls .menu > summary::after { display: none; }
/* open, or narrowing the screen: the same red, because both mean this button is doing something */
.controls .menu[open] > summary,
.controls .menu.on > summary { background: var(--kt); color: #fff; border-color: var(--kt); }
/* fixed, not absolute: a sideways-scrolling bar clips its own children, so main.js places the
   panel in the viewport under the summary that opened it */
/* a panel lives on <body>, not in the header — main.js moves it there when it opens. inside a
   sideways-scrolling box, even a fixed child can be clipped and re-stacked by that box, which is
   how these ended up behind the page on a phone while looking right on a desktop. out there,
   nothing but the offline bar is above it and nothing can clip it. */
.panel { position: fixed; z-index: 9000; display: none; margin: 0; padding: .25rem; list-style: none;
         min-width: 8rem; background: #1b2129;
         border: 1px solid var(--muted-border-color); border-radius: var(--border-radius);
         box-shadow: 0 8px 24px rgba(0, 0, 0, .55); }
.panel.open { display: block; }
/* the filter is one panel holding two choices, side by side: picking an address and picking a
   day are the same decision, and the second menu used to cover the first one's answer */
.panel.filter { display: none; grid-template-columns: auto auto; gap: .25rem 1rem; }
.panel.filter.open { display: grid; }
.panel.filter ul { margin: 0; padding: 0; list-style: none; }
.panel.filter .cap { margin: .15rem .6rem .25rem; font-size: .7rem; text-transform: uppercase;
                     letter-spacing: .04em; color: var(--muted-color); }
/* the search and the scope narrow the same roster, so they sit under both columns */
.panel.filter .narrow { grid-column: 1 / -1; display: flex; align-items: center; gap: .6rem;
                        padding: .35rem .6rem 0; border-top: 1px solid var(--muted-border-color); }
.panel.filter .narrow .scope { display: inline-flex; align-items: center; gap: .3rem; margin: 0;
                               font-size: .8rem; white-space: nowrap; }
.panel.filter .narrow .scope input { margin: 0; }
/* pico marks every li with a square, and it sets it on the li itself — so list-style on the
   panel lost, and every line in both menus began with a bullet */
.panel li { list-style: none; }
.panel li a { display: block; padding: .35rem .6rem; cursor: pointer; text-decoration: none;
              color: var(--color); border-radius: var(--border-radius); white-space: nowrap; }
.panel li a:hover { background: var(--kt); color: #fff; }

/* the halls the school runs, and the week as seven boxes on one line: a day is a tick, not a
   sentence to type */
.groups { margin: .25rem 0 1rem; padding: 0; }
.groups li { list-style: none; padding: .2rem 0; border-bottom: 1px solid var(--muted-border-color); }
.days { display: flex; flex-wrap: wrap; gap: .75rem; margin-bottom: .75rem; }
.days .day { display: inline-flex; align-items: center; gap: .3rem; margin: 0; }
.days .day input { margin: 0; }

#grid { margin: 0 .75rem; }
.diag { white-space: pre-wrap; font-size: 11px; padding: .5rem; margin: 0; }
.wiki { display: block; width: 100%; max-width: 900px; height: auto; margin: .5rem auto; }
/* without touch-action the browser claims the drag for scrolling and paint never gets a move */
.tabulator-cell.cell { cursor: pointer; user-select: none; touch-action: none; }
.tabulator-cell.cell:hover { background: var(--muted-border-color); }
.tabulator-cell.cell.on { background: rgba(30, 132, 73, .28); }
.tabulator-cell.cell.on::after { content: "✓"; color: var(--ok); font-weight: 700; }
.tabulator-cell.cell.ill { background: rgba(192, 57, 43, .18); }
.tabulator-cell.cell.ill::after { content: "✚"; color: var(--bad); font-weight: 700; }
/* two native pickers, because a phone's own date wheel beats anything drawn here — but sized to
   the line they sit on: a control taller than a row makes every row in the table taller. */
.tabulator-cell a.edit { text-decoration: none; opacity: .55; }
.tabulator-cell a.edit:hover { opacity: 1; }
.sick { display: inline-flex; gap: .15rem; }
.sick input { width: 6.3rem; height: 1.4rem; margin: 0; padding: 0 .15rem; font-size: .65rem;
              line-height: 1; border-radius: 3px; }
.dh { display: inline-flex; align-items: center; gap: .3rem; }
.masstoggle { display: none; margin: 0; }
.tabulator-col:hover .masstoggle { display: inline-block; }

.stats { display: flex; gap: 1.5rem; margin: .25rem 0 .75rem; color: var(--muted-color); }
.stats b { font-weight: 700; }
.ok { color: var(--ok); } .bad { color: var(--bad); }

main.login { max-width: 320px; margin: 4rem auto; padding: 0 1rem; text-align: center; }
.login .logo { display: block; width: 96px; height: auto; margin: 0 auto 1rem; }
.bar .brand { height: 32px; width: 32px; }
/* a wide screen has room to spare, so the mark sits in the middle of it. a phone's bar is full
   and may scroll sideways, where a centred absolute child would drift out of view — so there it
   stays in the row with everything else. */
@media (min-width: 768px) {
  header.bar { position: relative; }
  .bar .brand { position: absolute; left: 50%; transform: translateX(-50%); }
}
/* no auto margins: in a scrolling row they eat the free space and push the rest out of reach */

.bycat p { margin: .6rem 0 .15rem; font-weight: 600; }
.bycat ul { margin: 0 0 .4rem 1.2rem; }
.byname { display: none; }
.lacktoggle:checked ~ .bycat { display: none; }
.lacktoggle:checked ~ .byname { display: table; }

.tablesearch { width: 11rem; margin: 0; padding: .15rem .4rem; font-size: .8rem; }
.tabulator { font-size: .9rem; }

/* drop tabulator's own backgrounds — inherit the page */
.tabulator,
.tabulator-header,
.tabulator .tabulator-header .tabulator-col,
.tabulator-row,
.tabulator-row.tabulator-row-even,
.tabulator-row .tabulator-cell { background: transparent; background-color: transparent; }
/* the vendor paints this one #666 with white text, which is the grey panel the table used to
   sit on. the table is the page: the page's surface, the page's ink. the holder is named here
   because the vendor's own rule names it, and a shorter selector loses the tie. */
.tabulator .tabulator-tableholder .tabulator-table { background-color: transparent; color: inherit; }
/* except the frozen ones: they sit OVER the columns scrolling past them, and the rule above
   left the dates showing through the name they are supposed to be sliding behind */
/* the table's surface, stated here rather than inherited: pico's variables are unset on this
   page and every layer above was transparent, so the only opaque thing was the vendor's own
   .tabulator-table. a frozen column has to carry that same surface — it slides over the
   scrolling ones, and transparent means the dates read straight through the names. */
.tabulator, .tabulator .tabulator-header,
.tabulator .tabulator-header .tabulator-col.tabulator-frozen,
.tabulator .tabulator-row .tabulator-cell.tabulator-frozen { background-color: var(--sheet); }
/* the vendor's header is dark with white type; on the page's own surface that is a row of
   invisible column names and three sort arrows floating alone */
.tabulator .tabulator-header, .tabulator .tabulator-header .tabulator-col { color: inherit; }

/* the dates stay on screen while the roster scrolls under them. sticky rather than a table with
   its own height: tabulator recurses until the stack gives out when a maxHeight meets a frozen
   column, and the frozen column is what keeps the name in view sideways. */
.tabulator .tabulator-header { position: sticky; top: 0; z-index: 12; }
/* sticky sticks to the nearest ancestor that clips, and tabulator's own box clips: with that
   box left visible, the header rides the page instead and the dates stay on screen while the
   roster scrolls under them. its own maxHeight is not an option — that plus a frozen column
   loops its layout until the stack ends. */
.tabulator { overflow: visible; }

/* one line per row, everywhere. a wrapped cell doubles a row's height and the eye loses the
   line it was reading; the grid already scrolls sideways, which is the cheaper trade. */
.tabulator-cell, .tabulator-col, .debts td, .debts th { white-space: nowrap; }

table { font-size: .9rem; }
table th, table td { border-color: var(--grid); }

/* tables: bold text, never recolor the font (no green/red) */
table th, table td, .tabulator-cell { font-weight: 700; }
table .ok, table .bad, .tabulator-cell.ok, .tabulator-cell.bad { color: inherit; }
.avatar { width: 38px; height: 38px; border-radius: 50%; object-fit: cover; display: grid; place-items: center; background: var(--kt); color: #fff; font-weight: 600; }
.avatar.big { width: 96px; height: 96px; font-size: 2.2rem; }
/* the belt itself, and the stripes sewn across its end — on the belt, the way they are worn,
   not a second symbol beside it */
.belt { position: relative; display: inline-block; width: 26px; height: 13px; border-radius: 2px;
        background: var(--c); border: 1px solid rgba(0, 0, 0, .45); vertical-align: middle; }
.belt i { position: absolute; top: 0; bottom: 0; width: 2px; background: #111; opacity: .85; }
.belt i:nth-child(1) { right: 3px; }
.belt i:nth-child(2) { right: 7px; }
.belt i:nth-child(3) { right: 11px; }

.deck { max-width: 420px; margin: 1rem auto; text-align: center; }
.cardstack { position: relative; height: 340px; margin: 1rem 0; }
.card { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
        justify-content: center; gap: .75rem; cursor: grab; touch-action: none; user-select: none;
        border: 1px solid var(--muted-border-color); border-radius: 1rem; background: var(--card-background-color); }
.card h3 { margin: 0; } .card p { margin: 0; color: var(--muted-color); }
/* where and when this one trains, under the name: lowercase because it is a label, not a title */
.card .where { text-transform: lowercase; font-size: .85rem; letter-spacing: .02em; }
.hint { color: var(--muted-color); font-size: .85rem; }
/* it toggles on every tap as the queue fills and drains — in the flow that reflowed the whole
   page under the finger, so it overlays the bottom edge instead of pushing anything */
#opstatus { position: fixed; left: 0; right: 0; bottom: 0; z-index: 20; text-align: center;
            background: var(--badbg); color: #000; }

.dir-received { color: var(--ok); font-weight: 600; }
.dir-owed     { color: var(--bad); font-weight: 600; }
tr.owe td { background: var(--badbg); }

details.add > summary { display: inline-block; width: auto; padding: .4rem 1rem; border-radius: var(--border-radius); background: var(--kt); color: #fff; }
details.add article { margin-top: .5rem; }
