/* QuantCrew V2 — blocky, Excel-like tool styling on the QuantSuite tokens
   (gold #e3a93b on base #0A0D13; square corners, dense grids).

   TYPE SCALE (design pass, 2026-08-08 — DESIGN-BRIEF.md item 1). Six UI
   sizes and nothing else:
     10.5px  captions — uppercase labels, column heads
     11.5px  fine print — metas, counts, hints
     12.5px  secondary — table cells, buttons, chips
     14px    body (the root size)
     16px    emphasis — panel titles, names
     19px    page titles
   Outside the scale, deliberately: the board's micro sizes (8.5–10.5px,
   density is the point) and the mono KPI numerals (22/26px). Don't invent
   a seventh size — pick the nearest of these. */
/* THEME (owner, 2026-08-09: "add a button somewhere to switch between light
   and dark mode for the whole app"). Two palettes over ONE set of tokens —
   every rule below reads tokens and never a raw hex, so a surface only has
   to be designed once. Dark stays the default and the identity.

   Light is a designed second surface, not an inversion. The two rules that
   matter:
     · Gold is a FILL in dark and INK in light. #e3a93b on white is 1.9:1,
       so light steps it to #9a6c14 (4.6:1) and flips --on-gold to white.
       Anything painting gold-on-gold-wash needs both to move together.
     · Every status colour (red/green/blue/violet) is text somewhere, so
       light darkens all of them rather than reusing the dark values.
   --line-2 is the stronger rule: the board's week divider, which is drawn
   into a gradient by views.py and board.js and must follow the theme. */
:root {
  color-scheme: dark;
  --sans: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", Consolas, monospace;
  --ease: .14s ease;  /* the one hover/selection timing (brief item 8) */

  --gold: #e3a93b; --gold-bright: #f6c667; --gold-deep: #a87a24;
  --on-gold: #15120c;                     /* ink that sits ON a gold fill */
  /* THE SAME GOLD, RENDERED WHERE IT HAS TO BE READ. On this ground one
     colour can do both jobs, so these two are exactly --gold and
     --gold-bright here and every rule below is unchanged by their existence.
     They earn their keep in light — see the note over that palette. */
  --gold-ink: #e3a93b;                    /* text, glyphs, focus, selection */
  --gold-hover: #f6c667;                  /* a gold FILL under the pointer */
  /* Ink for a chip painted with a CREW's own colour. Constant in both
     themes on purpose: --c comes from the database and does not know a
     theme exists, so flipping the ink to white with the rest of the
     palette put white RC-codes on Main Unit's #f6c667. */
  --on-data: #15120c;
  --gold-wash: #161408;                   /* solid gold-tinted surface */
  --gold-tint: rgba(227, 169, 59, .055);  /* the barely-there wash */
  --bg: #0A0D13; --panel: #11151d; --panel-2: #171c26; --raised: #1d2330;
  --bg-alt: #0d1119;                      /* weekends, alternate cells */
  --line: #232a38; --line-2: #2c3547;
  /* --text-faint is the caption tier. Both themes hold it at the shallowest
     grey that still clears 4.5:1 on --panel — quiet is the brief, unreadable
     isn't, and the old #667080 / #7c8794 pair measured 3.7:1 on every page. */
  --text: #e8e6e1; --text-dim: #9aa3af; --text-faint: #7b8593;
  --green: #46c08a; --on-green: #06120c; --red: #ef5d6c;
  --blue: #5aa6e0;                        /* kit, diversions, "elsewhere" */
  --violet: #7e5fa8; --violet-2: #c77dff;
  /* The dashboard load bars have their own fills. This was the FIRST place
     the one-token problem showed up: light's --gold was #8f6412, tuned to be
     readable as ink, and painted across a 60px column it read as mud rather
     than as gold — so an area colour was carved off for it. --gold is an
     area colour in both themes now (see the light palette), which is the same
     answer applied everywhere; these two stay because --blue still needs the
     treatment and the pair is tuned together. */
  --load-rig: #e3a93b; --load-shoot: #5aa6e0;
  --scrim: rgba(4, 6, 10, .72);           /* modal backdrop */
  --shadow: 0 3px 14px rgba(0, 0, 0, .5);
  --shadow-sm: none;
  /* the board's weekend shading — painted into a gradient by views.py and
     board.js, so it has to be a token they can name rather than a literal */
  --we-shade: rgba(255, 255, 255, .035);
  /* today's column on the board — same deal, named because board.js paints it
     into the track gradient. Weaker than the weekend shade on purpose: the
     2px gold edge does the finding, the wash only holds the column together */
  --today-wash: rgba(227, 169, 59, .07);
  /* The dropdown caret we draw ourselves (see "quiet cells" below). A data
     URI cannot read a token, so the hex has to live here WITH the palette
     rather than in a rule — same discipline, one level up. Square-cut and
     1.6px to sit with the blocky grammar, not the OS's rounded chevron. */
  --caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1 5 5 9 1' fill='none' stroke='%237b8593' stroke-width='1.6'/%3E%3C/svg%3E");
  --caret-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1 5 5 9 1' fill='none' stroke='%23f6c667' stroke-width='1.6'/%3E%3C/svg%3E");
  /* THE TICK for a branded checkbox, drawn the same way --caret above
     draws the select's chevron. --on-gold is #15120c in BOTH themes,
     so one colour is right in both — checked, not assumed. */
  --tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='9' viewBox='0 0 11 9'%3E%3Cpath d='M1 4.7 4.1 7.6 10 1.3' fill='none' stroke='%2315120c' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* GOLD IS GOLD HERE TOO (owner, 2026-09-07: "the main Quant Crew gold becomes
   muddy brown in light mode"). It did, and the reason is worth keeping: this
   palette had one --gold doing two incompatible jobs. #e3a93b is 2.1:1 on
   white, so anything gold that had to be READ was unreadable — and the fix
   applied was to darken --gold itself to #8f6412, which does read (5.3:1) but
   is a brown. Every FILL went brown with it: the primary buttons, the board's
   view toggles, the wordmark's square.

   So the two jobs are two tokens now, and the split is the same one the load
   bars already needed (see --load-rig below, which was carved off for exactly
   this reason).

     --gold       AREAS. Fills, washes, swatches, bars, 3px accent rails.
                  #e3a93b in both themes — it is the brand, and a brand does
                  not have two colours. Dark ink on it reads 8.9:1, better
                  than the white-on-brown it replaces.
     --gold-ink   ANYTHING THAT MUST BE READ: text, glyphs, and the 1-2px
                  lines that are the only signal a thing is focused, selected
                  or active. #8f6412 — the value light was already using, so
                  nothing legible today changes.
     --gold-deep  BORDERS. #c69324 -> #b8851c, because a gold fill on a white
                  page is only 2.1:1 and a primary button needs an edge that
                  clears 3:1 against the page. 3.28:1, and it strengthens
                  input focus and .btn:hover on the way past.
     --gold-hover a gold fill under the pointer. Light DEEPENS (#cf9020)
                  where dark brightens, which is this palette's habit.

   In dark --gold-ink and --gold-hover ARE --gold and --gold-bright, so every
   rule that moved between them renders identically there. That is deliberate:
   dark had nothing wrong with it and this change must not be able to touch
   it. */
:root[data-theme="light"] {
  color-scheme: light;
  --gold: #e3a93b; --gold-bright: #7d5610; --gold-deep: #b8851c;
  --gold-ink: #8f6412; --gold-hover: #cf9020;
  --on-gold: #15120c;
  --gold-wash: #fbf3e0;
  /* LEFT ON THE OLD HUE ON PURPOSE, here and at --today-wash below. Both are
     washes at 7-9% alpha over a near-white surface, where #9a6c14 and #e3a93b
     land within a shade of each other; rebasing them would repaint every
     selection tint in the app to buy a difference nobody can see. They read
     as warm, not as brown, which is what the complaint was about. */
  --gold-tint: rgba(154, 108, 20, .07);
  --bg: #eef0f4; --panel: #ffffff; --panel-2: #f2f4f7; --raised: #ffffff;
  --bg-alt: #e7eaf0;
  --line: #d8dde5; --line-2: #bcc4d0;
  --text: #1b2530; --text-dim: #5a6673; --text-faint: #6b7684;
  --green: #0f6b45; --on-green: #ffffff; --red: #c22c39;
  --blue: #1f6fc4;
  --violet: #6a4b96; --violet-2: #7c46c4;
  --load-rig: #d3941f; --load-shoot: #3d8ed6;
  --scrim: rgba(20, 26, 34, .42);
  --shadow: 0 6px 20px rgba(16, 24, 32, .16);
  --shadow-sm: 0 1px 2px rgba(16, 24, 32, .05);
  --we-shade: rgba(22, 32, 48, .05);      /* weekends darken here, not lighten */
  --today-wash: rgba(154, 108, 20, .09);  /* gold is ink here, so a touch more */
  /* Light needs its own caret: gold is INK here, so the open state darkens
     rather than brightens — the dark file's #f6c667 is invisible on white. */
  --caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1 5 5 9 1' fill='none' stroke='%236b7684' stroke-width='1.6'/%3E%3C/svg%3E");
  --caret-on: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1 5 5 9 1' fill='none' stroke='%237d5610' stroke-width='1.6'/%3E%3C/svg%3E");
  /* THE TICK for a branded checkbox, drawn the same way --caret above
     draws the select's chevron. --on-gold is #15120c in BOTH themes,
     so one colour is right in both — checked, not assumed. */
  --tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='9' viewBox='0 0 11 9'%3E%3Cpath d='M1 4.7 4.1 7.6 10 1.3' fill='none' stroke='%2315120c' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
* { box-sizing: border-box; }
/* The hidden attribute must ALWAYS win. Any display: block/flex/grid rule
   silently beats it otherwise — that bug has bitten this app four times now
   (crew members, the fill dialog, the export toolbar, and the modal's
   6th-day + pre-light rows, which were showing on every booking). */
[hidden] { display: none !important; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: var(--sans); font-size: 14px; line-height: 1.45;
}
/* A little motion, precisely placed: every interactive surface eases its
   hover/selection change in the same 140ms. Nothing animates position. */
a, button, .btn, .mini, .fchip, .crewchip, .supchip, .attn, .rchip,
input, select, textarea { transition: color var(--ease), background-color var(--ease),
  border-color var(--ease), box-shadow var(--ease), opacity var(--ease); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
/* keyboard focus is visible, mouse focus is quiet */
:focus-visible { outline: 1px solid var(--gold-ink); outline-offset: 1px; }
:focus:not(:focus-visible) { outline: none; }
a { color: var(--gold-bright); text-decoration: none; }
h1 { font-size: 19px; font-weight: 600; margin: 0 0 10px; }
h2 { font-size: 14px; font-weight: 600; margin: 18px 0 8px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-dim); }
h3 { font-size: 16px; margin: 0 0 10px; }
code { font-family: var(--mono); font-size: 12.5px; background: var(--panel-2); padding: 2px 6px; }

.top {
  display: flex; align-items: center; gap: 22px;
  padding: 8px 16px; border-bottom: 1px solid var(--line); background: var(--panel);
  /* Stays visible while a page scrolls (owner, carried from the Help mock-up).
     Harmless on the board page too: body.boardpage locks the outer scroll
     itself (overflow: hidden), so there's nothing for this to stick against
     there. z-index sits above the board's own sticky row/column headers (up
     to 7) but below the modal backdrop (40), so a modal still overlays it. */
  position: sticky; top: 0; z-index: 20;
}
.brand { color: var(--text); font-size: 16px; display: flex; align-items: center; gap: 8px; }
.brand b { color: var(--gold-ink); font-weight: 700; }
.dot { width: 9px; height: 9px; background: var(--gold); display: inline-block; }
.dot.big { width: 12px; height: 12px; margin-right: 8px; }
.prodnav, .usernav { display: flex; gap: 2px; align-items: center; flex-wrap: wrap; }
.prodnav a { color: var(--text-dim); padding: 6px 11px; border: 1px solid transparent; }
.prodnav a.on { color: var(--gold-ink); background: var(--panel-2); border-color: var(--line); border-bottom-color: var(--gold-ink); }
.prodnav a:hover { color: var(--text); }
.usernav { margin-left: auto; gap: 14px; }
.usernav a { color: var(--text-dim); }
/* The theme switch shows the surface you'd GET, not the one you're on:
   a sun while dark, a moon while light. */
.themetog { display: inline-flex; align-items: center; justify-content: center;
  width: 27px; height: 25px; padding: 0; background: none; cursor: pointer;
  border: 1px solid transparent; color: var(--text-dim); }
.themetog:hover { color: var(--gold-ink); background: var(--panel-2); border-color: var(--line); }
.themetog .ti { width: 15px; height: 15px; }
.themetog .sun { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; }
.themetog .sun circle { fill: currentColor; stroke: none; }
.themetog .moon { fill: currentColor; stroke: none; }
:root[data-theme="dark"] .themetog .moon { display: none; }
:root[data-theme="light"] .themetog .sun { display: none; }
.who { color: var(--text-faint); }
.linkbtn { background: none; border: none; color: var(--text-dim); cursor: pointer; font: inherit; padding: 0; }
.linkbtn:hover { color: var(--text); }
.inline { display: inline; }

.wrap { max-width: 1720px; margin: 0 auto; padding: 14px 16px; }
.messages { max-width: 1720px; margin: 10px auto 0; padding: 0 16px; }
/* Routine messages are toasted instead (base.html + app.js), so this container
   is often emitted with nothing in it. Without this it would still hold its
   margin open — a strip of empty page where a banner used to be. */
.messages:empty { display: none; }
.msg { background: var(--panel-2); border: 1px solid var(--gold-deep); padding: 8px 12px; margin-bottom: 6px; }
/* Only errors and warnings reach the banner now, so it may as well look like
   what it is rather than borrowing the gold used for everything else. */
.msg.error { border-color: var(--red); }
.msg.warning { border-color: var(--gold-bright); }

.btn {
  display: inline-block; background: var(--raised); color: var(--text);
  border: 1px solid var(--line); padding: 6px 13px; font: inherit; cursor: pointer;
}
.btn:hover { border-color: var(--gold-deep); }
.btn.gold { background: var(--gold); border-color: var(--gold); color: var(--on-gold); font-weight: 600; }
.btn.gold:hover { background: var(--gold-hover); }
.btn.danger { border-color: var(--red); color: var(--red); background: none; }
.btn.sm { padding: 3px 9px; font-size: 12.5px; }
.btn.wide { display: block; width: 100%; text-align: center; margin: 8px 0; }
.mini { background: none; border: 1px solid var(--line); color: var(--text-dim);
        font-size: 11.5px; padding: 1px 7px; cursor: pointer; }
.mini:hover { color: var(--text); border-color: var(--gold-deep); }
.mini.danger { color: var(--red); }

.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; margin: 14px 0; }
.card { background: var(--panel); border: 1px solid var(--line); padding: 14px; color: var(--text); }
.card:hover { border-color: var(--gold-deep); }
.cardname { font-weight: 600; font-size: 16px; }
.cardmeta { color: var(--text-faint); font-size: 12.5px; margin-top: 4px; }
/* Empty states are a designed moment, not a shrug (brief item 5): a dashed
   plot of ground with the next step written on it. The control that fills it
   is always right beside it — the copy points there. */
.empty { display: block; border: 1px dashed var(--line); background: var(--panel);
  color: var(--text-dim); padding: 16px 18px; font-size: 12.5px; }
.empty b { color: var(--text); display: block; margin-bottom: 2px; font-size: 14px; }
span.empty, .supchips .empty { display: inline; border: none; background: none;
  padding: 0; color: var(--text-faint); }  /* inline "everyone's seated" notes stay quiet */
.dim { color: var(--text-faint); font-size: 12.5px; }
.note { color: var(--text-faint); font-size: 12.5px; }

/* ---- collapsible guidance (templates/qc/hint_panel.html, static/hints.js) --
   Owner, 2026-09-05: the instruction strips are "useful at first but consume
   unnecessary space once the user knows the workflow." Collapsed, the whole
   panel is one small line — "› Board help" — and on the board that hands the
   height straight to the schedule, since body.boardpage never scrolls.

   The summary is styled as a quiet label rather than a button on purpose: it
   sits under a working screen and should not compete with anything on it.
   inline-flex, so the target is the label and its caret and stops there — on
   the board this row also holds the zoom control, and a full-width summary
   would make the empty space beside it swallow the hints. */
.qchint { margin: 0; }
.qchint > .qchint-t {
  display: inline-flex; align-items: baseline; gap: 6px; cursor: pointer;
  list-style: none;                       /* the disclosure triangle, hidden */
  color: var(--text-faint); font-size: 11.5px;
  text-transform: uppercase; letter-spacing: .4px; padding: 2px 0;
}
.qchint > .qchint-t::-webkit-details-marker { display: none; }
.qchint > .qchint-t:hover { color: var(--text-dim); }
/* Keyboard focus has to be visible on something this quiet — the summary IS
   the control, and it is the only way to it without a pointer. */
.qchint > .qchint-t:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 2px; }
.qchint-c { color: var(--gold-ink); transition: transform .15s; font-size: 13px; line-height: 1; }
.qchint[open] > .qchint-t .qchint-c { transform: rotate(90deg); }
.qchint-b { margin-top: 3px; }
/* The body's own .note keeps its size and colour; what it loses is the top
   margin it no longer needs under a caption. */
.qchint-b > .note { margin: 0; }
/* In the board's footer the panel takes the slack the hint paragraph used to,
   so the zoom control keeps its place on the right — and, collapsed, the whole
   row is the height of one small line. */
.boardfoot > .qchint { flex: 1 1 0; min-width: 0; }
/* the saved pulse: the row itself confirms, not just the toast */
@keyframes qcsaved { from { background-color: color-mix(in srgb, var(--gold) 11%, transparent); }
                     to { background-color: transparent; } }
form.qcsaved, .qcsaved { animation: qcsaved .9s ease-out; }
.swatch { display: inline-block; width: 18px; height: 18px; border: 1px solid var(--line); }

.authcard { max-width: 380px; margin: 8vh auto; background: var(--panel); border: 1px solid var(--line); padding: 26px; }
.authcard .sub { color: var(--text-dim); margin-top: -6px; }
.or { text-align: center; color: var(--text-faint); margin: 10px 0; }
/* ---- the second door on the sign-in page (public signup, 2026-09-04) ----
   A ruled divider rather than a line of centred text, because Create an
   account is not a footnote under Sign in — for everybody who has never been
   here before it is the whole page. The rule is drawn as two borders either
   side of the label so it needs no pseudo-element trickery and no fixed
   width. */
.authsep { display: flex; align-items: center; gap: 10px; margin: 18px 0 10px;
  color: var(--text-faint); font-size: 11.5px; }
.authsep::before, .authsep::after { content: ""; flex: 1;
  border-top: 1px solid var(--line); }
/* ---- the two steps of onboarding, named before they are asked for --------
   The button says Continue, and a person is entitled to know what they are
   continuing to. Two items; if this ever needs a third, the answer is
   probably that the third thing does not belong in onboarding. */
.obsteps { list-style: none; margin: 16px 0; padding: 0; display: grid; gap: 6px; }
.obsteps li { display: flex; flex-direction: column; padding: 8px 11px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text-faint); }
.obsteps li.on { border-color: var(--gold-deep); background: var(--gold-tint); }
.obsteps li b { color: var(--text-dim); font-size: 12.5px; }
.obsteps li.on b { color: var(--text); }
.obsteps li em { font-style: normal; font-size: 11.5px; }

.formpage { max-width: 460px; }
form label { display: block; margin: 10px 0 4px; color: var(--text-dim); }
label.check { display: flex; align-items: center; gap: 8px; }
label.check input { width: auto; }
input, select, textarea {
  width: 100%; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); padding: 6px 9px; font: inherit;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--gold-deep); }

/* ---- A select wears the app's clothes, not the OS's --------------------
   `background: var(--panel-2)` above colours the FIELD and not the CONTROL.
   With appearance left at auto, Windows/Chrome still draws its own dropdown
   button, so a branded dark field ended in a light-grey OS chevron box —
   which is exactly the mismatch reported. It had already been solved for
   management rows (.qcells, further down) and nowhere else, which is why
   Setup's quiet cells looked right while the booking, calendar, equipment,
   labour, exports and invite pickers did not.

   So the switch-off belongs at the root, and every select draws the same
   caret the quiet cells draw, from the same --caret tokens, which already
   flip with the theme. Hover lifts the border to --line-2 and focus turns it
   gold — the same two states .qcsel-btn uses, so the native control and the
   searchable picker now read as one family.

   [multiple] and size>1 are excluded: those render as list boxes, and a
   chevron on a list box points at nothing.

   THE POPUP IS ALREADY OURS — :root sets color-scheme (dark, or light with
   the theme), which is what makes Chrome render the option list, its
   scrollbar and its highlight on the right side of the fence. The option
   colours below take it the last step to --raised, the ground .qcsel-pop
   uses. They are set as a PAIR so a platform that honours one and not the
   other still cannot produce dark-on-dark. */
select:not([multiple]) {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 26px;
  background-image: var(--caret);
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 9px 6px;
}
select:not([multiple]):hover { border-color: var(--line-2); }
select:not([multiple]):focus { background-image: var(--caret-on); }
/* size="4" and friends are a list, not a dropdown. */
select[size]:not([size="1"]) { padding-right: 9px; background-image: none; }
select option { background: var(--raised); color: var(--text); }

/* Disabled reads as unavailable rather than merely empty — and background
   COLOR, not the shorthand, so a disabled select keeps its caret instead of
   losing the only thing that says it is a dropdown at all. */
input:disabled, select:disabled, textarea:disabled {
  color: var(--text-faint); background-color: var(--panel);
  border-color: var(--line); cursor: not-allowed;
}
select:disabled:hover { border-color: var(--line); }

input[type="color"] { padding: 2px; height: 32px; width: 44px; }
input[type="number"] { width: 74px; }
ul.errorlist { color: var(--red); margin: 4px 0; padding-left: 18px; font-size: 12.5px; }
.invitebox { background: var(--panel-2); border: 1px solid var(--gold-deep); padding: 12px; margin-bottom: 14px; word-break: break-all; }

/* ---- Delete a production ----
   The only irreversible screen in the app, so it is allowed to look like it:
   red rather than gold, because gold means "go on then" everywhere else and
   this is the one button that should not feel encouraging. */
.delprod { max-width: 560px; }
.delwarn { border: 1px solid var(--red); border-left: 3px solid var(--red);
  background: color-mix(in srgb, var(--red) 8%, transparent);
  padding: 12px 14px; line-height: 1.55; margin: 14px 0; }
.delwarn b { color: var(--text); }
.delcount { list-style: none; margin: 0 0 18px; padding: 0;
  display: grid; gap: 3px; font-size: 12.5px; color: var(--text-dim); }
.delcount b { color: var(--text); font-family: var(--mono); }
.delprod label { font-size: 12.5px; }
.delprod label b { color: var(--text); }
.delactions { display: flex; gap: 8px; align-items: center; margin-top: 14px; }
.btn.danger[disabled] { opacity: .4; cursor: not-allowed; }
.delzone { margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--line); }
.delzone a { color: var(--red); font-size: 12.5px; }

/* ---- New production: the two ways to start ----
   Built from the idioms already in this file rather than invented: choices
   are blocky panels that take a gold inset edge when live (the rail's .on),
   the explanatory block wears the gold left border of .suhow, and the type
   sits on the six-step scale — 14 for the choice, 12.5 for its line, 11.5
   for the fine print under a tick. No italics: nothing else in the app
   explains itself in italics, which is most of why this page read as
   somebody else's screen. */
.newprod { max-width: 640px; }
.startmode { border: 0; padding: 0; margin: 20px 0 0; }
.startmode legend { padding: 0; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-faint); }
.startmode > .check { align-items: flex-start; gap: 11px; cursor: pointer;
  padding: 11px 13px; margin-top: 8px;
  border: 1px solid var(--line); background: var(--panel); }
.startmode > .check:hover { background: var(--panel-2); }
/* the live choice, marked the way the setup rail marks its section */
.startmode > .check:has(input:checked) { border-color: var(--gold-deep);
  background: var(--gold-tint); box-shadow: inset 3px 0 0 var(--gold); }
.startmode .check input[type="radio"] { width: auto; margin-top: 3px; flex: 0 0 auto; }
.startmode > .check b { display: block; font-size: 14px; }
/* display:block is not cosmetic — as inline elements the label and its
   explanation rendered as one run-on sentence ("Start from scratchMain Unit
   and Rigging Unit…"). */
.startmode em, .copyticks em { display: block; font-style: normal;
  color: var(--text-faint); line-height: 1.5; margin-top: 3px; }
.startmode > .check em { font-size: 12.5px; }

.copypanel { margin: 10px 0 0 32px; padding: 13px 15px;
  background: var(--bg-alt); border: 1px solid var(--line);
  border-left: 3px solid var(--gold); }
.copypanel > label { margin-top: 0; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-faint); }
.copypanel select { width: 100%; }
.copypanel .note { margin: 12px 0 0; }
.copyticks { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.copyticks .check { align-items: flex-start; gap: 9px; padding: 6px 7px; cursor: pointer; }
.copyticks .check:hover { background: var(--panel-2); }
.copyticks .check input[type="checkbox"] { width: auto; margin-top: 3px; flex: 0 0 auto; }
.copyticks .check b { display: block; font-size: 12.5px; font-weight: 600; }
.copyticks em { font-size: 11.5px; }

.table { width: 100%; border-collapse: collapse; background: var(--panel); border: 1px solid var(--line); }
.table th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px;
            color: var(--text-faint); padding: 7px 10px; border: 1px solid var(--line); background: var(--panel-2); }
.table td { padding: 7px 10px; border: 1px solid var(--line); vertical-align: top; }
.verb { color: var(--text-faint); }
.diff { font-family: var(--mono); font-size: 11.5px; color: var(--text-dim); }

/* management grids (Units / Locations / Roles) — Excel-ish, fill the page */
.mgrid { border: 1px solid var(--line); background: var(--panel); width: 100%; }
.mhead, .mline { display: grid; gap: 10px; align-items: center; padding: 7px 12px;
                 border-bottom: 1px solid var(--line);
                 grid-template-columns: minmax(220px, 2fr) minmax(140px, 1fr) 120px 110px minmax(160px, auto); }
.mgrid.narrow .mhead, .mgrid.narrow .mline { grid-template-columns: minmax(240px, 2fr) 160px 130px minmax(160px, auto); }
.mgrid.roles .mhead, .mgrid.roles .mline { grid-template-columns: minmax(220px, 2fr) minmax(170px, 1fr) 150px 120px minmax(150px, auto); }
.mhead { background: var(--panel-2); font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-faint); }
.mline:hover { background: var(--panel-2); }
.mline input[type="color"] { width: 44px; }
.mline .actions { display: flex; gap: 4px; justify-content: flex-end; }
.addrow { display: flex; gap: 8px; align-items: center; width: 100%; max-width: 900px; }
.addrow input, .addrow select { width: auto; flex: 1; }
.addrow input[type="color"] { flex: 0 0 44px; }

/* crew cards */
.crewcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); gap: 12px; }
.crewcard { background: var(--panel); border: 1px solid var(--line); border-top: 3px solid var(--c, var(--gold)); padding: 10px; }
.crewhead { display: flex; gap: 6px; align-items: center; margin-bottom: 8px; }
.crewhead .crewname { font-weight: 600; }
.seats { border-top: 1px solid var(--line); }
.seat { display: flex; gap: 6px; align-items: center; padding: 4px 0; border-bottom: 1px solid var(--line); }
.seat.tbc .seatpos { color: var(--text-dim); }
.seat.tbc select { border-style: dashed; color: var(--text-dim); }
.seatpos { flex: 0 0 128px; font-size: 12.5px; }
.inlineform { display: inline; flex: 0 0 auto; }
.inlineform.grow, .grow { flex: 1; }
.star { background: none; border: none; color: var(--gold-ink); cursor: pointer; font-size: 16px; padding: 0 2px; }
.addseat { display: flex; gap: 6px; margin-top: 8px; }

/* ---- THE BOARD (V1-style, blocky) ---- */
.boardbar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 8px; }
.boardbar h1 { margin: 0; }
.rangelabel { color: var(--gold-bright); font-weight: 600; }
.weeksform { display: flex; gap: 6px; align-items: center; }
.weeksform label { display: flex; gap: 6px; align-items: center; margin: 0; }
.chipbar { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.chiplabel { color: var(--text-faint); font-size: 12.5px; }
.crewchip { display: inline-flex; gap: 7px; align-items: center; border: 1px solid var(--line);
            background: var(--panel-2); padding: 3px 11px 3px 4px; font-size: 12.5px;
            cursor: grab; user-select: none; }
.crewchip:hover { border-color: var(--gold-deep); }
.crewchip:active { cursor: grabbing; }
.crewchip.on { border-color: var(--gold-ink); box-shadow: 0 0 0 1px var(--gold-ink); color: var(--gold-bright); }
.crewchip .ccode { background: var(--c); color: var(--on-data); font-weight: 700; font-size: 10.5px;
                   font-family: var(--mono); padding: 2px 5px; }
/* A LOCATION chip, dragged onto a crew row in the crews view. Deliberately
   uncoloured: on this board colour means CREW — blocks are painted with it in
   both views — so a coloured location chip would say something untrue at a
   glance. The code block stays, because the initials are what you read when
   the bar is full. */
.crewchip.loc .ccode { background: var(--line-2); color: var(--text); }

/* The board page is a fixed viewport: the schedule is its own scroll window
   (both axes); the page itself never scrolls. */
body.boardpage { height: 100vh; overflow: hidden; display: flex; flex-direction: column; }
body.boardpage .wrap { flex: 1; display: flex; flex-direction: column; min-height: 0;
                       max-width: none; width: 100%; }
body.boardpage .boardbar, body.boardpage .note, body.boardpage .boardfoot { flex: 0 0 auto; }
.boardfoot { display: flex; gap: 20px; align-items: flex-start; margin-top: 8px; }
/* beats body.boardpage .note above — inside the footer the hints take the
   slack so the zoom control keeps its place on the right */
body.boardpage .boardfoot .note, .boardfoot .note { flex: 1 1 0; min-width: 0; margin: 0; }
@media (max-width: 900px) { .boardfoot { flex-direction: column; } }
/* the panel + its zoom control, sized to the schedule (board.js hug()) */
.boardwrap { flex: 1 1 auto; min-height: 0; position: relative; display: flex; }
.boardx { overflow: auto; flex: 1 1 auto; min-width: 0;
          border: 1px solid var(--line); background: var(--panel); position: relative;
          overscroll-behavior: contain; }
.binner { position: relative; }
.bhead { position: sticky; top: 0; z-index: 6; background: var(--panel-2); }
.bh { display: flex; }
.bcorner { flex: 0 0 170px; position: sticky; left: 0; z-index: 7; background: var(--panel-2);
           border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
           font-size: 11.5px; color: var(--text-faint); padding: 4px 8px; }
.bstrip { display: flex; }
.bweek { border-right: 1px solid var(--line-2); border-bottom: 1px solid var(--line);
         font-size: 11.5px; font-weight: 600; padding: 3px 8px; white-space: nowrap; overflow: hidden; }
.bweek span { font-weight: 400; color: var(--text-faint); margin-left: 6px; font-size: 10.5px; }
.bday { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
        text-align: center; font-size: 10.5px; padding: 2px 0 3px; color: var(--text-dim);
        font-family: var(--mono); }
.bday span { display: block; font-size: 9px; color: var(--text-faint); }
.bday.we { background: var(--bg-alt); }
.bday.today { color: var(--gold-ink); box-shadow: inset 0 -2px 0 var(--gold-ink); }

.brow { display: flex; }
.rowlbl { flex: 0 0 170px; position: sticky; left: 0; z-index: 3; background: var(--panel-2);
          border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 3px 8px; }
.rowlbl b { display: block; font-size: 12.5px; }
.rowlbl span { font-size: 10.5px; color: var(--text-faint); text-transform: uppercase; letter-spacing: .4px; }
.track { position: relative; flex: 0 0 auto; border-bottom: 1px solid var(--line); overflow: hidden; }

/* ---- find a row, and get to today --------------------------------------
   Both live in the board bar, which is already busy, so they are sized to sit
   with the toggle groups rather than announce themselves. The find box only
   earns its width while it is being used. */
.rowfind { display: inline-flex; align-items: center; gap: 7px; }
.rowfind input { width: 148px; padding: 5px 9px; font-size: 12.5px;
                 background: var(--panel-2); border: 1px solid var(--line);
                 color: var(--text); transition: width .16s ease, border-color .16s; }
.rowfind input::placeholder { color: var(--text-faint); }
.rowfind input:focus { width: 216px; outline: none; border-color: var(--gold-deep); }
/* Safari/Chrome put a native clear button in a search field that fights the
   Esc-to-clear behaviour and does not match anything else here. */
.rowfind input::-webkit-search-cancel-button { display: none; }
.rfcount { font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px;
           color: var(--text-faint); white-space: nowrap; }
.rfcount[hidden] { display: none; }
.rfcount.none { color: var(--red); }
/* Filtered-out rows leave the flow entirely: tracks() reads offsetWidth, so a
   hidden row drops out of layout, lane fitting and drag without any of them
   needing to know this feature exists. */
.brow.rowhide { display: none; }
#todaybtn { white-space: nowrap; }


/* There is deliberately no filler below the last row. Owner said it twice —
   "odd empty space/bar at the bottom", then "theres still this bottom weird
   gap bit" — so the panel now ends at the last row instead (board.js hug()).
   The last row keeps its bottom border; that edge IS the end of the sheet. */

/* crew-row expand: chevron in the label, members listed underneath */
.rowx { position: absolute; top: 4px; right: 4px; width: 17px; height: 17px; padding: 0;
        background: var(--panel-2); border: 1px solid var(--line); color: var(--text-dim);
        cursor: pointer; font-size: 10.5px; line-height: 1; transition: transform .15s; }
.rowx:hover { color: var(--gold-bright); border-color: var(--gold-deep); }
.brow.open .rowx { transform: rotate(180deg); color: var(--gold-ink); border-color: var(--gold-deep); }
.rowmembers { margin: 6px 0 4px; border-top: 1px solid var(--line); padding-top: 5px;
              display: grid; gap: 2px; font-size: 11.5px; }
.rowmembers[hidden] { display: none; }
.rowmembers .rm { display: flex; gap: 8px; justify-content: space-between; min-width: 0; }
.rowmembers .rmp { color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rowmembers .rmw { text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rowmembers .rmw.tbc { color: var(--text-faint); font-style: italic; }
.rowmembers .rm.lead .rmw { color: var(--gold-bright); }

/* auto-save toast */
.qctoast { position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 14px); z-index: 80;
           background: var(--raised); border: 1px solid var(--gold-deep); color: var(--gold-bright);
           padding: 7px 16px; font-size: 12.5px; opacity: 0; pointer-events: none;
           transition: opacity .18s, transform .18s; }
.qctoast.show { opacity: 1; transform: translate(-50%, 0); }
.qctoast.err { border-color: var(--red); color: var(--red); }

/* THE STALE-PAGE NOTICE (global freshness). Fixed, so it cannot reflow the
   page under somebody who is mid-sentence — the whole point of this feature is
   that nothing they are typing is disturbed. Bottom LEFT, because .qctoast
   above is bottom-centre and this one stays put while those come and go.

   Every colour is a token, so light mode is right without a second rule. The
   [hidden] line is not redundant: `display: flex` below would otherwise beat
   the browser's own [hidden] rule and the notice would be on screen from the
   first paint of every production page. */
.qcfresh { position: fixed; left: 18px; bottom: 22px; z-index: 90;
           display: flex; align-items: center; gap: 12px;
           background: var(--raised); border: 1px solid var(--gold-deep);
           border-left: 3px solid var(--gold); color: var(--gold-bright);
           padding: 9px 12px 9px 13px; font-size: 12.5px;
           box-shadow: 0 6px 20px rgb(0 0 0 / 28%); }
.qcfresh[hidden] { display: none; }
.qcfresh .qcfreshgo { background: none; border: 1px solid var(--gold-deep);
                      color: var(--gold-bright); font: inherit; font-weight: 600;
                      padding: 3px 11px; cursor: pointer; }
.qcfresh .qcfreshgo:hover { background: color-mix(in srgb, var(--gold) 16%, transparent); }
/* Narrow screens: full width, and ABOVE where the toast appears rather than
   under it — this one is persistent and the toast is not, so the transient
   thing is the one that gets the corner it always had. */
@media (max-width: 560px) {
  .qcfresh { left: 10px; right: 10px; bottom: 72px; justify-content: space-between; }
}

/* HOD band — slim collapsible strip above the schedule rows */
.hodband { border-bottom: 1px solid var(--gold-deep); }
.hodhead { position: sticky; left: 0; display: flex; align-items: center; gap: 8px;
           width: max-content; background: none; border: 0; color: var(--gold-bright);
           font: inherit; font-size: 10.5px; font-weight: 600; text-transform: uppercase;
           letter-spacing: .5px; padding: 5px 10px; cursor: pointer; }
.hodhead .dim { text-transform: none; letter-spacing: 0; font-weight: 400; }
.hodhead .hcaret { color: var(--gold-ink); transition: transform .15s; }
.hodband:not(.collapsed) .hcaret { transform: rotate(90deg); }
.hodband.collapsed .hodrows { display: none; }
.hodrow .rowlbl b { color: var(--gold-bright); }
.blk.hodblk { background: color-mix(in srgb, var(--gold) 14%, var(--panel)); }

/* HODs section on the Roles tab */
details.hodsec { margin-top: 26px; border: 1px solid var(--line); background: var(--panel);
                 padding: 10px 14px; }
details.hodsec summary { cursor: pointer; list-style: none; display: flex; align-items: center;
                         gap: 8px; font-weight: 600; }
details.hodsec summary::-webkit-details-marker { display: none; }
details.hodsec summary .caret { margin-left: auto; color: var(--gold-ink); transition: transform .15s; }
details.hodsec[open] summary .caret { transform: rotate(180deg); }

/* In the footer beside the hints. It used to float over the board's corner,
   which stopped working once the panel ended at the last row — it would have
   sat on top of the schedule. */
.zoomctl { display: flex; align-items: center; flex: 0 0 auto;
           gap: 8px; padding: 7px 12px 18px; background: var(--panel);
           border: 1px solid var(--line); }
.zbtn { width: 22px; height: 22px; background: var(--panel-2); border: 1px solid var(--line);
        color: var(--text); cursor: pointer; font-size: 14px; line-height: 1; padding: 0; }
.zbtn:hover { border-color: var(--gold-deep); color: var(--gold-bright); }
.zline { position: relative; width: 180px; height: 2px; background: var(--line); margin: 0 8px; }
.zmark { position: absolute; top: 50%; transform: translate(-50%, -50%) rotate(45deg); width: 7px; height: 7px;
         background: var(--gold); box-shadow: 0 0 7px color-mix(in srgb, var(--gold) 70%, transparent); pointer-events: none;
         transition: left .12s ease; }
.zdot { position: absolute; top: 50%; transform: translate(-50%, -50%); width: 16px; height: 16px;
        background: none; border: 0; padding: 0; cursor: pointer; }
.zdot i { display: block; width: 8px; height: 8px; margin: 4px auto 0; background: var(--raised);
          border: 1px solid var(--text-faint); }
.zdot:hover i { border-color: var(--gold-ink); }
.zdot.on i { background: var(--gold); border-color: var(--gold); }
.zdot span { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); font-size: 9px;
             color: var(--text-faint); white-space: nowrap; letter-spacing: .3px; }
.zdot:hover span, .zdot.on span { color: var(--gold-bright); }

.blk {
  position: absolute; border-left: 3px solid var(--c); background: color-mix(in srgb, var(--c) 20%, var(--panel));
  padding: 1px 7px 1px 5px; cursor: grab; user-select: none; overflow: hidden; font-size: 11.5px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--c) 35%, transparent);
  transition: top .13s ease, height .13s ease;  /* live restack + vertical fit glide */
  line-height: 1.25;
  display: flex; flex-direction: column; justify-content: center;  /* text centres in taller fitted blocks */
}
.blk.ro { cursor: default; }
.blk.dragging { opacity: .88; z-index: 10; cursor: grabbing; transition: none;
                box-shadow: var(--shadow); }
.track { transition: height .13s ease; }
.blk .bmain { display: flex; gap: 4px; align-items: center; white-space: nowrap; overflow: hidden; }
.blk .bcode { background: var(--c); color: var(--on-data); font-weight: 700; font-size: 9px;
              padding: 0 3px; font-family: var(--mono); }
.blk b { font-weight: 600; font-size: 11.5px; }
.blk .al { display: block; font-size: 9.5px; color: var(--text-dim); white-space: nowrap; }
.blk .rsz { position: absolute; top: 0; bottom: 0; width: 7px; cursor: ew-resize; }
.blk .rsz.l { left: 0; } .blk .rsz.r { right: 0; }
.blk.ro .rsz { display: none; }
.blk.sel { box-shadow: 0 0 0 2px var(--gold-ink); z-index: 5; }
/* Rig/Shoot focus: the unfocused side's bookings — visible, out of the way,
   untouchable. height beats the inline style board.js applies. */
.blk.thinline { height: 12px !important; opacity: .7; padding: 0 4px; cursor: default; }
.blk.thinline .al, .blk.thinline .rsz, .blk.thinline .bcode, .blk.thinline .clashbadge { display: none; }
.blk.thinline .bmain b { font-size: 8.5px; font-weight: 500; }
.blk.dim { opacity: .22; }
.blk.clash { box-shadow: inset 0 0 0 1px var(--red); }
.clashbadge { color: var(--red); font-size: 12.5px; margin-left: 4px; }
.track.droptgt { outline: 2px dashed var(--gold-deep); outline-offset: -2px; background-color: var(--gold-tint); }

/* SOMEBODY ELSE'S CHANGE, MARKED WHERE IT LANDED (board.js markChanges).
   The board has always redrawn itself when another person changed the job; it
   never said WHICH booking, so the answer was to go and look for it.

   An OUTLINE, deliberately, because every other state on a block is already a
   box-shadow: selection is a gold ring and a clash is a red inset one, and a
   changed block may be either of those at the same time. Outline sits outside
   both and cannot be argued with by the cascade — a selected block that
   somebody else has just moved shows both marks at once.

   Ink rather than a hue, for the same reason: gold on this board means
   "selected", red means "double-booked", blue means "elsewhere". A change is
   none of those, so it borrows the text colour, which is high-contrast in both
   themes and means nothing else.

   A RING AND NOTHING INSIDE IT. The first version washed the block itself as
   well; screenshotted in both themes, that reads as a lift in dark and as
   DIMMED in light, because the ink flips and a 14% black over a crew colour
   looks like the .dim spotlight state. A block's fill is the crew's own
   colour and it is already saying something — the ring points at it without
   editing it, and it is legible enough on its own in both themes.

   It takes itself away. Six seconds is long enough to look up, follow the
   toast and find the row; nothing has to be dismissed and nothing is left
   behind to be misread later as current. Under prefers-reduced-motion the
   global rule at the top of this file drops the animation, and the mark simply
   holds and then goes — board.js removes the class either way. */
.blk.justchanged, .pbar.justchanged {
  outline: 2px solid var(--text); outline-offset: 1px; z-index: 4;
  animation: qcchanged 6s ease-out forwards;
}
@keyframes qcchanged { 0%, 62% { outline-color: var(--text); } 100% { outline-color: transparent; } }
@keyframes qcchangefade { 0%, 62% { opacity: 1; } 100% { opacity: 0; } }

/* What is left where a deleted booking was. A hole is the one change nobody
   can spot, so its outline stays behind for a moment, struck through, and
   fades. Never a drop target and never clickable — it is not there any more. */
.blkghost {
  position: absolute; pointer-events: none; z-index: 3;
  border: 1px dashed var(--text-dim);
  background: color-mix(in srgb, var(--text) 6%, transparent);
  color: var(--text-faint); font-size: 11.5px; line-height: 1.25;
  padding: 1px 7px 1px 5px; overflow: hidden; white-space: nowrap;
  text-decoration: line-through; animation: qcchangefade 6s ease-out forwards;
}

/* And the row it happened on. The label column is sticky at the left edge, so
   this is the half that survives being scrolled away from: a change two weeks
   off the side of the window still shows up as a marked row in front of you.
   The right edge, never the left — the left border is the crew's own colour. */
.brow.justchanged > .rowlbl {
  background-color: color-mix(in srgb, var(--text) 9%, var(--panel-2));
  box-shadow: inset -2px 0 0 var(--text);
  animation: qcchangerow 6s ease-out forwards;
}
@keyframes qcchangerow {
  /* background-COLOR, not the shorthand: .rowlbl paints itself with the
     shorthand and only the colour is interpolable. */
  0%, 62% { background-color: color-mix(in srgb, var(--text) 9%, var(--panel-2));
            box-shadow: inset -2px 0 0 var(--text); }
  100%    { background-color: var(--panel-2); box-shadow: inset -2px 0 0 transparent; }
}
.dragghost { position: fixed; top: -200px; left: -200px; display: flex; gap: 6px; align-items: center;
             background: var(--raised); border: 1px solid var(--gold-deep); padding: 6px 12px;
             font-size: 12.5px; color: var(--text); pointer-events: none; z-index: 99; }
.dragghost .bcode { width: 14px; height: 14px; }
.dragghost .al { color: var(--text-faint); font-size: 10.5px; }
/* on-brand segmented toggles: gold fill on the active segment (V1) */
.viewtog, .unittog { display: inline-flex; border: 1px solid var(--line); background: var(--panel-2); }
.viewtog a, .unittog button { padding: 5px 14px; color: var(--text-dim); font-size: 12.5px;
                              background: none; border: none; font: inherit; cursor: pointer; }
.viewtog a.on, .unittog button.on { background: var(--gold); color: var(--on-gold); font-weight: 600; }
.viewtog a + a, .unittog button + button { border-left: 1px solid var(--line); }
.unittog em { font-style: normal; opacity: .75; margin-left: 4px; font-size: 11.5px; }
.weeksform { display: flex; gap: 8px; align-items: center; }
/* activity textures, V1's grammar */
.wt-shoot { background: color-mix(in srgb, var(--c) 34%, var(--panel)); }
.wt-prelight { border-left-style: dashed; background: color-mix(in srgb, var(--c) 13%, var(--panel)); }
.wt-seein { border: 1px dashed var(--c); border-left-width: 3px; background: color-mix(in srgb, var(--c) 14%, var(--panel)); }
.wt-derig, .wt-strike, .wt-wrap {
  background: repeating-linear-gradient(45deg, color-mix(in srgb, var(--c) 26%, transparent) 0 5px, transparent 5px 11px),
              color-mix(in srgb, var(--c) 7%, var(--panel));
}

.modal-backdrop { position: fixed; inset: 0; background: var(--scrim); display: flex;
                  align-items: flex-start; justify-content: center; padding-top: 7vh; z-index: 40; }
.modal-backdrop[hidden] { display: none; }  /* display:flex beats the hidden attr otherwise */
.modal { background: var(--panel); border: 1px solid var(--line); padding: 20px;
         width: min(540px, 92vw); max-height: 84vh; overflow-y: auto; }
.frow2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.mrow { display: flex; gap: 8px; margin-top: 16px; align-items: center; flex-wrap: wrap; }
.spacer { flex: 1; }
.asslist { list-style: none; padding: 0; margin: 0 0 8px; }
.asslist li { padding: 6px 0; border-bottom: 1px solid var(--line); }
.hdot { display: inline-block; width: 11px; height: 11px; margin-right: 7px; }
.hd { color: var(--text-faint); font-weight: 400; font-size: 12.5px; margin-left: 10px; }
/* ---- WHERE THE STEPPER STANDS (.stepper) --------------------------------
   The control ITSELF is static/datenav.css — one file, because the standalone
   crew sheet needs the same group and loads no app.css. What stays here is
   CONTEXT: how one sizes in the row it happens to sit in. Editing the look of
   a date control? Wrong file. */
.frow2 .stepper { width: 100%; }
.clashban { background: color-mix(in srgb, var(--red) 10%, transparent); border: 1px solid var(--red); padding: 8px 10px;
            font-size: 12.5px; margin-bottom: 10px; }
.modal.wide { width: min(680px, 94vw); }
.modal.qdlg { width: min(500px, 92vw); }
.whosin { border: 1px solid var(--line); background: var(--panel-2); padding: 8px 10px; margin-top: 12px; }
.whosin .wt { font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px; color: var(--text-faint); margin-bottom: 6px; }
details.whosin summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 8px; margin-bottom: 0; }
details.whosin summary::-webkit-details-marker { display: none; }
details.whosin summary .caret { margin-left: auto; color: var(--gold-ink); transition: transform .15s; }
details.whosin[open] summary .caret { transform: rotate(180deg); }
details.whosin[open] summary { margin-bottom: 6px; }
details.whosin summary:hover { color: var(--text); }
.rgroup { border-top: 1px solid var(--line); padding: 5px 0; }
.rgh { display: flex; align-items: center; justify-content: space-between; }
.rgname { font-weight: 600; font-size: 12.5px; }
.cstep { display: inline-flex; align-items: center; border: 1px solid var(--line); }
.cstepb { background: var(--raised); border: none; color: var(--text); padding: 1px 9px; cursor: pointer; font: inherit; }
.cstepb:hover { color: var(--gold-ink); }
.cnum { padding: 0 9px; font-family: var(--mono); font-size: 12.5px; }
.raddrow { display: flex; gap: 6px; margin-top: 8px; }
.ld { border: 1px solid var(--gold-deep); background: var(--gold-tint);
      padding: 7px 10px; margin-top: 10px; font-size: 12.5px; }
.ld .ldlink { display: block; color: var(--text-faint); font-size: 11.5px; margin-top: 2px; }
.linked { color: var(--gold-ink); margin-left: 5px; }

/* ---- the booking modal, before its answer arrives (static/board.js) -----
   MEASURED 2026-09-05: the new-booking modal landed a median 264ms after the
   double click and the edit modal 410ms, nine tenths of it round trip. These bars
   stand exactly where the controls will, at the control's own height, so the
   answer FILLS the dialog instead of replacing it — the captions do not jump
   and the box does not resize under the pointer.

   The captions repeat `form label` on purpose: the skeleton is not inside a
   <form> (there is nothing yet to post), so it would otherwise inherit none
   of the spacing the real fields have and every row would sit differently.
   The sweep is decoration and says so — the global prefers-reduced-motion
   rule at the top of this file already stops it, leaving a plain bar. */
.mskel label { display: block; margin: 10px 0 4px; color: var(--text-dim); }
.mskb {
  display: block; height: calc(1.45em + 14px); position: relative; overflow: hidden;
  border: 1px solid var(--line); background: var(--panel-2);
}
.mskb.tall { height: calc(4.35em + 14px); }   /* Notes is a 3-row textarea */
.mskb::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent,
              color-mix(in srgb, var(--text) 8%, transparent), transparent);
  animation: qcskel 1.15s ease-in-out infinite;
}
@keyframes qcskel { to { transform: translateX(100%); } }
/* The buttons standing in their final places until the answer arrives.
   Faded and inert — deliberately NOT a general .btn:disabled rule,
   which would also restyle the delete-a-production confirm button on a
   page this job never looked at. */
.mskbtn { opacity: .45; pointer-events: none; }
/* The crew strip's caption. `details.whosin summary` already lays the
   real one out as a flex row with the caret pushed right; the shell's is
   a plain <div> (there is nothing to open yet), so it needs the same two
   declarations of its own or the caret sits against the words. */
.whosin > .wt.mskcap { display: flex; align-items: center; }
.whosin > .wt.mskcap .caret { margin-left: auto; color: var(--gold-ink); }
.mgrid.labour .mhead, .mgrid.labour .mline {
  grid-template-columns: minmax(160px, 1.4fr) minmax(140px, 1fr) minmax(120px, 1fr)
                         110px minmax(140px, 1.4fr) minmax(120px, 1fr) minmax(120px, auto);
}

/* history timeline */
.timeline { max-width: 980px; }
.tday { font-size: 11.5px; text-transform: uppercase; letter-spacing: .5px; color: var(--gold-bright);
        margin: 18px 0 6px; border-bottom: 1px solid var(--line); padding-bottom: 4px; }
.tevent { display: flex; gap: 12px; padding: 8px 10px; border-left: 2px solid var(--line);
          margin-left: 4px; }
.tevent:hover { background: var(--panel); }
.tevent.v-created { border-left-color: var(--green); }
.tevent.v-updated { border-left-color: var(--gold-ink); }
.tevent.v-deleted { border-left-color: var(--red); }
.ttime { flex: 0 0 52px; font-family: var(--mono); font-size: 12.5px; color: var(--text-faint); padding-top: 2px; }
.twhat b { font-weight: 600; }
.twhat .tverb { color: var(--text-dim); }
.tdiffs { margin-top: 3px; }
.tdiff { font-family: var(--mono); font-size: 11.5px; color: var(--text-dim); }
.tdiff b { color: var(--text); font-weight: 500; }

/* Labour-days tab — V1's per-role budget grid (.ld* namespace) */
.ldbar { display: flex; gap: 14px; align-items: baseline; flex-wrap: wrap;
         border: 1px solid var(--line); background: var(--panel); padding: 8px 12px;
         margin-bottom: 14px; font-size: 12.5px; color: var(--text-dim); }
.ldbar b { color: var(--gold-bright); font-weight: 600; }
.ldbar .legend { margin-left: auto; color: var(--text-faint); font-family: var(--mono); font-size: 11.5px; }
.ldsec { margin: 18px 0 8px; }
.ldsec h2 { margin: 0; display: inline; }
.ldsec .hint { color: var(--text-faint); font-size: 12.5px; margin-left: 10px; }
.ldwrap { overflow-x: auto; border: 1px solid var(--line); background: var(--panel); }
.ldhead, .ldrow, .ldsub, .ldfootrow, .ldlabel {
  display: grid; gap: 0; align-items: stretch; width: max-content; min-width: 100%; }
.ldhead { background: var(--panel-2); font-size: 10.5px; text-transform: uppercase;
          letter-spacing: .4px; color: var(--text-faint); position: sticky; top: 0; z-index: 3; }
.ldhead > span { padding: 6px 7px; border-bottom: 1px solid var(--line); border-right: 1px solid var(--line); }
.ldhead .sub { display: block; text-transform: none; letter-spacing: 0; font-size: 10.5px;
               color: var(--text-faint); white-space: nowrap; }
.ldrow > *, .ldsub > span, .ldfootrow > span { border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line); display: flex; align-items: center; min-height: 30px; }
.ldrow:hover { background: var(--panel-2); }
.ldrole { padding: 3px 8px; position: sticky; left: 0; background: var(--panel); z-index: 2;
          gap: 6px; white-space: nowrap; overflow: hidden; }
.ldrow:hover .ldrole { background: var(--panel-2); }
.ldgridbox input, .ldgridbox select { border: none; background: none; height: 100%; }
/* The role picker is a spreadsheet cell but it is still a dropdown, and it has
   to look like one. This grid was one of the places the OS chevron was showing
   through; switching that off at the root fixes the look and would ALSO have
   left the control with no affordance at all, because `background: none` above
   blanks the root rule's caret along with the ground. So the caret is put back
   here — ours, faint, tucked tighter than the standard 26px because a grid
   cell has no room to spare. */
.ldgridbox select:not([multiple]) {
  background-image: var(--caret);
  background-repeat: no-repeat; background-position: right 4px center;
  background-size: 9px 6px; padding-right: 18px;
}
.ldgridbox select:not([multiple]):focus { background-image: var(--caret-on); }
.ldgridbox input:focus, .ldgridbox select:focus { outline: none; box-shadow: inset 0 0 0 1px var(--gold-deep); }
.ldrow .wk, .ldhod .wk { justify-content: center; text-align: center; font-family: var(--mono);
  font-size: 12.5px; color: var(--text-faint); padding: 0; }
.ldrow input.wk::placeholder { color: var(--text-faint); }
.ldrow .wk.has, .ldhod .wk.has { color: var(--gold-bright); font-weight: 500; }
.ldrate .sub { display: block; font-size: 10px; color: var(--text-faint); }
.lddays, .ldcost, .ldrate { justify-content: flex-end; padding: 3px 9px;
  font-family: var(--mono); font-size: 12.5px; }
.ldcost { color: var(--text-dim); }
/* The rate is the ROLE'S, set on the Roles tab (owner, 2026-09-06), so on an
   editable row it reads as a quiet link to where it is changed rather than as
   a field — the input that used to sit here wrote a second, competing rate. */
.ldratelink { color: inherit; text-decoration: none; border-bottom: 1px dotted transparent; }
.ldratelink:hover { color: var(--gold-bright); border-bottom-color: currentColor; }
.ldx { background: none; border: none; color: var(--text-faint); cursor: pointer; font-size: 14px;
       width: 100%; justify-content: center; }
.ldx:hover { color: var(--red); }
.ldhod { background: var(--gold-tint); }
.ldhod .ldrole { background: var(--gold-wash); }
.ldhod .ldrole b { font-weight: 600; }
.ldlabel > span { padding: 5px 8px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--gold-ink); border-bottom: 1px solid var(--line); background: var(--gold-tint); }
.ldsub > span, .ldfootrow > span { background: var(--panel-2); font-family: var(--mono);
  font-size: 12.5px; padding: 4px 9px; justify-content: flex-end; }
.ldsub .lbl, .ldfootrow .lbl { justify-content: flex-start; font-family: var(--sans);
  font-weight: 600; font-size: 12.5px; position: sticky; left: 0; background: var(--panel-2); z-index: 2; }
.ldfootrow.grand > span { color: var(--gold-bright); border-top: 1px solid var(--gold-deep); }
.ldactions { display: flex; gap: 8px; align-items: center; margin: 10px 0 4px; flex-wrap: wrap; }
.ldactions .hint { color: var(--text-faint); font-size: 12.5px; margin-left: auto; }
details.ldfold { border: 1px solid var(--line); background: var(--panel); margin-top: 16px; }
details.ldfold > summary { cursor: pointer; list-style: none; padding: 9px 12px; display: flex;
  align-items: baseline; gap: 10px; }
details.ldfold > summary::-webkit-details-marker { display: none; }
details.ldfold > summary h2 { margin: 0; display: inline; }
details.ldfold > summary .caret { margin-left: auto; color: var(--gold-ink); transition: transform .15s; }
details.ldfold[open] > summary .caret { transform: rotate(180deg); }
details.ldfold .foldbody { padding: 0 12px 12px; }
.ldtrack { border: 1px solid var(--line); width: max-content; min-width: 60%; }
.tline { display: grid; grid-template-columns: 170px 130px 130px 130px 190px 130px; gap: 0; }
.tline > * { border-bottom: 1px solid var(--line); border-right: 1px solid var(--line);
  padding: 5px 10px; display: flex; align-items: center; min-height: 30px; }
.tline.thead > span { background: var(--panel-2); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .4px; color: var(--text-faint); display: block; padding: 6px 10px; }
.tline.thead .sub { display: block; text-transform: none; letter-spacing: 0; font-size: 10.5px; }
.tline .mono { font-family: var(--mono); font-size: 12.5px; justify-content: flex-end; }
.tline form { display: contents; }
.tline input.sub-i { border: none; background: none; text-align: right;
  font-family: var(--mono); font-size: 12.5px; }
.tline input.sub-i:focus { outline: none; box-shadow: inset 0 0 0 1px var(--gold-deep); }
.tline.tfoot > * { background: var(--panel-2); font-weight: 600; }
.ldpos { color: var(--red); }
.ldneg { color: var(--green); }
.ldzero { color: var(--text-faint); }
.clawpill { font-style: normal; font-family: var(--mono); font-size: 9.5px; border: 1px solid var(--red);
  color: var(--red); padding: 1px 6px; margin-left: 8px; white-space: nowrap; }
.ldnote { border: 1px solid var(--line); background: var(--panel); color: var(--text-faint);
  font-size: 12.5px; padding: 10px 12px; margin-top: 16px; max-width: 1100px; }
.ldnote b { color: var(--text-dim); }
.ldcheck { display: flex; align-items: flex-start; gap: 8px; margin-top: 12px; }
.ldcheck input { width: auto; margin-top: 3px; }
.ldcheck .cdim { color: var(--text-faint); font-style: italic; font-size: 12.5px; display: block; }

/* ---- Quiet cells (design pass, 2026-08-08) ----
   Everything autosaves, so an editable row doesn't need to dress as a form.
   Inside management rows, inputs and selects sit flat like spreadsheet
   cells: plain text at rest, a lifted cell on hover, a gold-edged cell
   while editing. Add-forms (.addrow, .sucadd, .addseat…) keep their real
   input boxes — an affordance to type something NEW is a different job. */
/* background-COLOR, not the shorthand: these three rules run over the caret
   below, and `background: var(--panel-2)` would silently blank it. */
.qcells :is(input, select):not([type="color"]):not([type="checkbox"]) {
  background-color: transparent; border-color: transparent;
}
.qcells :is(input, select):not([type="color"]):hover {
  background-color: var(--panel-2); border-color: var(--line);
}
.qcells :is(input, select):not([type="color"]):focus {
  background-color: var(--panel-2); border-color: var(--gold-deep);
}
/* A select in a quiet cell has to read as TEXT at rest, and the browser's own
   chevron flatly contradicts that — 86 of them down the People column read as
   a column of OS furniture rather than a list of departments. So the native
   control is switched off and we draw the caret on the same terms as the rest
   of the row furniture: absent at rest, faint once the cell is under the
   pointer, gold while it is open. Owner, 2026-08-12: "isnt very on brand it
   feels a bit off".
   The padding is reserved at rest so revealing the caret never reflows the
   text, and appearance:none also drops the OS control's own background, which
   is what made the cell look pasted onto the row in dark mode. */
.qcells select:not([multiple]) {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 21px;
  /* background-image: none is what keeps "absent at rest" true now that the
     root rule draws a caret on every select. Without it these 86 rows would
     all sprout one, which is the column of OS-looking furniture this block
     was written to remove. The hover and focus rules below put it back. */
  background-image: none;
  background-repeat: no-repeat; background-position: right 6px center;
  background-size: 9px 6px;
}
/* Keyboard users never hover, so the caret follows focus INTO the row too —
   otherwise tabbing across the People table moves an invisible cursor. This
   sits BEFORE the :focus rule below: the two have identical specificity, so
   source order is the only thing deciding which caret an open cell gets. */
.qcells:hover select:not([multiple]),
.qcells:focus-within select:not([multiple]),
.qcells select:not([multiple]):hover { background-image: var(--caret); }
.qcells select:not([multiple]):focus { background-image: var(--caret-on); }
/* row furniture goes quiet until the row is under the pointer */
.qcells .ordbtns .mini { border-color: transparent; color: var(--text-faint); }
.qcells:hover .ordbtns .mini { border-color: var(--line); }
.qcells .ordbtns .mini:hover { border-color: var(--gold-deep); color: var(--gold-bright); }
/* deletes: a ghost × that only turns red when you mean it. The loud treatment
   stays for modal buttons — a deliberate destructive screen SHOULD be loud. */
.qcells :is(.btn.danger, .mini.danger) {
  background: none; border-color: transparent; color: var(--text-faint); opacity: .35;
}
.qcells:hover :is(.btn.danger, .mini.danger),
.qcells:focus-within :is(.btn.danger, .mini.danger) { opacity: 1; }
.qcells :is(.btn.danger, .mini.danger):hover { color: var(--red); border-color: var(--red); }
/* colour wells: a swatch, not a slab */
.qcells input[type="color"] { width: 26px; height: 22px; padding: 1px; flex: 0 0 26px;
  background: transparent; border-color: transparent; }
.qcells input[type="color"]:hover { border-color: var(--line); }

/* Invitations: the confirmation state, and the link cell in the pending
   table. Green, not gold — "this worked" is not a call to action. */
.sentbox { border: 1px solid var(--green); background: color-mix(in srgb, var(--green) 7%, transparent);
  padding: 12px 14px; margin-bottom: 12px; }
.sentl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--green); margin-bottom: 7px; }
.sentbox .shrow input { font-family: var(--mono); font-size: 12.5px; }
.sentmeta { margin-top: 9px; font-size: 11.5px; color: var(--text-faint); line-height: 1.5; }
.sentmeta b { color: var(--text-dim); }
.fieldhint { color: var(--text-faint); font-size: 11.5px; margin: 3px 0 2px; }
.unitpick { border: 1px solid var(--line); background: var(--panel-2); padding: 7px 10px;
  max-height: 132px; overflow-y: auto; }
.unitpick label { display: flex; align-items: center; gap: 8px; margin: 2px 0;
  color: var(--text); font-size: 12.5px; }
.unitpick input { width: auto; }
.unitpick ul { list-style: none; margin: 0; padding: 0; }
.invlink { display: flex; gap: 6px; align-items: center; }
.invlink input { font-family: var(--mono); font-size: 11.5px; background: var(--panel-2);
  border: 1px solid var(--line); padding: 3px 7px; }
.invacts { display: flex; gap: 6px; }
/* A note that reports a FAILURE cannot sit in the caption tier — the whole
   point is that it is the one line on the panel you must not skim past. */
.note.warn { color: var(--gold-bright); }

/* the ? shortcut sheet */
.keysgrid { display: grid; grid-template-columns: auto 1fr; gap: 7px 16px;
  margin: 6px 0 2px; align-items: baseline; }
.keysgrid .kh { grid-column: 1 / -1; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--gold-ink); margin-top: 8px; }
.keysgrid .kh:first-child { margin-top: 0; }
kbd { font-family: var(--mono); font-size: 11.5px; background: var(--panel-2);
  border: 1px solid var(--line); border-bottom-width: 2px; padding: 1px 7px;
  white-space: nowrap; color: var(--text); }
.keysgrid span { font-size: 12.5px; color: var(--text-dim); }

/* Setup workspace (.su*) — one page replacing the five management tabs.

   Owner, 2026-08-15: the nav and the rail stay put and only the chosen
   section scrolls. Same lock the board uses (body.boardpage): the BODY stops
   scrolling and becomes a flex column, so the header takes its natural
   height and the shell takes the rest. min-height: 0 on every level is what
   lets an inner scroller actually shrink — without it a flex item refuses to
   go below its content and the scrollbar lands back on the window.

   This also retires the calc(100vh - 46px) that used to be here: 46px was
   the header's height written down in a second place, and it was wrong the
   moment the header wrapped to two lines on a narrow screen. */
/* Help uses the same rail-and-content shell, so it needs the same lock.
   Without it .sucontent has no bounded height, grows to its full content
   height, and becomes a scroll container with NOTHING to scroll — and its
   overscroll-behavior below then swallows the wheel instead of passing it
   to the page. The rail has no such containment, so scrolling worked over
   the left column and nowhere else. */
body.setuppage, body.helppage { height: 100vh; overflow: hidden; display: flex; flex-direction: column; }
/* width: 100% is load-bearing and cost a round trip to learn. .wrap carries
   `margin: 0 auto` for centring, which is harmless on a block — it fills the
   available width up to max-width. Turn it into a FLEX ITEM, as the line
   above does, and the auto margins stop it stretching: it shrinks to fit its
   content and centres, so the whole page collapsed to a column down the
   middle with empty gutters either side. */
body.setuppage .wrap, body.helppage .wrap { flex: 1 1 auto; min-height: 0; display: flex; width: 100%; }
.sushell { display: flex; gap: 0; margin: -14px -16px; flex: 1 1 auto; min-height: 0; }
.surail { flex: 0 0 212px; border-right: 1px solid var(--line); background: var(--panel);
  padding: 10px 0; display: flex; flex-direction: column;
  /* Last resort only. The rail is meant never to scroll — see .surnav and
     .surnote below, which between them absorb a short window. This catches
     the case where even the section list alone cannot fit, and there being
     no scrollbar would mean Equipment is simply unreachable. */
  overflow-y: auto; }
/* THE SECTION LIST NEVER MOVES. flex-shrink: 0 is the whole fix: on a short
   viewport — or a zoomed-in one, which is the same thing in CSS pixels — the
   rail used to overflow and take "Production setup" and Crews off the top
   with it. Anything that has to give, gives below. */
.surnav { flex: 0 0 auto; }
/* …and this is what gives: it shrinks and scrolls itself so the glossary and
   the delete link stay reachable without ever pushing the list off screen. */
.surnote { flex: 0 1 auto; min-height: 0; overflow-y: auto; }
.surlbl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--text-faint); padding: 6px 16px 6px; }
.suritem { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: none; border: none; border-left: 3px solid transparent; color: var(--text-dim);
  font: inherit; padding: 8px 13px; cursor: pointer; }
.suritem:hover { color: var(--text); background: var(--panel-2); }
.suritem.on { color: var(--gold-bright); background: var(--panel-2); border-left-color: var(--gold); }
.suritem .n { margin-left: auto; font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.suritem.on .n { color: var(--gold-ink); }
.surnote { margin-top: auto; padding: 12px 16px; font-size: 11.5px; color: var(--text-faint);
  border-top: 1px solid var(--line); }
/* the glossary (brief item 12): six terms a newcomer will conflate, defined
   where they're configured — folded away for everyone else */
.sugloss { margin-bottom: 10px; }
.sugloss summary { cursor: pointer; list-style: none; color: var(--text-dim);
  font-size: 11.5px; }
.sugloss summary::-webkit-details-marker { display: none; }
.sugloss summary::before { content: "▸ "; color: var(--gold-ink); }
.sugloss[open] summary::before { content: "▾ "; }
.sugloss summary:hover { color: var(--text); }
.sugloss .sug { margin-top: 6px; line-height: 1.4; }
.sugloss .sug b { color: var(--text-dim); display: block; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .4px; }
/* THE scroller. Everything above it is fixed, so this is the one box the
   wheel acts on — which is the whole point of the exercise. */
.sucontent { flex: 1 1 auto; padding: 16px 18px 40px; min-width: 0; min-height: 0;
  overflow-y: auto;
  /* Hitting the bottom of a section must not hand the wheel to anything
     else — the page behind it is locked, but this also stops the bounce. */
  overscroll-behavior-y: contain; }
.supanel { display: none; }
.supanel.on { display: block; }
.suhead { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.suhead h1 { margin: 0; }
.suhead .sub { color: var(--text-faint); font-size: 12.5px; }
/* A heading INSIDE a panel, for a tab that holds two different kinds of
   thing (Roles & HODs). Quieter than the panel head so the hierarchy reads,
   and on the six-size scale rather than a seventh size. */
.suhead.sub2 { margin-bottom: 8px; align-items: baseline; }
/* The global h2 is a small uppercase label; this one is a real heading, so
   it resets the transform and the tracking rather than inheriting them. */
.suhead.sub2 h2 { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.2px;
  text-transform: none; color: var(--text); }
.susearch { margin-left: auto; width: min(300px, 32vw); background: var(--panel-2);
  border: 1px solid var(--line); padding: 6px 12px; }
/* crews: list / detail / pool */
.sucrews { display: grid; grid-template-columns: 230px minmax(320px, 1fr) 250px; gap: 12px;
  align-items: start; }
.suclist { border: 1px solid var(--line); background: var(--panel); }
.sucrow { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: none; border-left: 3px solid var(--c); border-bottom: 1px solid var(--line);
  color: var(--text); font: inherit; padding: 9px 11px; cursor: pointer; }
.sucrow:hover { background: var(--panel-2); }
.sucrow.on { background: var(--panel-2); box-shadow: inset -3px 0 0 var(--gold); }
.sucrow .cn { font-weight: 600; font-size: 12.5px; display: block; }
.sucrow .cu { display: block; font-size: 11.5px; color: var(--text-faint); }
.sucrow .seats { margin-left: auto; font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.sucadd { display: flex; gap: 6px; padding: 9px 11px; flex-wrap: wrap; }
.sucadd input[name="name"] { flex: 1 1 100%; }
.sucadd select { flex: 1; width: auto; }
.sudetailwrap { border: 1px solid var(--line); background: var(--panel); min-height: 200px; }
.sudhead { display: flex; align-items: center; gap: 10px; padding: 10px 14px;
  border-bottom: 1px solid var(--line); border-top: 3px solid var(--c, var(--gold)); }
.sudname { font-weight: 600; font-size: 16px; }
input.sudname { width: auto; flex: 1; }
.sudhead select { width: auto; }
.sudetail .seats { border-top: none; padding: 4px 14px; }
.sudetail .addseat { display: flex; gap: 6px; padding: 10px 14px; border-top: 1px solid var(--line); }
.sudetail .addseat select { width: auto; flex: 1; }
/* Bulk add for units and crews — the same disclosure as .bulkseat below,
   sitting under each section's single "+ Add" row rather than replacing it. */
.bulkadd { max-width: 900px; margin-top: 6px; }
.bulkadd > summary { font-size: 12px; color: var(--gold-bright); cursor: pointer;
  list-style: none; padding: 4px 0; }
.bulkadd > summary::-webkit-details-marker { display: none; }
.bulkadd > summary::before { content: "+ "; }
.bulkadd[open] > summary::before { content: "− "; }
.bulkadd > summary:hover { color: var(--gold-ink); }
.barow { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; }
.barow input[name="name"] { flex: 1; }
.barow select { width: auto; flex: 0 0 190px; }
.bafoot { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 8px; flex-wrap: wrap; }
.bafoot .dim { font-size: 11.5px; }

/* Bulk seating: one role, any number of people, one submit. Closed by default
   so "+ Seat" stays the obvious way to add a single one. */
.bulkseat { border-top: 1px solid var(--line); }
.bulkseat > summary { padding: 8px 14px; font-size: 12px; color: var(--gold-bright);
  cursor: pointer; list-style: none; }
.bulkseat > summary::-webkit-details-marker { display: none; }
.bulkseat > summary::before { content: "+ "; }
.bulkseat[open] > summary::before { content: "− "; }
.bulkseat > summary:hover { color: var(--gold-ink); }
.bsbar { display: flex; align-items: center; gap: 8px; padding: 0 14px 8px; flex-wrap: wrap; }
.bsbar select { width: auto; flex: 1; min-width: 130px; }
.bstbc { display: flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--text-faint); white-space: nowrap; }
.bstbc input { width: 58px; }
.bspick { display: flex; flex-wrap: wrap; gap: 4px 10px; padding: 0 14px 12px;
  max-height: 190px; overflow-y: auto; }
.bschip { display: flex; align-items: center; gap: 5px; font-size: 12px;
  padding: 2px 0; white-space: nowrap; }
.bschip.all { width: 100%; color: var(--gold-bright); border-bottom: 1px solid var(--line);
  padding-bottom: 5px; margin-bottom: 3px; }
.bschip input { width: auto; margin: 0; }
.sufoot { padding: 8px 14px 10px; color: var(--text-faint); font-size: 11.5px; }
.seat.dragover { outline: 2px dashed var(--gold-ink); outline-offset: -2px; }
.supool { border: 1px solid var(--line); background: var(--panel); }
.supoolh { padding: 9px 12px; border-bottom: 1px solid var(--line); font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .5px; color: var(--text-faint); }
.supoolh b { color: var(--gold-bright); letter-spacing: 0; text-transform: none;
  font-size: 12.5px; display: block; }
.supg { padding: 8px 10px; border-bottom: 1px solid var(--line); }
.supgl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); margin-bottom: 6px; }
.supchips { display: flex; flex-wrap: wrap; gap: 5px; }
.supchip { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line);
  background: var(--panel-2); padding: 3px 9px; font-size: 12.5px; cursor: grab; }
.supchip.seatedp { opacity: .5; }
/* people register */
.sufilters { display: flex; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }
.sufilters .fchip { cursor: pointer; font: inherit; }
.sutable { width: 100%; border-collapse: collapse; background: var(--panel); border: 1px solid var(--line); }
.sutable th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--text-faint); padding: 7px 12px; border-bottom: 1px solid var(--line); background: var(--panel-2); }
.sutable td { padding: 5px 12px; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.sutable td.surowform { padding: 3px 8px; }
.supline { display: grid; grid-template-columns: minmax(150px, 1.2fr) minmax(130px, 1fr) 130px minmax(60px, auto); gap: 8px; align-items: center; }
.supline.wide { grid-template-columns: minmax(150px, 1.2fr) minmax(130px, 1fr) 130px minmax(110px, 1fr) 100px minmax(120px, 1fr) minmax(40px, auto); }
/* Lists that scroll in their own box rather than pushing the page down. A
   real job puts 80+ people on this tab, which buried App access — the thing
   you go looking for when somebody needs to sign in — a screen and a half
   below the fold. Owner, 2026-08-12: "its so out of the way currently".
   Each list keeps its own scrollbar so both stay reachable from the top. */
.suscroll { overflow: auto; border: 1px solid var(--line); background: var(--panel);
  max-height: 260px; }
.suscroll.short { max-height: 190px; }
.suscroll > .sutable, .suscroll > .table { border: 0; }
/* Sticky headers: scrolling a boxed list with the column names gone is how
   you end up guessing which column you are editing. The border is a shadow
   because a sticky cell's own bottom border scrolls away from it. */
.suscroll thead th { position: sticky; top: 0; z-index: 2;
  box-shadow: inset 0 -1px 0 var(--line); }
.sucount { color: var(--text-faint); font-size: 12px; }
/* roles & departments */
/* HODs are the same shape of thing as roles — a short editable registry with
   a weekly rate — so they get the same grid rather than a wrapping flex of
   independently-sized forms, which is what made them unreadable: no column
   headings, and nothing lining up from one row to the next. */
/* Narrower than the Roles table on purpose: it has one fewer column, and at
   the same width the two fr columns stretch until a name and its title are
   half a screen apart. It should read as the short registry it is.
   Written .rolegrid.hodgrid, not .hodgrid: .rolegrid sets its own max-width
   further down the file at equal specificity, so a bare class here loses. */
.rolegrid.hodgrid { max-width: 1000px; }
.hodgrid .rghead, .hodgrid .rgrow {
  grid-template-columns: minmax(150px, 1.3fr) minmax(130px, 1fr) minmax(140px, 1fr) 105px 105px 34px; }
.hodgrid.norates .rghead, .hodgrid.norates .rgrow {
  grid-template-columns: minmax(150px, 1.3fr) minmax(130px, 1fr) minmax(140px, 1fr) 34px; }
.sudepts { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 12px;
  align-items: start; }
.sudept { border: 1px solid var(--line); background: var(--panel); }
.sudept.dragover { border-color: var(--gold-ink); }
.sudepth { display: flex; align-items: baseline; gap: 8px; padding: 9px 13px;
  border-bottom: 1px solid var(--line); background: var(--panel-2); }
.sudepth .n { margin-left: auto; font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.surole { display: flex; align-items: center; gap: 9px; padding: 5px 13px;
  border-bottom: 1px solid var(--line); }
.surole .grip { color: var(--text-faint); cursor: grab; font-size: 12.5px; }
.surole input[name="name"] { width: auto; flex: 1; }
.surole .rn { flex: 1; font-size: 12.5px; }
.surole .use { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; }
.surole .raterow { width: 96px; text-align: right; font-family: var(--mono); font-size: 12.5px; }
.sudrop { margin: 8px; padding: 8px; border: 1px dashed var(--line); color: var(--text-faint);
  font-size: 11.5px; text-align: center; }
/* locations */
.sulocs { border: 1px solid var(--line); border-bottom: none; background: var(--panel);
  max-width: 900px; }
.suloc { display: flex; align-items: center; gap: 10px; padding: 7px 12px;
  border-bottom: 1px solid var(--line); }
.suloc .ordbtns { display: flex; flex-direction: column; gap: 2px; width: 26px; }
.suloc .ln { width: auto; flex: 0 1 190px; font-weight: 600; }
.suloc select { width: auto; }
/* the how-booked strip: data, not the accent — quiet deep-gold marks
   (brief item 3: gold's job is brand + primary action, not charts) */
.suloc .usage { flex: 1; display: flex; gap: 2px; height: 7px; max-width: 240px; }
.suloc .usage i { flex: 1; background: var(--panel-2); border: 1px solid var(--line); }
.suloc .usage i.u1 { background: color-mix(in srgb, var(--gold-deep) 55%, var(--panel-2));
  border-color: transparent; }
.suloc .usage i.u2 { background: var(--gold-deep); border-color: transparent; }
.suloc .bk { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint);
  min-width: 86px; text-align: right; }
/* units & work types */
.sunarrow { max-width: 680px; }
.suunit { display: flex; align-items: center; gap: 10px; border: 1px solid var(--line);
  border-left: 3px solid var(--c); background: var(--panel); padding: 8px 12px; margin-bottom: 8px; }
.suunit .un { font-weight: 600; } .suunit input.un { width: auto; flex: 1; }
.suunit select { width: auto; }
/* Archived units: still real rows that everything points at, so they are
   dimmed and set apart rather than hidden — what they came off is the
   picker, not the record. */
.suarchived { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--line); }
.suhead2 { font-size: 13px; font-weight: 600; letter-spacing: .02em; margin: 0 0 2px; }
.suhead2 .n { color: var(--text-faint); font-weight: 500; margin-left: 4px; }
.suarchived .sub { display: block; margin: 0 0 10px; }
.suunit.archived { opacity: .72; }
.suunit.archived .un { flex: 1; }
.suwt { display: flex; align-items: center; gap: 10px; border: 1px solid var(--line);
  background: var(--panel); padding: 6px 12px; margin-bottom: 6px; }
.suwt .wn { flex: 1; } .suwt input.wn { width: auto; }
.suwt .use { color: var(--text-faint); font-size: 11.5px; white-space: nowrap; }
.suwt select { width: auto; }
@media (max-width: 1100px) {
  .sucrews { grid-template-columns: 1fr; }
  .sushell { flex-direction: column; }
  /* flex: 0 0 auto is load-bearing. FLEX-BASIS IS AXIS-RELATIVE: the desktop
     rule above says `flex: 0 0 212px`, which means 212px WIDE only for as long
     as .sushell is a row. The line above flips it to a column, and that same
     212px silently becomes the rail's HEIGHT — with grow and shrink both 0
     forbidding it from growing to fit. The rail needs 582px on Help and 328px
     on Setup, and `overflow: visible` below means the excess does not clip or
     scroll: it hangs into .sucontent, which paints over it, and the section
     list shows through every gap between the content blocks.
     Whenever a media query flips flex-direction, re-check every flex-basis
     underneath it — the symptom is overlapping text, not an error. */
  .surail { flex: 0 0 auto;
    flex-direction: row; flex-wrap: wrap; position: static; min-height: 0;
    border-right: none; border-bottom: 1px solid var(--line); overflow: visible; }
  .surnote { display: none; }
  /* The rail is a row of tabs at this width, not a column beside the work,
     so there is nothing to hold still — give the page its ordinary scroll
     back rather than trapping a tall form in a short box. */
  body.setuppage, body.helppage { height: auto; overflow: visible; display: block; }
  body.setuppage .wrap, body.helppage .wrap { display: block; }
  .sucontent { overflow-y: visible; }
}

/* Finances tab — Xero-ish report on the QuantCrew tokens (.fin*) */
.phead.finhead { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; margin-bottom: 4px; }
.finscope { color: var(--gold-bright); font-size: 12.5px; font-weight: 600; }
.finact { margin-left: auto; display: flex; gap: 8px; }
.finchips { display: flex; gap: 6px; margin: 14px 0; flex-wrap: wrap; align-items: center; }
.fchip { display: inline-flex; gap: 7px; align-items: baseline; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text-dim); padding: 5px 13px; font-size: 12.5px; }
.fchip span { font-size: 10.5px; color: var(--text-faint); }
.fchip:hover { border-color: var(--gold-deep); color: var(--text); }
.fchip.on { background: var(--gold-wash); border-color: var(--gold-deep); color: var(--gold-bright); }
.fchip.filter { border-color: var(--gold-ink); color: var(--gold-bright); }
.fintiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: 10px; margin-bottom: 12px; }
.fintile { border: 1px solid var(--line); background: var(--panel); padding: 12px 15px 10px; }
.fintile .v { font-size: 22px; font-weight: 700; font-family: var(--mono);
  font-variant-numeric: tabular-nums; color: var(--gold-bright); }
.fintile.hero .v { font-size: 26px; }
.fintile .l { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); margin-top: 2px; }
.fintile .s { font-size: 11.5px; color: var(--text-faint); margin-top: 5px; }
.fintile .s.up, .finledger .up { color: var(--red); }
.fintile .s.down, .finledger .down { color: var(--green); }
.fingrid { display: grid; grid-template-columns: minmax(420px, 5fr) minmax(300px, 3fr);
  gap: 12px; align-items: stretch; }
.finpanel { border: 1px solid var(--line); background: var(--panel); }
.finwide { grid-column: 1 / -1; }
.fph { display: flex; align-items: center; gap: 12px; padding: 10px 14px;
  border-bottom: 1px solid var(--line); font-size: 11.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-dim); flex-wrap: wrap; }
.fph .dim { text-transform: none; letter-spacing: 0; }
.flegend { display: inline-flex; gap: 6px; align-items: center; font-size: 11.5px;
  color: var(--text-faint); text-transform: none; letter-spacing: 0; }
.flegend .lc { width: 10px; height: 10px; display: inline-block; margin-left: 8px; }
.flegend .lc.crew { background: var(--gold-deep); }
.flegend .lc.hod { background: var(--violet); }
.flegend .lc.cum { background: var(--blue); height: 2px; }
/* the cash-out chart — inline SVG, geometry computed server-side */
.fchartwrap { padding: 10px 8px 2px; }
.fchart { width: 100%; height: auto; display: block; }
.fchart .fgrid { stroke: var(--line); stroke-width: 1; }
.fchart .fax { fill: var(--text-faint); font-size: 10.5px; font-family: var(--mono); }
.fchart .fax.onw { fill: var(--gold-bright); font-weight: 700; }
.fchart .faxb { fill: var(--blue); font-size: 10.5px; font-family: var(--mono); }
.fchart .fhit { fill: transparent; }
.fchart .fbc { fill: var(--gold-deep); }
.fchart .fbc.on { fill: var(--gold); }
.fchart .fbc.off, .fchart .fbh.off { fill: var(--raised); }
.fchart a:hover .fbc { fill: var(--gold); }
.fchart .fbh { fill: var(--violet); }
.fchart .fcum { fill: none; stroke: var(--blue); stroke-width: 1.6; }
.fchart .fcumd { fill: var(--blue); }
/* donut + legend */
.findonutwrap { display: flex; gap: 16px; padding: 16px 14px; align-items: center;
  flex-wrap: wrap; }
.fdonut { width: 168px; height: 168px; border-radius: 50%; position: relative;
  flex: 0 0 auto; }
.fdhole { position: absolute; inset: 27px; border-radius: 50%; background: var(--panel);
  display: flex; flex-direction: column; align-items: center; justify-content: center; }
.fdhole b { font-family: var(--mono); font-size: 16px; color: var(--gold-bright); }
.fdhole span { font-size: 9.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); margin-top: 1px; }
.fdlegend { flex: 1; min-width: 190px; display: flex; flex-direction: column; gap: 1px; }
.fdli { display: grid; grid-template-columns: 10px 1fr 42px 78px; gap: 8px;
  align-items: center; padding: 4px 6px; color: var(--text-dim); font-size: 12.5px;
  text-decoration: none; }
a.fdli:hover { background: var(--panel-2); color: var(--text); }
.fdli i { width: 10px; height: 10px; }
.fdli .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fdli b { font-family: var(--mono); font-size: 11.5px; text-align: right; }
.fdli .c { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint);
  text-align: right; }
.seg2 { display: inline-flex; border: 1px solid var(--line); margin-left: auto; }
.seg2 a { color: var(--text-faint); font-size: 11.5px; padding: 3px 12px;
  text-transform: none; letter-spacing: 0; }
.seg2 a.on { background: var(--gold); color: var(--on-gold); font-weight: 600; }
/* breakdown rows with sparklines */
.finrows { padding: 6px 0; }
.finrow { display: grid; grid-template-columns: 18px 12px minmax(110px, 1fr) 94px 84px
  minmax(90px, 2fr) 96px 40px; gap: 9px; align-items: center; padding: 6px 14px;
  color: var(--text); text-decoration: none; }
a.finrow:hover { background: var(--panel-2); }
.frank { font-family: var(--mono); font-size: 10.5px; color: var(--text-faint);
  text-align: right; }
.fdot { width: 10px; height: 10px; }
.fname { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fspark { width: 94px; height: 22px; }
.fspark polyline { fill: none; stroke-width: 1.4; opacity: .9; }
.fmd { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); text-align: right; }
.fbar { height: 13px; background: var(--panel-2); border: 1px solid var(--line); }
.fbar i { display: block; height: 100%; background: linear-gradient(90deg, var(--gold-deep), var(--gold)); }
.fcost { font-family: var(--mono); font-size: 12.5px; text-align: right;
  font-variant-numeric: tabular-nums; }
.fshare { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); text-align: right; }
.fpfoot { padding: 8px 14px 10px; font-size: 11.5px; color: var(--text-faint);
  border-top: 1px solid var(--line); }
/* top roles */
.finroles { padding: 8px 0; }
.frole { display: grid; grid-template-columns: minmax(110px, 1fr) 56px minmax(70px, 1.4fr) 92px;
  gap: 9px; align-items: center; padding: 6px 14px; }
/* the week ledger */
.finledger { width: 100%; border-collapse: collapse; }
.finledger th { text-align: left; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-faint); padding: 8px 14px;
  border-bottom: 1px solid var(--line); white-space: nowrap; }
.finledger th.r, .finledger td.r { text-align: right; }
.finledger td { padding: 7px 14px; border-bottom: 1px solid var(--line); font-size: 12.5px;
  font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.finledger td:first-child { font-family: inherit; font-weight: 600; }
.finledger .dim2 { color: var(--text-faint); font-family: inherit; }
.finledger tbody tr { cursor: pointer; }
.finledger tbody tr:hover { background: var(--panel-2); }
.finledger tr.on { background: var(--gold-wash); }
.finledger tr.on td { color: var(--gold-bright); }
@media (max-width: 1100px) { .fingrid { grid-template-columns: 1fr; } }

/* thin dark scrollbars, V1-style */
* { scrollbar-width: thin; scrollbar-color: var(--raised) var(--panel); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--panel); }
::-webkit-scrollbar-thumb { background: var(--raised); border: 2px solid var(--panel); }
::-webkit-scrollbar-thumb:hover { background: var(--gold-deep); }

@media (max-width: 640px) {
  .top { flex-wrap: wrap; gap: 8px; }
  .wrap { padding: 10px; }
  .frow2 { grid-template-columns: 1fr; }
}

/* Exports tab — the document centre (.ex*): rail of documents, options
   toolbar, the preview frame. The frame shows the real print/preview pages
   (light "paper" against the app chrome) so the export can never surprise. */
.exshell { display: flex; margin: -14px -16px; height: calc(100vh - 46px); }
.exrail { flex: 0 0 250px; border-right: 1px solid var(--line); background: var(--panel);
  padding: 14px 0; display: flex; flex-direction: column; }
.exdoc { display: block; width: 100%; text-align: left; background: none; border: none;
  border-left: 3px solid transparent; padding: 11px 16px; cursor: pointer;
  color: var(--text-dim); font: inherit; }
.exdoc b { display: block; font-size: 14px; color: inherit; }
.exdoc span { display: block; font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }
.exdoc:hover { background: var(--panel-2); color: var(--text); }
.exdoc.on { background: var(--panel-2); border-left-color: var(--gold); color: var(--gold-bright); }
.exmain { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.extools { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 9px 14px; border-bottom: 1px solid var(--line); background: var(--panel); }
.extools [hidden] { display: none !important; }  /* .btn/.exopts set display — the hidden attr must still win */
.exopts { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.exlbl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); }
/* The base rule is width:100% for form pages; inside this flex toolbar a
   full-width control eats the row. The crew sheet's date picker needs it
   as much as the week selects do. */
.exopts select, .exopts input { width: auto; }
.exminis { display: inline-flex; gap: 5px; }
.excrews { display: inline-flex; gap: 4px 12px; flex-wrap: wrap; align-items: center; }
.excrew { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.excrew i { width: 9px; height: 9px; flex: 0 0 auto; }
.excrew.exrates { border-left: 1px solid var(--line); padding-left: 12px; }

/* ---- the workbook's Filter button and its dialog ------------------------
   Owner, 2026-09-12: one button, not a toolbar that grows a control every
   time the workbook learns an option. The button carries a summary of the
   APPLIED state so what it is set to is still readable without opening it,
   and lights up only when that state is not the document's own default. */
.exfbtn { display: inline-flex; align-items: center; gap: 8px;
  background: var(--gold-tint); border-color: var(--gold-deep);
  color: var(--gold-ink); font-weight: 600; }
.exfbtn:hover { background: color-mix(in srgb, var(--gold) 14%, transparent);
  border-color: var(--gold); }
/* The funnel, because it is the emblem people already read as "filter" —
   owner, 2026-09-12. currentColor so it follows the button's own ink through
   both themes and the applied state, rather than being a second thing to
   keep in step. */
.exfbtn .exficon { width: 13px; height: 13px; flex: 0 0 auto; fill: currentColor; }
.exfbtn .exfsum { color: var(--text-faint); font-weight: 400; }
/* APPLIED: a full gold edge and a gold surface, so "a filter is on" is
   legible at a glance and distinct from merely being hoverable. The SOLID
   gold fill stays reserved for Print and Download beside it — those are the
   two actions that leave with a document, and a third would have all three
   shouting at once. */
.exfbtn.on { border-color: var(--gold); background: var(--gold-wash); }
.exfbtn.on .exfsum { color: var(--gold-bright); }

/* A column, not a scrolling block: the head and the actions stay put and the
   BODY scrolls, so Apply is reachable on a job with ninety people in the
   list and on a phone. */
.modal.exfilter { width: min(620px, 94vw); max-height: min(84vh, 720px);
  padding: 0; display: flex; flex-direction: column; }
.exfhead { padding: 16px 20px 12px; border-bottom: 1px solid var(--line); }
.exfhead h3 { margin: 0; }
.exfbody { padding: 4px 20px 16px; overflow-y: auto; flex: 1; min-height: 0; }

/* ---- the dialog's tick boxes -------------------------------------------
   THE ONE FAULT BEHIND MOST OF HOW THIS LOOKED. `input, select, textarea`
   near the top of this file sets `width: 100%` for form pages, and that
   lands on a checkbox too: measured in this dialog, a tick box's LAYOUT
   width was 113px while its painted width was 13px. So every row put its
   tick at one end and its label at the other, and every crew name wrapped
   one word per line. Three other places already patch this locally —
   .startmode for radios, .copyticks for checkboxes, .exopts for the toolbar
   above — and this dialog simply never got one.

   `appearance: none` is the other half. A white Windows checkbox in a dark
   gold-on-charcoal dialog is what read as unfinished; the box is now the
   app's own — panel surface, the app's rule, gold when it is on. */
.exfilter input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 15px; height: 15px; flex: 0 0 auto; margin: 0; padding: 0;
  background: var(--panel-2); border: 1px solid var(--line-2);
  cursor: pointer;
}
.exfilter input[type="checkbox"]:hover:not(:disabled) { border-color: var(--gold-deep); }
.exfilter input[type="checkbox"]:checked {
  background: var(--gold) var(--tick) center / 11px 9px no-repeat;
  border-color: var(--gold);
}
.exfilter input[type="checkbox"]:disabled { cursor: not-allowed; opacity: .5; }
.exfsec { padding: 14px 0 2px; border-bottom: 1px solid var(--line); }
.exfsec:last-child { border-bottom: none; }
.exfsec h4 { margin: 0 0 9px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-faint); font-weight: 600; }
/* Wide enough for a crew name on ONE line at 12.5px. The 180px column was
   not the cause of the wrapping, but it left no room for a name like "Main
   Unit Lamp" once the tick took its proper 15px. */
.exfgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
  gap: 2px 16px; margin-top: 10px; }
.exftools { display: flex; gap: 8px; align-items: center; margin-bottom: 8px; }
.exftools input[type="search"] { flex: 1; min-width: 0; }
/* A LIST PANE, and deliberately one that scrolls inside the dialog. The cap
   is load-bearing: without it a ninety-person production would be the whole
   dialog and Apply would sit below the fold (see
   test_the_actions_cannot_scroll_away_from_a_long_people_list). What was
   wrong is that it did not LOOK deliberate — a second scrollbar with no edge
   around it reads as a mistake. It now carries the app's own inset-panel
   treatment, the one .whosin uses, so it reads as a box with a list in it. */
.exfpeople { display: flex; flex-direction: column; gap: 1px;
  max-height: 252px; overflow-y: auto;
  border: 1px solid var(--line); background: var(--panel-2);
  padding: 6px 10px; }
/* .excrew is inline-flex, which outranks the UA rule behind the hidden
   attribute — the same reason .extools carries this. Search hides rows with
   `hidden`, and a row that will not hide is a row a person thinks they
   deselected. */
.exfpeople [hidden], .exfsec [hidden] { display: none !important; }
.exwhogrp { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); font-weight: 600;
  margin: 9px 0 3px; padding-top: 8px; border-top: 1px solid var(--line); }
.exwhogrp:first-child { margin-top: 0; padding-top: 2px; border-top: none; }
/* CENTRED on the tick rather than flex-start: with a 15px box and one line
   of text, flex-start left the label sitting a pixel high on every row. */
.exfsec .excrew { display: flex; align-items: center; gap: 9px; padding: 3px 0;
  min-width: 0; }
/* A NAME STAYS ON ONE LINE. The secondary text beside it — a HOD's title, a
   person's roles and crews — is the part allowed to run out of room, and it
   ellipsises instead of pushing the name around. */
.exfgrid .excrew { overflow: hidden; }
.exfpeople .excrew { align-items: baseline; }
.exfpeople .excrew .dim {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11.5px; }
.exfnote { margin: 8px 0 2px; font-size: 11.5px; color: var(--text-faint); }
.exfnote.exfoff { color: var(--gold-ink); }
/* THE SWITCH ROW: one tick, one label, a rule under it. It used to carry an
   explanation as a third flex column, which is what made it stack a word per
   line; the explanation is gone (owner, 2026-09-12: no explained wording) and
   so is the two-line block that existed to hold it. */
.exfshoot { border-bottom: 1px solid var(--line); padding: 2px 0 10px;
  margin-bottom: 2px; }
/* A crew outside the population is legible but plainly out of reach — greyed
   and disabled, never hidden: a row that vanished would look like a crew the
   production does not have. */
.excrew.off { opacity: .4; cursor: default; }
.exfweeks { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.exfweeks label { display: inline-flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--text-dim); }
.exfweeks select { width: auto; }
/* The crew list is still legible while it is not in effect — greyed, not
   disabled: a person may well be about to untick everybody and go back to it. */
.exfilter.hasnamed .exfgrid, .exfilter.hasnamed .exminis,
.exfilter.hasnamed .exfshoot { opacity: .45; }
#exboxwrap.off { opacity: .45; }
.exffoot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px 20px; border-top: 1px solid var(--line); background: var(--panel-2); }

@media (max-width: 620px) {
  .modal-backdrop { padding-top: 0; align-items: stretch; }
  .modal.exfilter { width: 100vw; max-height: 100vh; height: 100vh; border: none; }
  .exfgrid { grid-template-columns: 1fr; }
  .exfpeople { max-height: none; }
}
.exspacer { margin-left: auto; }
.exframe { flex: 1; min-height: 0; background: var(--bg); padding: 0; }
.exframe iframe { display: block; width: 100%; height: 100%; border: 0; background: #fff; }
@media (max-width: 1100px) {
  .exshell { flex-direction: column; height: auto; }
  .exrail { flex-direction: row; flex-wrap: wrap; border-right: none;
    border-bottom: 1px solid var(--line); }
  .exrail .surnote { display: none; }
  .exdoc { width: auto; }
  .exframe { height: 72vh; }
}

/* Phases band (V1): one slim strip under the board rows — Prep & Rig /
   Principal Photography / Wrap. Bars are modal-edited, never dragged. */
.pbandrow .rowlbl b { font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-faint); font-weight: 700; }
.pbandtrack { position: relative; height: 30px; flex: 0 0 auto;
  border-top: 1px solid var(--line); }
:root[data-theme="light"] .pbar { color: color-mix(in srgb, var(--c) 45%, #000); }
.pbar { position: absolute; top: 5px; bottom: 5px; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase;
  color: var(--c); background: color-mix(in srgb, var(--c) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--c) 55%, transparent);
  overflow: hidden; white-space: nowrap; }
#pband[data-ed="1"] { cursor: copy; }
#pband[data-ed="1"] .pbar { cursor: pointer; }
.pswatches { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.psw { width: 22px; height: 22px; border-radius: 5px; border: 2px solid transparent;
  background: var(--c); cursor: pointer; padding: 0; }
.psw.on { border-color: var(--text); }

/* Pre-light (owner, 2026-08-07): its own view, a Full/Overlay/Off switch on
   the main board, and a when-badge on every pre-light block. */
.viewtog .tlbl { padding: 3px 9px 3px 11px; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-faint); border-right: 1px solid var(--line); }
.whenbadge { font-family: var(--mono); font-size: 8.5px; font-weight: 700; letter-spacing: .04em;
  padding: 0 3px; border-radius: 2px; background: rgba(0,0,0,.34); color: #fff;
  flex: 0 0 auto; opacity: .92; }
.blk.pl-pre { border-left-style: dotted; border-left-width: 4px; }
.blk.pl-after { border-right: 4px solid var(--c); }
.plsum { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  color: var(--text-dim); margin-left: 4px; }
.plsum b { color: var(--gold-bright); font-family: var(--mono); }
.plsum i { width: 9px; height: 9px; display: inline-block; margin-left: 8px; }
.plsum i.w-pre { background: var(--blue); } .plsum i.w-whole { background: var(--gold); }
.plsum i.w-after { background: var(--violet-2); }
.unittog.wide3 button { flex: 1; }
.wtpl { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 12.5px;
  color: var(--text-dim); white-space: nowrap; }
.wtpl input { width: auto; }

/* Per-crew drill-down (.cs*): one row per seat — crew bookings inherited on
   the top lane, that person's diversions on the lane below. */
.csboard { overflow-x: auto; border: 1px solid var(--line); background: var(--panel); }
.cswatch { display: inline-block; width: 11px; height: 11px; margin-right: 7px; }
.cslbl { width: 220px !important; flex: 0 0 220px !important; }
.csrow .rowlbl { position: relative; }
.csrow .rowlbl .tbcname { color: var(--text-faint); font-style: italic; font-weight: 400; }
.csrow .rowlbl .leadstar { color: var(--gold-ink); font-size: 12.5px; }
.rowadd { position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  background: none; border: 1px solid var(--line); color: var(--text-faint);
  cursor: pointer; font-size: 12.5px; line-height: 1; padding: 2px 6px; }
.rowadd:hover { color: var(--gold-bright); border-color: var(--gold-deep); }
.blk.csbase { background: color-mix(in srgb, var(--c) 22%, var(--panel-2));
  border-left: 3px solid var(--c); cursor: default; }
.blk.csbase.awayblk { opacity: .38; }
.blk.csbase.awayblk .bmain b { text-decoration: line-through; }
.blk.csdiv { background: color-mix(in srgb, var(--blue) 26%, var(--panel-2));
  border: 1px solid var(--blue); border-left-width: 3px; }
.blk.csdiv.clickable { cursor: pointer; }
.blk.csdiv:hover { background: color-mix(in srgb, var(--blue) 38%, var(--panel-2)); }
.divarrow { color: var(--blue); font-weight: 700; margin-right: 3px; }
.rowdrill { position: absolute; top: 4px; right: 25px; width: 17px; height: 17px;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text-dim);
  font-size: 11.5px; line-height: 1; }
.rowdrill:hover { color: var(--gold-bright); border-color: var(--gold-deep); }

/* Roles + Departments (owner, 2026-08-08: split apart, made explicit) */
.rolegrid { border: 1px solid var(--line); background: var(--panel); max-width: 1080px; }
/* a select in a grid row hugs its value — the chevron belongs to the text,
   not to the far edge of the column */
:is(.rgrow, .supline) select { width: auto; justify-self: start; max-width: 100%; }
.seat .inlineform.grow select { width: auto; max-width: 100%; }
.rghead, .rgrow { display: grid; gap: 10px; align-items: center; padding: 6px 12px;
  border-bottom: 1px solid var(--line);
  grid-template-columns: minmax(160px, 1.4fr) minmax(150px, 1fr) 92px 110px 34px; }
.rolegrid.norates .rghead, .rolegrid.norates .rgrow {
  grid-template-columns: minmax(160px, 1.4fr) minmax(150px, 1fr) 92px 34px; }
.rghead { background: var(--panel-2); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .5px; color: var(--text-faint); }
.rghead .r, .rgrow .r { text-align: right; }
.rgrow:hover { background: var(--panel-2); }
.rgrow .rgname { font-weight: 600; }
.rgrow .use { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.rgrow input.raterow { font-family: var(--mono); text-align: right; }
.deptlist { display: flex; flex-direction: column; gap: 6px; max-width: 1280px; }
.deptrow { display: grid; gap: 10px; align-items: center; padding: 8px 12px;
  border: 1px solid var(--line); border-left: 3px solid var(--c);
  background: var(--panel);
  grid-template-columns: 26px 44px minmax(150px, 240px) 150px 1fr 34px; }
.deptrow.unfiled { opacity: .7; border-style: dashed; }
.deptrow .ordbtns { display: flex; flex-direction: column; gap: 2px; }
.deptrow .dn { font-weight: 600; width: auto; }
.deptrow .dcount { font-size: 11.5px; color: var(--text-faint); font-family: var(--mono);
  white-space: nowrap; }
.deptrow .droles { display: flex; gap: 4px; flex-wrap: wrap; }
.rchip { font-size: 11.5px; padding: 1px 7px; background: var(--panel-2);
  border: 1px solid var(--line); color: var(--text-dim); white-space: nowrap; }
@media (max-width: 1000px) {
  .deptrow { grid-template-columns: 26px 44px 1fr 34px; }
  .deptrow .dcount, .deptrow .droles { grid-column: 3 / -1; }
}

/* History filters (owner, 2026-08-08: types + search instead of endless scroll) */
.hfilters { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin: 14px 0 18px; }
.hchips { display: flex; gap: 6px; flex-wrap: wrap; }
.hchips .fchip span { font-family: var(--mono); font-size: 10.5px; }
.hverbs { margin-left: auto; }
.hsearch { display: flex; gap: 6px; align-items: center; }
.hsearch input { width: 280px; }
.tkind { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); border: 1px solid var(--line); padding: 0 5px;
  margin: 0 4px; white-space: nowrap; }
@media (max-width: 900px) { .hverbs { margin-left: 0; } .hsearch input { width: 100%; } }

/* Equipment schedule (.eq*) — the board with kit on the left */
.eqboard .eqlbl { width: 260px !important; flex: 0 0 260px !important; }
.eqcatrow { min-height: 0; }
.brow.eqcatrow .rowlbl.eqcat { font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .7px; color: var(--gold-ink); background: var(--panel);
  padding: 5px 8px; font-weight: 700; }
.eqcatfill { flex: 0 0 auto; background: var(--panel); border-bottom: 1px solid var(--line); }
.blk.eqblk { background: color-mix(in srgb, var(--c) 26%, var(--panel-2));
  border: 1px solid var(--c); border-left-width: 3px; }
.eqboard .track[data-ed="1"] { cursor: copy; }
.eqboard .blk.eqblk[data-ed="1"] { cursor: grab; }
.eqboard .blk.eqblk.dragging { cursor: grabbing; }
.blk.eqblk:hover { background: color-mix(in srgb, var(--c) 40%, var(--panel-2)); }
.blk.eqblk.clash { border-color: var(--red); background: color-mix(in srgb, var(--red) 26%, var(--panel-2)); }
.eqclashwarn { color: var(--red); font-size: 12.5px; font-weight: 600; }
.secl2 { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--text-faint); margin: 0 0 8px; }
.eqgrid .rghead, .eqgrid .rgrow {
  grid-template-columns: minmax(160px, 1.4fr) minmax(130px, 1fr) 130px minmax(140px, 1.2fr) 34px; }

/* ============================================================================
   DASHBOARD — "the production's front page" (owner-approved, 2026-08-14).
   Third build. The first two led with schedule-shaped data and neither
   landed; this one leads with IDENTITY and ORIENTATION and demotes the
   numbers. Built to mockups/dashboard-front-page/ — see SPEC.md there.

   Type scale holds at 10.5/11.5/12.5/14/16/19 with two standing exemptions:
   mono numerals, and the masthead title (31px, same class of exemption as
   the landing brand — do not reuse it anywhere else on the page).
   ========================================================================= */

/* ---- masthead ---------------------------------------------------------- */
.mast { padding: 16px 0 0; }
.mastrow { display: flex; align-items: flex-start; gap: 18px; flex-wrap: wrap; }
.mastid { min-width: 0; }
.eyebrow { display: block; font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 1.6px; text-transform: uppercase; color: var(--text-faint);
  margin-bottom: 6px; }
.mast h1 { margin: 0 0 4px; font-size: 31px; line-height: 1.1; letter-spacing: -.4px;
  font-weight: 650; display: flex; align-items: center; gap: 12px; }
.mast h1 .mdot { width: 11px; height: 11px; background: var(--gold); flex: 0 0 auto; }
.mastmeta { font-size: 12.5px; color: var(--text-dim); }
.mastmeta b { color: var(--text); font-weight: 600; }
.mastmeta .sun { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.mastmeta .sep { color: var(--text-faint); padding: 0 5px; }
.mastact { margin-left: auto; display: flex; flex-direction: column;
  align-items: flex-end; gap: 8px; padding-top: 16px; }
.mastact .row { display: flex; gap: 8px; align-items: center; }
/* Links, not buttons: the switch is a real ?focus= navigation, so it works
   without JS and can be bookmarked. Styled here because it lives only on
   this page. */
.focustog { display: inline-flex; border: 1px solid var(--line); background: var(--panel-2); }
.focustog a { padding: 4px 12px; font-size: 12.5px; color: var(--text-dim); }
.focustog a + a { border-left: 1px solid var(--line); }
.focustog a:hover { color: var(--text); background: var(--panel); }
.focustog a.on { background: var(--gold); color: var(--on-gold); font-weight: 600; }
.deptline { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.deptline b { color: var(--text-dim); font-weight: 600; }
/* An unfilled seat is the one number here that is a job to do, not a fact. */
.deptline b.tbc { color: var(--gold-bright); }

/* ---- the body grid ----------------------------------------------------- */
.dashgrid { display: grid; grid-template-columns: 2fr 1fr; gap: 14px;
  margin-top: 14px; align-items: start; }
.dcol { display: grid; gap: 14px; align-content: start; min-width: 0; }
.dpanel { background: var(--panel); border: 1px solid var(--line);
  box-shadow: var(--shadow-sm); min-width: 0; }
.dph { display: flex; align-items: baseline; gap: 10px; padding: 10px 14px 9px;
  border-bottom: 1px solid var(--line); font-family: var(--mono); font-size: 10.5px;
  letter-spacing: 1.4px; text-transform: uppercase; color: var(--text-faint);
  flex-wrap: wrap; }
/* Everything that isn't the header's own label has to RESET the mono caps it
   sets, or a sentence inside .dph comes out shouting. */
.dph .sub, .dph .end, .dph .trend { font-family: var(--sans); letter-spacing: 0;
  text-transform: none; }
.dph .sub { font-size: 12.5px; color: var(--text-dim); }
.dph .end { margin-left: auto; font-size: 12.5px; }

/* ---- noticeboard: a full-width pinboard, not a column ------------------- */
.nboard { margin-top: 18px; }
.pinrow { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)) 360px;
  gap: 10px; padding: 12px 14px; align-items: start; }
.pinrow.noform { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.pin { border: 1px solid var(--line); background: var(--panel-2); padding: 9px 12px 8px; }
.pin.lv-warn { border-top: 2px solid var(--gold); }
.pin.lv-urgent { border-top: 2px solid var(--red); }
.pin .nb { font-size: 12.5px; }
.pin.lv-warn .nb::before { content: "⚠ "; color: var(--gold-bright); }
.pin.lv-urgent .nb::before { content: "⚠ "; color: var(--red); }
.pin .nm { font-size: 11.5px; color: var(--text-faint); margin-top: 3px; }
.pinempty { margin: 0; }
.noteform textarea { width: 100%; resize: vertical; font-size: 12.5px; }
.noteform .arow { display: flex; gap: 8px; margin-top: 8px; }
/* Neither control may collapse. A plain flex row squeezed the select to the
   width of "N" and the date picker to a sliver — both then say nothing at
   all, which is worse than either being a little narrow. */
.noteform .arow select { flex: 0 1 104px; min-width: 88px; }
.noteform .arow input { flex: 1 1 auto; min-width: 112px; }
.noteform .btn { flex: 0 0 auto; }

/* ---- today on the floor: location-first cards -------------------------- */
.floor { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 10px; padding: 12px 14px; }
.locard { display: block; border: 1px solid var(--line);
  border-left: 3px solid var(--c, var(--gold)); background: var(--panel-2);
  padding: 10px 12px 9px; color: inherit; min-width: 0; }
.locard:hover { border-color: var(--gold-deep); border-left-color: var(--c); color: inherit; }
.locard .top { display: flex; align-items: baseline; gap: 8px; }
.locard .loc { font-size: 16px; font-weight: 650; letter-spacing: -.2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.locard .act { display: block; font-size: 12.5px; color: var(--text-dim);
  margin: 1px 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.locard .crew { display: flex; align-items: center; gap: 7px; font-size: 12.5px;
  min-width: 0; }
.locard .crew .cc { width: 10px; height: 10px; background: var(--c); flex: 0 0 auto; }
.locard .crew b { font-weight: 600; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.locard .crew .heads { color: var(--text-faint); white-space: nowrap; flex: 0 0 auto; }
.mk { margin-left: auto; font-family: var(--mono); font-size: 10.5px; letter-spacing: .6px;
  text-transform: uppercase; padding: 1px 7px; border: 1px solid var(--line);
  color: var(--text-faint); white-space: nowrap; flex: 0 0 auto; }
.mk.starts { color: var(--green); border-color: var(--green); }
.mk.wraps { color: var(--gold-bright); border-color: var(--gold-deep); }
.kitline { display: flex; align-items: center; gap: 9px; margin: 0 14px 12px;
  padding: 7px 11px; border: 1px solid var(--line); border-left: 3px solid var(--blue);
  background: var(--panel-2); font-size: 12.5px; color: var(--text-dim); }
.kitline b { color: var(--text); }
.kitline .tag { font-family: var(--mono); font-size: 10.5px; letter-spacing: .6px;
  text-transform: uppercase; color: var(--blue); flex: 0 0 auto; }

/* Focus QUIETENS the other side, it never removes it (owner, 2026-08-09:
   "catered more towards"). Three quiet signals and no opacity — opacity on
   opacity is what took a label to a quarter strength last time. */
.dash[data-focus="rig"] .side-shoot,
.dash[data-focus="shoot"] .side-rig { border-left-style: dashed; background: var(--panel); }
.dash[data-focus="rig"] .side-shoot .loc,
.dash[data-focus="shoot"] .side-rig .loc { color: var(--text-faint); }
.dash[data-focus="rig"] .side-shoot .cc,
.dash[data-focus="shoot"] .side-rig .cc { background: none;
  box-shadow: inset 0 0 0 1.5px var(--c); }

/* ---- the week ahead: the load strip, demoted ---------------------------- */
.trend { font-size: 12.5px; color: var(--text-faint); }
.trend b { font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-weight: 600; color: var(--text-dim); }
.trend em { font-style: normal; color: var(--text-dim); }
.trend.up em { color: var(--gold-bright); }
.trend.down em { color: var(--green); }
.wkstrip { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px;
  padding: 14px 14px 4px; }
.wkday { text-align: center; padding: 4px 2px 6px; min-width: 0; }
.wkday.we { background: var(--we-shade); }
.wkday.outside { background: var(--bg-alt); }
.wkday.today { box-shadow: inset 0 -2px 0 var(--gold-ink); }
/* One shared scale across all seven, or the days stop being comparable —
   which is the only job this thing has. */
.wkbar { display: flex; flex-direction: column; justify-content: flex-end;
  align-items: stretch; height: 64px; padding: 0 14px; }
.wkbar i { display: block; }
.wkbar i.z { display: none; }
.wkbar .sh { background: var(--load-shoot); margin-bottom: 2px; }
.wkbar .sh:last-child { margin-bottom: 0; }
.wkbar .rg { background: var(--load-rig); }
/* The far side keeps its HEIGHT and loses its fill: the bar still tells the
   truth about how many people are out. */
.dash[data-focus="rig"] .wkbar .sh { background: none;
  box-shadow: inset 0 0 0 1px var(--load-shoot); }
.dash[data-focus="shoot"] .wkbar .rg { background: none;
  box-shadow: inset 0 0 0 1px var(--load-rig); }
.wkn { display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 11.5px; font-weight: 600; margin-top: 5px; }
.wkn.nil { color: var(--text-faint); font-weight: 400; }
.wkd { display: block; font-family: var(--mono); font-size: 10.5px; letter-spacing: .6px;
  color: var(--text-faint); margin-top: 1px; }
.wkd b { color: var(--text-dim); font-weight: 600; margin-right: 3px; }
.wkday.today .wkd, .wkday.today .wkd b { color: var(--gold-bright); }
.wkfoot { display: flex; align-items: center; gap: 14px; padding: 8px 14px 11px;
  font-size: 11.5px; color: var(--text-faint); flex-wrap: wrap; }
.wkfoot .key { display: inline-flex; align-items: center; gap: 6px; }
.wkfoot .key i { width: 9px; height: 9px; }
.wkfoot .key i.rg { background: var(--load-rig); }
.wkfoot .key i.sh { background: var(--load-shoot); margin-left: 8px; }
.wkfoot .key .ku { margin-left: 8px; }
/* The one thing a load strip cannot say that the old crew rows could. */
.wkfoot .idle { margin-left: auto; }
.wkfoot .idle b { color: var(--text-dim); font-weight: 600; }

/* ---- needs you: ranked, and every row says what to do about it ---------- */
.work { padding: 6px 0; }
.wrow { display: flex; align-items: center; gap: 11px; padding: 8px 14px;
  color: inherit; }
.wrow:hover { background: var(--panel-2); color: inherit; }
.wrow > i { flex: 0 0 auto; width: 8px; height: 8px; background: var(--text-faint); }
.wrow.lv-0 > i { background: var(--red); }
.wrow.lv-1 > i, .wrow.lv-2 > i { background: var(--gold); }
.wrow .txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.wrow .txt b { font-size: 12.5px; font-weight: 600; }
.wrow.lv-0 .txt b { color: var(--red); }
.wrow .txt > span { font-size: 11.5px; color: var(--text-faint); }
.wrow .go { margin-left: auto; font-size: 12.5px; color: var(--gold-bright);
  white-space: nowrap; }
.allclear { padding: 15px 14px; font-size: 12.5px; color: var(--text-dim); }
.allclear b { display: block; color: var(--green); font-size: 14px; margin-bottom: 2px; }

/* ---- coming up --------------------------------------------------------- */
.cominglist { padding: 4px 0 6px; }
.comingrow { display: flex; align-items: center; gap: 12px; padding: 7px 14px;
  color: inherit; }
.comingrow:hover { background: var(--panel-2); color: inherit; }
.comingrow .cwhen { flex: 0 0 auto; width: 66px; display: flex; flex-direction: column; }
.comingrow .cwhen b { font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: .5px; }
.comingrow .cwhen span { font-family: var(--mono); font-size: 10.5px; color: var(--text-faint); }
.comingrow .ctxt { display: flex; flex-direction: column; min-width: 0; }
.comingrow .ctitle { font-size: 12.5px; font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.comingrow .ccat { font-size: 11.5px; color: var(--text-faint); }

/* ---- the run rail: the whole production in one band --------------------- */
/* The only place in the app that shows the run in one piece — the board and
   the strip are both windows onto it. */
.runrail { margin: 26px 0 0; }
.railband { position: relative; display: flex; height: 34px;
  border: 1px solid var(--line); background: var(--panel); }
.rphase { position: relative; display: flex; align-items: center; gap: 7px;
  padding: 0 10px; font-family: var(--mono); font-size: 10.5px; letter-spacing: 1px;
  text-transform: uppercase; color: var(--text-dim); white-space: nowrap;
  overflow: hidden; min-width: 0;
  /* 18% keeps --text legible over a phase colour in BOTH themes; the colour
     arrives from the database, so this is the same discipline the board uses
     for its crew fills. Do not raise it. */
  background: color-mix(in srgb, var(--c) 18%, var(--panel)); }
.rphase + .rphase { border-left: 1px solid var(--line-2); }
.rphase.gap { background: var(--panel); }
/* Too thin to letter: it keeps the colour, the tooltip and a slightly firmer
   fill so it still reads as a phase rather than as a seam. */
.rphase.narrow { padding: 0; background: color-mix(in srgb, var(--c) 34%, var(--panel)); }
.rphase b { color: var(--text); font-weight: 600; letter-spacing: 1px;
  overflow: hidden; text-overflow: ellipsis; }
.rphase .wks { color: var(--text-faint); }
.railmark { position: absolute; top: -7px; bottom: -3px; width: 0;
  border-left: 2px solid var(--gold); z-index: 2; }
.railmark span { position: absolute; top: -16px; left: -2px; white-space: nowrap;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: 1px;
  color: var(--gold-bright); }
/* Elapsed time is a rule under the band, not a repaint of it — the phases
   have to keep reading as phases. */
.railprog { height: 2px; background: var(--line); position: relative; }
.railprog i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--gold); }
.railends { display: flex; justify-content: space-between; margin-top: 5px; }
.railends span { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }

/* ---- what's changed: one line, not a feed ------------------------------ */
.changeline { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; padding: 9px 14px; border: 1px solid var(--line);
  background: var(--panel); font-size: 12.5px; color: var(--text-dim); }
.changeline .lbl { font-family: var(--mono); font-size: 10.5px; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--text-faint); margin-right: 4px; }
.changeline .t { font-family: var(--mono); font-size: 11.5px; color: var(--text-faint); }
.changeline b { color: var(--text); font-weight: 600; }
.changeline .sep { color: var(--line-2); }
.changeline .none { color: var(--text-faint); }
.changeline .end { margin-left: auto; font-size: 12.5px; }

/* ---- rest day / before the start / after the wrap ----------------------- */
.restday { padding: 14px; display: flex; gap: 14px; align-items: baseline;
  flex-wrap: wrap; }
.restday b { font-size: 14px; }
.restday span { font-size: 12.5px; color: var(--text-dim); }

@media (max-width: 1180px) {
  .dashgrid { grid-template-columns: 1fr; }
  .pinrow, .pinrow.noform { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .mastact { margin-left: 0; align-items: flex-start; padding-top: 4px; }
  .mast h1 { font-size: 24px; }
  .wkstrip { padding: 12px 8px 4px; }
  .wkbar { padding: 0 6px; }
}

/* Crew self-service details */
.obprompt span { color: var(--text-dim); font-size: 12.5px; }
.sharebox { border: 1px solid var(--line); background: var(--panel); padding: 14px 16px;
  margin: 18px 0; }
.shl { font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--text-faint); margin-bottom: 6px; }
.shrow { display: flex; gap: 8px; }
.shrow input { font-family: var(--mono); font-size: 12.5px; }
.shrow .btn { white-space: nowrap; }
.shmeta { margin-top: 8px; font-size: 12.5px; color: var(--text-faint); }
.pillopen, .pillshut { font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  padding: 1px 7px; margin-right: 4px; }
.pillopen { background: var(--green); color: var(--on-green); font-weight: 600; }
.pillshut { background: var(--raised); color: var(--text-dim); }
tr.pending td { opacity: .62; }

/* ── Calendar (owner, 2026-08-10) ─────────────────────────────────────────
   A casual shared production diary, deliberately not the Schedule: no
   units/crews/locations, just a date. "Tap a day → type the thing → done."
   Category colour is one custom property so it drives a chip's fill, a row's
   left stripe and a dot with a single rule per category — the same pattern
   --c (crew colour) already uses elsewhere. */
[data-cat] { --catc: var(--text-faint); }
[data-cat="delivery"] { --catc: var(--blue); }
[data-cat="collection"] { --catc: var(--violet-2); }
[data-cat="movement"] { --catc: var(--gold); }
[data-cat="meeting"] { --catc: var(--green); }
[data-cat="reminder"] { --catc: var(--red); }
[data-cat="production"] { --catc: var(--gold-deep); }

.calbar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; }
.calbar h1 { margin: 0; margin-right: auto; }
.calnav { display: flex; align-items: center; gap: 8px; }
/* Context, not component. The month is the .stepval of a shared group now
   (static/datenav.css), so size and alignment come from there; what is left
   here is the WIDTH — "September 2026" against "May 2026" is a five-character
   swing, and the group would jump under the cursor between two presses of the
   same arrow — and the weight, which keeps the month the thing the eye lands
   on inside its own group. It drops from 14px to the family's 12.5px
   deliberately: a group whose value is a size larger than every other one in
   the app is taller than they are, which is the inconsistency being removed.
   The narrow-screen rule below already used 12.5px. */
.calmonth { font-weight: 600; min-width: 148px; }

/* minmax(0, …) everywhere, not 1fr: a bare 1fr is minmax(AUTO, 1fr), so a
   long event title in one cell widened that column, shoved the other six out
   of true and pushed the day panel off the right of the page. The grid must
   size from the page inward and let .cchip's ellipsis do its job. */
.calwrap { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 14px; align-items: start; }

.calgrid { border: 1px solid var(--line); background: var(--panel); min-width: 0; }
.calweekhead { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.calweekhead span { padding: 6px 8px; font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .4px; color: var(--text-faint); border-bottom: 1px solid var(--line);
  min-width: 0; overflow: hidden; }
.calweek { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.calcell { display: flex; flex-direction: column; gap: 4px; min-height: 92px; min-width: 0;
  padding: 5px 6px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  color: var(--text); position: relative; overflow: hidden; }
.calweek .calcell:last-child { border-right: 0; }
.calcell:hover { background: var(--panel-2); }
.calcell.we { background: var(--bg-alt); }
.calcell.we:hover { background: var(--panel-2); }
.calcell.muted { color: var(--text-faint); }
.calcell.muted .cn { color: var(--text-faint); }
.calcell.today .cn { background: var(--gold); color: var(--on-gold); font-weight: 700; }
.calcell.sel { box-shadow: inset 0 0 0 2px var(--gold-deep); }
.calcell .cn { align-self: flex-start; font-size: 11.5px; font-family: var(--mono);
  width: 19px; height: 19px; display: flex; align-items: center; justify-content: center; }
.cevents { display: flex; flex-direction: column; gap: 2px; min-width: 0; max-width: 100%; }
.cchip { font-size: 10.5px; line-height: 1.35; padding: 1px 5px; border-left: 2px solid var(--catc);
  background: var(--panel-2); color: var(--text-dim); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; cursor: grab; min-width: 0; max-width: 100%; }
.cchip b { color: var(--text); font-weight: 600; font-family: var(--mono); }
.cchip:active { cursor: grabbing; }
.cmore { font-size: 10px; color: var(--text-faint); padding: 0 5px; }

.caldaypanel { border: 1px solid var(--line); background: var(--panel); min-width: 0; }
.caldayhead { display: flex; align-items: baseline; gap: 8px; padding: 10px 14px;
  border-bottom: 1px solid var(--line); }
.caldayhead h3 { margin: 0; }
.caltoday { font-size: 10.5px; text-transform: uppercase; letter-spacing: .4px;
  color: var(--gold-bright); border: 1px solid var(--gold-deep); padding: 1px 6px; }
.calnoday { border: 1px dashed var(--line); background: var(--panel); padding: 20px;
  text-align: center; color: var(--text-dim); }
.calnoday b { display: block; color: var(--text); margin-bottom: 3px; }
.calempty { padding: 16px 14px; color: var(--text-faint); font-size: 12.5px; }

.calevrow { display: block; width: 100%; text-align: left; font: inherit; color: inherit;
  background: none; border: none; border-left: 3px solid var(--catc);
  border-bottom: 1px solid var(--line); padding: 8px 12px; cursor: pointer; }
.calevrow:hover { background: var(--panel-2); }
.calevrow .evtime { display: block; font-size: 10.5px; font-family: var(--mono);
  color: var(--text-faint); }
.calevrow .evtitle { display: block; font-size: 13px; font-weight: 600; }
.calevrow .evnotes { display: block; font-size: 11.5px; color: var(--text-dim);
  margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.caladdform { padding: 10px 14px 12px; border-top: 1px solid var(--line); }
.caladdform input[type="text"], .caladdform textarea { width: 100%; }
.caladdrow { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.calalldaylbl { display: flex; align-items: center; gap: 5px; font-size: 11.5px;
  color: var(--text-dim); white-space: nowrap; }
.calalldaylbl input { width: auto; }
.caltimes { display: flex; align-items: center; gap: 4px; }
.caltimes input { width: 84px; }
.calto { color: var(--text-faint); }
.caladdrow select { width: auto; flex: 1; min-width: 110px; }
.caladdform textarea { margin-top: 8px; }
.calviewonly { padding: 12px 14px; font-size: 11.5px; color: var(--text-faint);
  border-top: 1px solid var(--line); }

/* ── dashboard "Coming up" panel ─────────────────────────────────────── */
.cominglist { display: flex; flex-direction: column; }
.comingrow { display: grid; grid-template-columns: 76px 1fr; gap: 10px; padding: 8px 14px;
  border-bottom: 1px solid var(--line); border-left: 3px solid var(--catc); color: inherit;
  font: inherit; }
a.comingrow:hover { background: var(--panel-2); }
.comingrow:last-child { border-bottom: 0; }
.comingrow .cwhen { font-size: 11.5px; color: var(--text-faint); }
.comingrow .cwhen b { display: block; font-size: 12.5px; color: var(--text); font-weight: 600; }
.comingrow .ctxt { min-width: 0; }
.comingrow .ctitle { display: block; font-size: 12.5px; font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.comingrow .ccat { font-size: 10.5px; color: var(--text-faint); text-transform: uppercase;
  letter-spacing: .4px; }

@media (max-width: 1000px) {
  .calwrap { grid-template-columns: 1fr; }
  .calcell { min-height: 64px; }
}
@media (max-width: 640px) {
  .calweekhead span { font-size: 9.5px; padding: 4px 3px; }
  .calcell { min-height: 56px; padding: 3px 4px; gap: 2px; }
  .calcell .cn { font-size: 10.5px; width: 16px; height: 16px; }
  .cchip { font-size: 9.5px; padding: 0 3px; }
  .calbar h1 { font-size: 16px; }
  /* font-size went with the component; on a phone the month gives up its
     floor so the group can shrink to the row rather than push Today off it. */
  .calmonth { min-width: 0; }
}

/* ---- WHERE THE DROPDOWN STANDS (.qcsel) --------------------------------
   The control ITSELF is static/dropdown.css, a file of its own, because the
   two standalone print documents need it and must not load this stylesheet.
   What stays here is only how a .qcsel sizes in the places this app puts one
   — context, not component. Editing the look of a dropdown? Wrong file.

   Toolbars need no rule at all any more — .qcsel.plain sizes to its content
   by default, the way a native select in a toolbar does, so Exports and both
   document toolbars are handled by the component. The notice row is the one
   place that needs its own number: a plain flex row squeezed the level picker
   to the width of "N", which is the same reason its <select> carried a rule
   before it was replaced. */
.noteform .arow .qcsel.plain { flex: 0 1 104px; min-width: 88px; }

/* Context fits: a seat's picker fills its row, the add-seat row shares space
   with the role picker, and TBC keeps the dashed edge it has as a <select>. */
.seat .inlineform.grow .qcsel { width: 100%; }
/* the booking modal's seat puts the picker straight into the flex row */
.seat > .qcsel { flex: 1; min-width: 0; }
.addseat .qcsel, .sudetail .addseat .qcsel { flex: 1; }
.seat.tbc .qcsel-btn { border-style: dashed; color: var(--text-dim); }


/* ── Core Labour List ─────────────────────────────────────────────────────
   The organisation's roster, above the production layer. Deliberately the
   same furniture as Setup — same table, same rows, same buttons — because it
   is the same job of work, just one level up. Tokens only; no new colours. */
.labpage { max-width: 900px; }
.labhead { display: flex; gap: 20px; align-items: flex-start;
           justify-content: space-between; margin-bottom: 18px; }
.labhead h1 { margin: 0 0 4px; }
.labhead .sub { display: block; max-width: 56ch; color: var(--ink-3); font-size: 12.5px;
                line-height: 1.5; }
.labbar { display: flex; gap: 16px; align-items: center; justify-content: space-between;
          flex-wrap: wrap; margin-bottom: 10px; }
.labsearch { display: flex; gap: 6px; }
.labsearch input { min-width: 240px; }
.labtabs { display: flex; gap: 2px; }
.labtabs a { padding: 5px 11px; font-size: 12.5px; color: var(--ink-3);
             background: var(--panel-2); border: 1px solid var(--line); }
/* --ink-1 IS DEFINED NOWHERE — a pre-existing typo, so this colour has always
   resolved to nothing and the tab inherits. Left exactly as found: correcting
   it would change dark, which this job may not do. Flagged, not fixed. */
.labtabs a.on { color: var(--ink-1); box-shadow: inset 0 -2px 0 var(--gold-ink); }
.labtabs .n { margin-left: 6px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.labtable { width: 100%; border-collapse: collapse; }
.labtable th { text-align: left; padding: 7px 10px; font-size: 11px; font-weight: 600;
               letter-spacing: .06em; text-transform: uppercase; color: var(--ink-4);
               border-bottom: 1px solid var(--line); }
.labtable td { padding: 4px 10px; border-bottom: 1px solid var(--line-2);
               vertical-align: middle; }
.labtable .ract { text-align: right; white-space: nowrap; width: 1%; }
.labtable .rcheck { width: 1%; padding-right: 0; }
.labrowform { padding: 0 !important; }
.labline { display: flex; gap: 6px; padding: 3px 10px; }
.labline input { flex: 1; min-width: 0; }
.labfoot { margin-top: 20px; }

/* ---------------------------------------------------------------------------
   The lobby: today, then your jobs, then your company.
   Owner, 2026-08-12 — the old page was a heading and some cards, and the
   labour list hung off a company name as a small button. Three bands now, in
   the order the day asks for them.
   --------------------------------------------------------------------------- */
.band { margin-bottom: 28px; }
.bandhead { display: flex; align-items: baseline; gap: 12px; margin-bottom: 10px;
            padding-bottom: 8px; border-bottom: 1px solid var(--line-soft, var(--line)); }
.bandhead .bt { font-size: 10.5px; text-transform: uppercase; letter-spacing: .8px;
                color: var(--text-faint); font-weight: 600; }
.bandhead .bn { font-family: var(--mono); font-size: 10.5px; color: var(--gold-ink);
                font-variant-numeric: tabular-nums; }

/* Job cards carry signal, not just a name: where the job has got to, and the
   one number worth acting on — seats with nobody in them. */
.jobs { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); }
.job { display: block; background: var(--panel); border: 1px solid var(--line); color: var(--text); }
.job:hover { border-color: var(--gold-deep); }
.jtop { display: block; padding: 15px 17px 13px; border-bottom: 1px solid var(--line-soft, var(--line)); }
.jname { display: flex; align-items: center; gap: 9px; font-size: 16px; font-weight: 600;
         letter-spacing: -.2px; }
.jcode { font-family: var(--mono); font-size: 10px; color: var(--text-faint);
         border: 1px solid var(--line); padding: 2px 5px; font-weight: 400; }
.jpill { font-size: 9.5px; text-transform: uppercase; letter-spacing: .6px; padding: 3px 8px;
         margin-left: auto; font-weight: 600; background: var(--raised); color: var(--text-dim); }
.jpill.prep { background: rgba(227,169,59,.14); color: var(--gold-bright); }
.jpill.shooting { background: rgba(72,199,142,.14); color: var(--green); }
.jdates { display: block; font-family: var(--mono); font-size: 11px; color: var(--text-faint);
          margin-top: 7px; font-variant-numeric: tabular-nums; }
.jdates b { color: var(--text-dim); font-weight: 500; }
.jstats { display: grid; grid-template-columns: repeat(3, 1fr); }
.jstat { padding: 12px 17px; border-right: 1px solid var(--line-soft, var(--line)); }
.jstat:last-child { border-right: 0; }
.jstat b { display: block; font-size: 19px; font-weight: 600; letter-spacing: -.3px;
           font-variant-numeric: tabular-nums; }
.jstat i { display: block; font-style: normal; font-size: 9.5px; text-transform: uppercase;
           letter-spacing: .6px; color: var(--text-faint); margin-top: 1px; }
.jstat.gap b { color: var(--gold-ink); }
.jfoot { display: block; border-top: 1px solid var(--line-soft, var(--line)); padding: 10px 17px;
         font-size: 12px; color: var(--text-faint); }
.jfoot b { color: var(--text-dim); font-weight: 500; }
.newjob { display: flex; align-items: center; justify-content: center; min-height: 150px;
          border-style: dashed; color: var(--text-faint); font-size: 13px; }

/* Work you have finished stays reachable — a wrapped job is exactly what you
   go back to look something up on — but it must not shout over the one you
   are on today. Quieter, two stats instead of three (a finished job has no
   seats left to fill), and it comes back to full strength on hover. */
.job.done { opacity: .62; }
.job.done:hover { opacity: 1; }
.job.done .jname { font-size: 15px; }
.job.done .jstats { grid-template-columns: repeat(2, 1fr); }
.jpill.closed, .jpill.wrap { background: var(--raised); color: var(--text-faint); }

/* The roster is the company's, not a job's — so it gets the company's panel
   rather than a button beside a heading. */
.teamband { background: var(--panel); border: 1px solid var(--line); }
.chead { display: flex; align-items: center; gap: 12px; padding: 14px 17px; flex-wrap: wrap; }
.cname { font-size: 15px; font-weight: 600; }
.clabel { font-size: 11px; color: var(--text-faint); }
.chead .btn { margin-left: auto; }
/* Says out loud what the roster IS, because "it carries over between jobs" is
   the whole point and nobody infers it from a headcount. */
.cwhat { margin: 0; padding: 0 17px 15px; font-size: 12.5px; color: var(--text-faint);
         max-width: 78ch; border-bottom: 1px solid var(--line-soft, var(--line)); }
.bandhead .bmore { margin-left: auto; font-size: 11px; color: var(--text-faint); }
.roster { display: grid; grid-template-columns: 150px 1fr; }
.rcount { padding: 17px; border-right: 1px solid var(--line-soft, var(--line)); }
.rcount b { display: block; font-size: 32px; font-weight: 600; letter-spacing: -1px;
            font-variant-numeric: tabular-nums; }
.rcount i { display: block; font-style: normal; font-size: 9.5px; text-transform: uppercase;
            letter-spacing: .6px; color: var(--text-faint); }
.rdepts { padding: 15px 17px; display: flex; flex-wrap: wrap; gap: 7px; align-content: flex-start; }
.rdept { font-size: 11.5px; color: var(--text-dim); border: 1px solid var(--line);
         padding: 5px 10px; display: flex; gap: 8px; align-items: center; background: var(--bg-alt, var(--bg)); }
.rdept em { font-style: normal; color: var(--text-faint); font-family: var(--mono); font-size: 10.5px; }
.rdept.more { color: var(--text-faint); border-style: dashed; }
.rempty { padding: 20px 17px; display: flex; gap: 16px; align-items: center; flex-wrap: wrap; }
.rempty p { margin: 0; color: var(--text-dim); font-size: 12.5px; max-width: 52ch; }

/* "How this works" copy. People arrive on a job by being crewed, which is not
   guessable from an empty table — so the pages that changed say so, once,
   where the question gets asked. */
.suhow, .labhow {
  margin: 0 0 14px; padding: 12px 14px; font-size: 12.5px; line-height: 1.65;
  color: var(--text-dim); background: var(--bg-alt); border: 1px solid var(--line);
  border-left: 3px solid var(--gold); max-width: 100ch;
}
.suhow b, .labhow b { color: var(--text); font-weight: 600; }
.labhow { margin-bottom: 18px; }

@media (max-width: 720px) {
  .trow { grid-template-columns: 4px 1fr 88px; }
  .tkind, .twho { display: none; }
  .roster { grid-template-columns: 1fr; }
  .rcount { border-right: 0; border-bottom: 1px solid var(--line-soft, var(--line)); }
}
