/* ===========================================================================
   CREW OS -- the design tokens, in one place
   ===========================================================================
   Until the refactor, every page carried its own copy of these and they had
   drifted -- --accent was #00c26e on fifteen pages and #ffffff on two, three
   font stacks were in use, 37 of 77 tokens disagreed somewhere. The refactor
   pulled the values every page already shared into this one file so linking it
   changed nothing, and gave the redesign a single place to land.

   THE REDESIGN HAS LANDED. The values below are no longer "what was already
   shipping" -- they are the new palette (approved 2026-09-04): black is the
   brand, green is a signal (dots, bars, positive deltas -- never a button fill,
   never body text), and every text/ground pair passes WCAG AA at its size.
   Redefine a token here and every page that links this file follows.

   HOW THE THEMES RESOLVE  (default is dark, per the brief -- "go black")
     :root                                 light, and the fallback for everything
     @media (prefers-color-scheme: dark)   dark when the OS is dark and nothing
       :root:not([data-theme="light"])       stamped otherwise
     :root[data-theme="dark"]              dark when the app stamps it (the shell
                                             toggle writes localStorage 'crew-theme')
     :root[data-theme="light"]             light stays the bare :root above; the
                                             stamp just turns the media query off

   The shell (js/crew-shell.js) flips data-theme on <html> and remembers it. Each
   staff page also carries a tiny bootstrap in <head>, before this stylesheet, so
   there is no flash of the wrong theme on load. Patient-facing forms and printed
   reports stamp data-theme="light" in the markup and ship no toggle.

   TWO RULES THE VALUES ENCODE, worth keeping in mind when you edit a page:
     - --white / --black and --paper / --ink invert TOGETHER. A rule written as
       `background: var(--ink); color: var(--paper)` survives both themes; one
       written as `background: var(--ink); color: #fff` does not.
     - In the dark there are no drop shadows on resting surfaces -- elevation is a
       lighter surface and a 1px top edge that catches light (see --shadow-*).
       Floating panels keep a deep shadow.

   A page that genuinely differs may still keep a short :root of its own AFTER
   this link, and should say why. Four pages were dark by hand before the
   redesign; events.html and intake-backfill.html are now folded onto these
   tokens, and pto.html and login.html remain hand-dark until their own rebuild.
   =========================================================================== */

:root {
  /* Ground and surfaces */
  --bg:             #f2f3f1;
  --paper:          #ffffff;
  --surface:        #f8f9f7;
  --surface-2:      #eef0ed;
  --card:           #ffffff;
  --bg-0:           #e7eae6;
  --off-white:      #f2f3f1;
  --light-bg:       #eef0ed;
  --panel:          #ffffff;
  --panel-2:        #f8f9f7;
  --card-soft:      #f8f9f7;
  --white:          #ffffff;
  /* Ink */
  --ink:            #0b0d0c;
  --ink-2:          #1b1e1c;
  --ink-3:          #383c3a;
  --mid:            #676c69;
  --muted:          #8d928f;
  --light:          #c6cbc8;
  --dim:            #b3b8b5;
  --black:          #0b0d0c;
  --text:           #0b0d0c;
  --ink-soft:       rgba(11,13,12,.66);
  --ink-faint:      rgba(11,13,12,.42);
  --ink-ghost:      rgba(11,13,12,.20);
  /* Accent: the pilot light */
  --accent:         #00a85f;
  --accent-ink:     #0a6b3c;
  --accent-bg:      #d6f3e5;
  --accent-soft:    rgba(0,168,95,.14);
  --green:          #00a85f;
  --green-bg:       #e4f6ec;
  --green-dark:     #2d6b48;
  /* State */
  --danger:         #bf3238;
  --danger-bg:      #fce6e7;
  --danger-ink:     #7d1f22;
  --warn:           #9c5d0a;
  --warn-bg:        #fcf0d8;
  --warn-ink:       #6b4306;
  --warn-line:      #ecd9ad;
  --amber:          #b5851a;
  --amber-bg:       #faf1d8;
  --red:            #bf3238;
  --red-bg:         rgba(191,50,56,.10);
  --err-bg:         #fbe9e9;
  --err-ink:        #8c1d1d;
  --err-line:       #f0c2c2;
  /* Line, edge, depth */
  --border:         #dfe3df;
  --border-light:   #e8ebe7;
  --border-ultra:   #eff1ee;
  --border-strong:  rgba(11,13,12,.18);
  --line:           #dfe3df;
  --radius:         10px;
  --radius-sm:      6px;
  /* Skeleton -- the resting and sweeping ends of a loading bar. A skeleton
     is a SHAPE, not a surface, so these sit close to the ground rather
     than on the elevation scale (js/crew-loading.js). */
  --skel:           rgba(11,13,12,.07);
  --skel-hi:        rgba(11,13,12,.13);
  --shadow-sm:      0 1px 2px rgba(11,13,12,.04);
  --shadow-md:      0 2px 8px rgba(11,13,12,.05);
  --shadow-lg:      0 12px 32px rgba(11,13,12,.08);
  /* Type */
  --font:           'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-mono:      'DM Mono', 'SF Mono', Menlo, monospace;
  --font-display:   'Archivo', 'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* Category hues (Marketing, PTO, score bands) */
  --vacation:       #2f6fd6;
  --sick:           #d9603f;
  --closed:         #b8912a;
  --within:         #4f9a3a;
  --borderline:     #c9921a;
  --outside:        #d2603f;
  --gym:            #2b7fe0;
  --dance:          #1f9f96;
  --yoga:           #8a5cf0;
  --martial:        #4f9a3a;
  --crossfit:       #d2603f;
  --hiit:           #d98a1f;
  --pilbarre:       #d84f9a;
  --rec:            #6e7478;
  --private:        #8a5cf0;
  --public:         #2b7fe0;
  --charter:        #d98a1f;
  /* Safe areas */
  --safe-top:       env(safe-area-inset-top, 0px);
  --safe-right:     env(safe-area-inset-right, 0px);
  --safe-bottom:    env(safe-area-inset-bottom, 0px);
  --safe-left:      env(safe-area-inset-left, 0px);
  color-scheme: light;
}

/* ── Dark, when the OS asks for it and nothing stamped otherwise ─────────── */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* Ground and surfaces */
    --bg:             #0a0c0b;
    --paper:          #121514;
    --surface:        #171b19;
    --surface-2:      #1d2220;
    --card:           #141817;
    --bg-0:           #050606;
    --off-white:      #0a0c0b;
    --light-bg:       #171b19;
    --panel:          #121514;
    --panel-2:        #181c1a;
    --card-soft:      #1a1f1d;
    --white:          #121514;
    /* Ink */
    --ink:            #f1f3f1;
    --ink-2:          #e1e5e2;
    --ink-3:          #c2c8c4;
    --mid:            #8f9691;
    --muted:          #6a716d;
    --light:          #3a403d;
    --dim:            #4b514e;
    --black:          #f1f3f1;
    --text:           #f1f3f1;
    --ink-soft:       rgba(241,243,241,.64);
    --ink-faint:      rgba(241,243,241,.40);
    --ink-ghost:      rgba(241,243,241,.20);
    /* Accent: the pilot light */
    --accent:         #00c26e;
    --accent-ink:     #5fd99a;
    --accent-bg:      rgba(0,194,110,.14);
    --accent-soft:    rgba(0,194,110,.14);
    --green:          #00c26e;
    --green-bg:       rgba(0,194,110,.10);
    --green-dark:     #58c48a;
    /* State */
    --danger:         #f0706d;
    --danger-bg:      rgba(240,112,109,.14);
    --danger-ink:     #ffb4b2;
    --warn:           #edb35d;
    --warn-bg:        rgba(237,179,93,.13);
    --warn-ink:       #f6d090;
    --warn-line:      rgba(237,179,93,.35);
    --amber:          #f5c46e;
    --amber-bg:       rgba(245,196,110,.10);
    --red:            #ff8a8a;
    --red-bg:         rgba(255,138,138,.12);
    --err-bg:         rgba(240,112,109,.12);
    --err-ink:        #ffb4b2;
    --err-line:       rgba(240,112,109,.35);
    /* Line, edge, depth */
    --border:         #252a28;
    --border-light:   #1f2422;
    --border-ultra:   #1a1e1c;
    --border-strong:  rgba(255,255,255,.16);
    --line:           #252a28;
    --radius:         10px;
    --radius-sm:      6px;
    --skel:           rgba(241,243,241,.07);
    --skel-hi:        rgba(241,243,241,.13);
    --shadow-sm:      inset 0 1px 0 rgba(255,255,255,.04);
    --shadow-md:      inset 0 1px 0 rgba(255,255,255,.05), 0 8px 24px rgba(0,0,0,.35);
    --shadow-lg:      inset 0 1px 0 rgba(255,255,255,.06), 0 24px 56px rgba(0,0,0,.50);
    /* Type */
    --font:           'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    --font-mono:      'DM Mono', 'SF Mono', Menlo, monospace;
    --font-display:   'Archivo', 'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    /* Category hues (Marketing, PTO, score bands) */
    --vacation:       #6ea8ff;
    --sick:           #ff8866;
    --closed:         #d4a946;
    --within:         #7bb661;
    --borderline:     #e6b04d;
    --outside:        #e07a5f;
    --gym:            #5fa8ff;
    --dance:          #4ecdc4;
    --yoga:           #b98cff;
    --martial:        #7bb661;
    --crossfit:       #e07a5f;
    --hiit:           #ffb454;
    --pilbarre:       #f078b6;
    --rec:            #9aa0a6;
    --private:        #b98cff;
    --public:         #5fa8ff;
    --charter:        #ffb454;
    /* Safe areas */
    --safe-top:       env(safe-area-inset-top, 0px);
    --safe-right:     env(safe-area-inset-right, 0px);
    --safe-bottom:    env(safe-area-inset-bottom, 0px);
    --safe-left:      env(safe-area-inset-left, 0px);
    color-scheme: dark;
  }
}

/* ── Dark, when the app stamps it (the shell toggle) -- wins over the OS ──── */
:root[data-theme="dark"] {
  /* Ground and surfaces */
  --bg:             #0a0c0b;
  --paper:          #121514;
  --surface:        #171b19;
  --surface-2:      #1d2220;
  --card:           #141817;
  --bg-0:           #050606;
  --off-white:      #0a0c0b;
  --light-bg:       #171b19;
  --panel:          #121514;
  --panel-2:        #181c1a;
  --card-soft:      #1a1f1d;
  --white:          #121514;
  /* Ink */
  --ink:            #f1f3f1;
  --ink-2:          #e1e5e2;
  --ink-3:          #c2c8c4;
  --mid:            #8f9691;
  --muted:          #6a716d;
  --light:          #3a403d;
  --dim:            #4b514e;
  --black:          #f1f3f1;
  --text:           #f1f3f1;
  --ink-soft:       rgba(241,243,241,.64);
  --ink-faint:      rgba(241,243,241,.40);
  --ink-ghost:      rgba(241,243,241,.20);
  /* Accent: the pilot light */
  --accent:         #00c26e;
  --accent-ink:     #5fd99a;
  --accent-bg:      rgba(0,194,110,.14);
  --accent-soft:    rgba(0,194,110,.14);
  --green:          #00c26e;
  --green-bg:       rgba(0,194,110,.10);
  --green-dark:     #58c48a;
  /* State */
  --danger:         #f0706d;
  --danger-bg:      rgba(240,112,109,.14);
  --danger-ink:     #ffb4b2;
  --warn:           #edb35d;
  --warn-bg:        rgba(237,179,93,.13);
  --warn-ink:       #f6d090;
  --warn-line:      rgba(237,179,93,.35);
  --amber:          #f5c46e;
  --amber-bg:       rgba(245,196,110,.10);
  --red:            #ff8a8a;
  --red-bg:         rgba(255,138,138,.12);
  --err-bg:         rgba(240,112,109,.12);
  --err-ink:        #ffb4b2;
  --err-line:       rgba(240,112,109,.35);
  /* Line, edge, depth */
  --border:         #252a28;
  --border-light:   #1f2422;
  --border-ultra:   #1a1e1c;
  --border-strong:  rgba(255,255,255,.16);
  --line:           #252a28;
  --radius:         10px;
  --radius-sm:      6px;
  --skel:           rgba(241,243,241,.07);
  --skel-hi:        rgba(241,243,241,.13);
  --shadow-sm:      inset 0 1px 0 rgba(255,255,255,.04);
  --shadow-md:      inset 0 1px 0 rgba(255,255,255,.05), 0 8px 24px rgba(0,0,0,.35);
  --shadow-lg:      inset 0 1px 0 rgba(255,255,255,.06), 0 24px 56px rgba(0,0,0,.50);
  /* Type */
  --font:           'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-mono:      'DM Mono', 'SF Mono', Menlo, monospace;
  --font-display:   'Archivo', 'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  /* Category hues (Marketing, PTO, score bands) */
  --vacation:       #6ea8ff;
  --sick:           #ff8866;
  --closed:         #d4a946;
  --within:         #7bb661;
  --borderline:     #e6b04d;
  --outside:        #e07a5f;
  --gym:            #5fa8ff;
  --dance:          #4ecdc4;
  --yoga:           #b98cff;
  --martial:        #7bb661;
  --crossfit:       #e07a5f;
  --hiit:           #ffb454;
  --pilbarre:       #f078b6;
  --rec:            #9aa0a6;
  --private:        #b98cff;
  --public:         #5fa8ff;
  --charter:        #ffb454;
  /* Safe areas */
  --safe-top:       env(safe-area-inset-top, 0px);
  --safe-right:     env(safe-area-inset-right, 0px);
  --safe-bottom:    env(safe-area-inset-bottom, 0px);
  --safe-left:      env(safe-area-inset-left, 0px);
  color-scheme: dark;
}

/* ===========================================================================
   PRINT: a page that opts in comes out on white.
   ---------------------------------------------------------------------------
   Opt in with <html data-print="light">. It is opt-in rather than universal
   because most pages here are screens, not documents, and nobody has looked
   at what they do on paper; a report that IS a document says so.

   The selectors carry data-print AND data-theme so they outrank the
   :root[data-theme="dark"] palette above, which would otherwise send a black
   page to the printer -- or, with print-color-adjust, a black page and a
   cartridge. The values are the light palette from the top of this file,
   with the mid greys darkened a step: what reads as quiet on a screen reads
   as faint on paper.
   =========================================================================== */
@media print {
  :root[data-print="light"],
  :root[data-print="light"][data-theme="dark"],
  :root[data-print="light"][data-theme="light"] {
    --bg:            #ffffff;
    --bg-0:          #ffffff;
    --paper:         #ffffff;
    --card:          #ffffff;
    --panel:         #ffffff;
    --surface:       #ffffff;
    --surface-2:     #f4f5f3;
    --off-white:     #ffffff;
    /* --white is --black's partner and they invert together (see the top of
       this file). It was missing here while --black was not, so a page that
       painted with var(--white) printed #121514 from the dark theme -- a black
       page edge the moment "Background graphics" was ticked. (intake.html,
       2026-09-21.) */
    --white:         #ffffff;
    --light-bg:      #f4f5f3;
    --ink:           #0b0d0c;
    --ink-2:         #1b1e1c;
    --ink-3:         #383c3a;
    --text:          #0b0d0c;
    --black:         #0b0d0c;
    --mid:           #4a4f4c;
    --muted:         #6a706d;
    --dim:           #8d928f;
    --light:         #c6cbc8;
    --accent:        #0a6b3c;
    --accent-ink:    #0a6b3c;
    --accent-bg:     #e8f4ed;
    --accent-soft:   #e8f4ed;
    --border:        #c9cecb;
    --border-light:  #dfe3e0;
    --danger:        #7d1f22;
    --danger-bg:     #fbeaea;
    --danger-ink:    #7d1f22;
    --warn:          #6b4306;
    --warn-bg:       #fcf0d8;
    --warn-ink:      #6b4306;
  }
}

/* ===========================================================================
   COMPONENTS -- the house parts, added 2026-09-22 (Pass 1 of
   docs/CREW-OS-UX-AUDIT-2026-09.md)
   ===========================================================================
   Until this section existed every page rolled its own header, eyebrow,
   tabs, buttons, pills, tiles, tables, fields, empty state and footer. The
   audit measured what that cost: page titles at four sizes, seven eyebrow
   variants, five in-page tab styles, four footers, eleven page widths, and
   most of the 600 hard-coded colours that break the dark theme.

   The values here are not new. They are the ones the pages that already
   meet the bar use -- Today, Shift, Patients, Re-exams due, Households --
   written once.

   SCOPED ON PURPOSE. Every rule sits under [data-ui]. A page adopts the
   layer by putting data-ui on <body> and deleting its private copies of
   these classes; until it does, nothing here reaches it, even where it
   already uses a class of the same name (.btn, .pill, .tab, .table are
   common). tests/crew-components.test.mjs holds the scope, the token-only
   rule, and -- for every adopted page -- that no private copy has crept
   back.

   docs/ui-gallery.html renders every part in both themes.

   ONE MORE RULE THE VALUES ENCODE: green is a signal. .pill--ok, .tile .up
   and the checked box are the only green things here. There is no green
   button and no green fill, and there should not be one.
   =========================================================================== */

/* ── The page ──────────────────────────────────────────────────────────── */
[data-ui] { font-family: var(--font); color: var(--ink); background: var(--bg);
  -webkit-font-smoothing: antialiased; font-variant-numeric: tabular-nums;
  /* iOS inflates text when a phone turns sideways; this keeps the sizes set here. */
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
[data-ui] .page { max-width: 1200px; margin: 0 auto; padding: 40px 32px 88px; }
[data-ui] .page--wide { max-width: 1400px; }
[data-ui] .page--narrow { max-width: 760px; }

[data-ui] .page-head { display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; flex-wrap: wrap; margin-bottom: 32px; }
[data-ui] .page-head > div { min-width: 0; }
[data-ui] .eyebrow { font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .18em; text-transform: uppercase; color: var(--muted); line-height: 1.2; }
[data-ui] .page-title { margin-top: 8px; font-family: var(--font-display); font-size: 42px;
  font-weight: 700; letter-spacing: -.025em; line-height: 1; color: var(--ink); text-wrap: balance; }
[data-ui] .page-sub { margin-top: 12px; font-size: 14px; line-height: 1.5; color: var(--mid); max-width: 60ch; }
[data-ui] .page-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ── Sections ─────────────────────────────────────────────────────────── */
[data-ui] .sec { margin-top: 40px; }
[data-ui] .sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding-bottom: 10px; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
[data-ui] .sec-eyebrow { font-family: var(--font-mono); font-size: 10.5px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase; color: var(--mid); }
[data-ui] .sec-title { font-family: var(--font-display); font-size: 20px; font-weight: 700;
  letter-spacing: -.02em; color: var(--ink); }
[data-ui] .sec-title em { font-style: italic; font-weight: 400; color: var(--mid); }
[data-ui] .sec-note { font-family: var(--font-mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
[data-ui] .hr { border: 0; border-top: 1px solid var(--border); margin: 24px 0; }

/* ── Buttons: filled (the one primary), ghost, quiet, danger ───────────── */
[data-ui] .btn { appearance: none; -webkit-appearance: none; display: inline-flex; align-items: center;
  justify-content: center; gap: 8px; padding: 10px 16px; border-radius: 9px; border: 1px solid transparent;
  font-family: var(--font); font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; line-height: 1.2;
  cursor: pointer; background: var(--ink); color: var(--paper); text-decoration: none; white-space: nowrap;
  transition: background .12s, border-color .12s, color .12s, opacity .12s; }
[data-ui] .btn:hover { background: var(--ink-2); }
[data-ui] .btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
[data-ui] .btn:disabled, [data-ui] .btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
[data-ui] .btn--ghost { background: var(--paper); color: var(--ink); border-color: var(--border); }
[data-ui] .btn--ghost:hover { background: var(--paper); border-color: var(--border-strong); }
[data-ui] .btn--quiet { background: transparent; color: var(--mid); border-color: transparent; padding-left: 6px; padding-right: 6px; }
[data-ui] .btn--quiet:hover { background: transparent; color: var(--ink); }
[data-ui] .btn--danger { background: var(--danger); color: var(--paper); }
[data-ui] .btn--danger:hover { background: var(--danger); opacity: .9; }
[data-ui] .btn--sm { padding: 6px 11px; font-size: 12px; border-radius: 7px; }

/* ── Pills: a state, in mono caps ─────────────────────────────────────── */
[data-ui] .pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 9px; border-radius: 999px;
  font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  line-height: 1.5; white-space: nowrap; background: var(--surface-2); color: var(--mid); border: 1px solid transparent; }
[data-ui] .pill--ok   { background: var(--accent-bg); color: var(--accent-ink); }
[data-ui] .pill--warn { background: var(--warn-bg);   color: var(--warn-ink); }
[data-ui] .pill--bad  { background: var(--danger-bg); color: var(--danger-ink); }
[data-ui] .pill--ink  { background: var(--ink); color: var(--paper); }
[data-ui] .pill--line { background: transparent; border-color: var(--border); color: var(--mid); }
[data-ui] .pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

/* ── Tiles: a label, a number, a sentence ─────────────────────────────── */
[data-ui] .tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; }
[data-ui] .tile { padding: 18px 20px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--paper); min-width: 0; }
[data-ui] .tile--accent { border-color: var(--accent); }
[data-ui] .tile--warn { border-color: var(--warn); }
[data-ui] .tile-l { font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); }
[data-ui] .tile-v { margin-top: 8px; font-family: var(--font-display); font-size: 30px; font-weight: 700;
  letter-spacing: -.025em; line-height: 1; color: var(--ink); }
[data-ui] .tile-v small { font-size: 14px; font-weight: 500; color: var(--mid); letter-spacing: 0; margin-left: 4px; }
[data-ui] .tile-s { margin-top: 8px; font-size: 12px; line-height: 1.45; color: var(--mid); }
[data-ui] .tile .up  { color: var(--accent-ink); font-weight: 600; }
[data-ui] .tile .dn  { color: var(--warn-ink);   font-weight: 600; }
[data-ui] .tile .bad { color: var(--danger-ink); font-weight: 600; }

/* ── In-page tabs: mono caps on a hairline (the Growth / Plan room style) ─ */
[data-ui] .tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; }
[data-ui] .tabs::-webkit-scrollbar { display: none; }
[data-ui] .tab { appearance: none; -webkit-appearance: none; background: none; border: 0; border-bottom: 2px solid transparent;
  margin-bottom: -1px; padding: 12px 0 11px; font-family: var(--font-mono); font-size: 11px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: var(--muted); cursor: pointer; white-space: nowrap;
  text-decoration: none; display: inline-flex; gap: 8px; align-items: center; }
[data-ui] .tab:hover { color: var(--ink); }
[data-ui] .tab[aria-selected="true"], [data-ui] .tab.is-on { color: var(--ink); border-bottom-color: var(--ink); }
[data-ui] .tab .n { letter-spacing: 0; color: var(--mid); }

/* ── Segmented switch: one of a few (Re-exams due's TODAY / ALL) ───────── */
[data-ui] .seg { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; padding: 3px; background: var(--paper); }
[data-ui] .seg > button, [data-ui] .seg > a { appearance: none; -webkit-appearance: none; border: 0; background: transparent;
  cursor: pointer; font-family: var(--font-mono); font-size: 11px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--mid); padding: 7px 16px; border-radius: 999px; line-height: 1.2; text-decoration: none; }
[data-ui] .seg > button:hover, [data-ui] .seg > a:hover { color: var(--ink); }
[data-ui] .seg > [aria-pressed="true"], [data-ui] .seg > .is-on { background: var(--ink); color: var(--paper); }

/* ── Check: a pill with a box in it (Re-exams due's service filter) ────── */
[data-ui] .check { display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border: 1px solid var(--border);
  border-radius: 999px; background: var(--paper); font-size: 12.5px; font-weight: 600; color: var(--ink-2); cursor: pointer;
  -webkit-user-select: none; user-select: none; }
[data-ui] .check:hover { border-color: var(--border-strong); }
[data-ui] .check input { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; margin: 0; position: relative;
  border: 1.5px solid var(--mid); border-radius: 4px; background: transparent; cursor: pointer; flex: none;
  transition: background .12s, border-color .12s; }
[data-ui] .check input:checked { background: var(--accent); border-color: var(--accent); }
[data-ui] .check input:checked::after { content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px;
  border: solid var(--paper); border-width: 0 2px 2px 0; transform: rotate(45deg); }
[data-ui] .check.is-off { opacity: .55; }

/* ── Tables ───────────────────────────────────────────────────────────── */
[data-ui] .table-wrap { border: 1px solid var(--border); border-radius: var(--radius); background: var(--paper); overflow: auto; }
[data-ui] .table { width: 100%; border-collapse: collapse; font-size: 13px; }
[data-ui] .table th { font-family: var(--font-mono); font-size: 10px; font-weight: 500; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); text-align: left; padding: 10px 14px;
  border-bottom: 1px solid var(--border); background: var(--surface); white-space: nowrap; }
[data-ui] .table td { padding: 11px 14px; border-bottom: 1px solid var(--border-light); color: var(--ink); vertical-align: middle; }
[data-ui] .table tr:last-child td { border-bottom: 0; }
[data-ui] .table tbody tr:hover td { background: var(--surface); }
[data-ui] .table .num { text-align: right; }
[data-ui] .table .muted { color: var(--mid); }

/* ── Fields ───────────────────────────────────────────────────────────── */
[data-ui] .field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
[data-ui] .label, [data-ui] .field > label { font-family: var(--font-mono); font-size: 10px; font-weight: 500;
  letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
[data-ui] .input, [data-ui] .field > input, [data-ui] .field > select, [data-ui] .field > textarea,
[data-ui] .select > select { appearance: none; -webkit-appearance: none; width: 100%; font-family: var(--font);
  font-size: 13.5px; color: var(--ink); background: var(--paper); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 12px; line-height: 1.3; outline: 0; transition: border-color .12s; }
[data-ui] .input:focus, [data-ui] .field > input:focus, [data-ui] .field > select:focus,
[data-ui] .field > textarea:focus, [data-ui] .select > select:focus { border-color: var(--ink); }
[data-ui] .input::placeholder, [data-ui] .field > input::placeholder, [data-ui] .field > textarea::placeholder { color: var(--muted); }
[data-ui] .field > textarea { min-height: 88px; resize: vertical; }
/* A date is a value, so it is set in mono like every other value. */
[data-ui] .field > input[type="date"], [data-ui] .field > input[type="time"] { font-family: var(--font-mono);
  font-size: 12.5px; letter-spacing: .02em; }
/* A select with a drawn chevron: no image, so it follows the theme. */
[data-ui] .select { position: relative; }
[data-ui] .select > select { padding-right: 34px; cursor: pointer; }
[data-ui] .select::after { content: ""; position: absolute; right: 13px; top: 50%; width: 7px; height: 7px;
  border: solid var(--mid); border-width: 0 1.5px 1.5px 0; transform: translateY(-70%) rotate(45deg); pointer-events: none; }
[data-ui] .row { display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; }

/* ── Empty, and told ──────────────────────────────────────────────────── */
[data-ui] .empty { padding: 22px 0; font-size: 14px; line-height: 1.5; color: var(--mid); }
[data-ui] .empty b { color: var(--ink); font-weight: 600; }

/* ── Notices: something the page has to say (an error is one of them) ─── */
[data-ui] .notice { padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
[data-ui] .notice b { font-weight: 600; color: var(--ink); }
[data-ui] .notice--ok   { border-color: var(--accent);    background: var(--accent-bg); color: var(--accent-ink); }
[data-ui] .notice--warn { border-color: var(--warn-line); background: var(--warn-bg);   color: var(--warn-ink); }
[data-ui] .notice--bad  { border-color: var(--danger);    background: var(--danger-bg); color: var(--danger-ink); }
[data-ui] .notice--ok b, [data-ui] .notice--warn b, [data-ui] .notice--bad b { color: inherit; }
[data-ui] .notice .btn { margin-top: 10px; }

/* ── Footer: one quiet maker's mark, or none ──────────────────────────── */
[data-ui] .foot { margin-top: 56px; padding-top: 16px; border-top: 1px solid var(--border-light); display: flex;
  justify-content: space-between; gap: 16px; flex-wrap: wrap; font-family: var(--font-mono); font-size: 9.5px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
[data-ui] .foot .mark { color: var(--muted); }
[data-ui] .foot .mark b { color: var(--accent); font-weight: 500; }

/* ── Dialog: what js/crew-dialog.js draws in place of alert / confirm ──── */
[data-ui].dlg-backdrop, [data-ui] .dlg-backdrop { position: fixed; inset: 0; z-index: 1000; display: flex;
  align-items: center; justify-content: center; padding: 20px;
  background: color-mix(in srgb, var(--bg-0) 72%, transparent); }
[data-ui] .dlg { width: min(440px, 100%); background: var(--paper); border: 1px solid var(--border); border-radius: 14px;
  padding: 22px 22px 18px; box-shadow: var(--shadow-lg); }
[data-ui] .dlg-title { font-family: var(--font-display); font-size: 18px; font-weight: 700; letter-spacing: -.02em; color: var(--ink); }
[data-ui] .dlg-body { margin-top: 8px; font-size: 13.5px; line-height: 1.5; color: var(--mid); }
[data-ui] .dlg-body .input { margin-top: 12px; }
[data-ui] .dlg-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }

/* ── Info: an "i" beside a label, and the note it opens (js/crew-info.js) ─
   Ben, 2026-09-23: explanations live behind an "i" where the reader needs
   them, not in a block at the foot of the page. The note is one shared box
   on <body>, placed by the script beside the "i"; on a phone it is a sheet
   along the bottom (below). It never prints. The "i" is a mark in running
   text, so it does not grow to 44 px the way a button does: under a finger
   its BUTTON is 44 px and the mark stays small inside it (see pointer:
   coarse). text-transform is reset because it sits in uppercase labels and
   table heads, and an "I" reads as a letter, not a sign. */
[data-ui] .info { display: inline-flex; align-items: center; justify-content: center; position: relative;
  width: 17px; height: 17px; margin: 0 0 0 6px; padding: 0; vertical-align: -3px; flex: none;
  border: 1px solid var(--border-strong); border-radius: 50%; background: transparent; color: var(--muted);
  font: 700 10.5px/1 var(--font-display); letter-spacing: 0; text-transform: none; cursor: pointer; }
[data-ui] .info:hover, [data-ui] .info[aria-expanded="true"] { color: var(--ink); border-color: var(--ink); }
[data-ui] .info:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
[data-ui] .info-pop { position: fixed; z-index: 900; box-sizing: border-box; width: max-content;
  max-width: min(360px, calc(100vw - 32px)); max-height: calc(100vh - 32px); overflow-y: auto;
  padding: 14px 16px; background: var(--paper); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-lg); font: 400 13px/1.55 var(--font); letter-spacing: normal; text-transform: none;
  text-align: left; white-space: normal; color: var(--mid); }
[data-ui] .info-pop[hidden] { display: none; }
[data-ui] .info-pop:focus { outline: none; }
[data-ui] .info-pop .info-t { margin: 0 0 6px; font-family: var(--font-display); font-size: 14px; font-weight: 700;
  letter-spacing: -.01em; color: var(--ink); }
[data-ui] .info-pop p { margin: 0; }
[data-ui] .info-pop p + p { margin-top: 8px; }
[data-ui] .info-pop b, [data-ui] .info-pop strong { color: var(--ink); font-weight: 600; }
@media print {
  [data-ui] .info, [data-ui] .info-pop { display: none; }
}

/* ── Small screens ────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  [data-ui] .page { padding: 24px 16px 64px; }
  [data-ui] .page-title { font-size: 32px; }
  [data-ui] .page-head { margin-bottom: 24px; }
  [data-ui] .tiles { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}

/* ── On a phone, and under a finger ───────────────────────────────────────
   Measured on 2026-09-22 (pass1 mobile audit): on an iPhone 1095 of 1363
   tappable controls were under Apple's 44 pt minimum, 142 fields were small
   enough that iOS Safari zoomed the page when one was tapped, and mono
   captions ran at 9.5-10.5 px. Everything below sits inside a query a
   desktop with a mouse never matches, so the desktop render is untouched
   (tests/crew-components.test.mjs holds that, and each rule).

   Under a finger (pointer: coarse -- phones and iPads, whatever the width)
   every control in the layer is at least 44 px tall. The controls grow in
   place rather than hiding a larger hit area in a pseudo-element: what the
   finger can hit is what the eye sees. A field counts too: at 16 px it is
   43 px tall, so it takes the same floor. A 44 px min-width replaces a flex
   item's own floor (its label's width), so a button or tab in a row too
   long for the screen would squeeze to 44 px and spill its label over the
   next; flex-shrink: 0 keeps every one at its label's width and the row
   scrolls, as it does with a mouse. The segmented switch is a flex item in
   the same rows: squeezed, its segments wrap onto two lines instead of
   overlapping -- the quieter half of the same failure -- so it takes the
   same floor. */
@media (pointer: coarse) {
  [data-ui] .btn { min-height: 44px; min-width: 44px; flex-shrink: 0; }
  [data-ui] .tab { min-height: 44px; min-width: 44px; flex-shrink: 0; }
  [data-ui] .seg { flex-shrink: 0; }
  [data-ui] .seg > button, [data-ui] .seg > a { min-height: 44px; display: inline-flex; align-items: center;
    justify-content: center; white-space: nowrap; }
  [data-ui] .check { min-height: 44px; }
  /* The "i": the button is 44 px, the mark stays 17 px inside it, and the
     margins give the extra back so a label's line does not grow. */
  [data-ui] .info { width: 44px; height: 44px; margin: -13px -13px -13px -8px; border: 0; }
  [data-ui] .info::before { content: ""; position: absolute; top: 13px; left: 13px; width: 17px; height: 17px;
    box-sizing: border-box; border: 1px solid var(--border-strong); border-radius: 50%; }
  [data-ui] .info[aria-expanded="true"]::before { border-color: var(--ink); }
  [data-ui] .input, [data-ui] .field > input, [data-ui] .field > select, [data-ui] .select > select { min-height: 44px; }
  /* A press dims the part as well. iOS's own tap flash stays: Safari applies
     :active only when a touch listener is present, so the flash is the one
     answer a finger always gets. A part that is off or disabled keeps its
     own dimming, and a press never lifts it. */
  [data-ui] .btn:active:not(:disabled):not([aria-disabled="true"]), [data-ui] .tab:active,
  [data-ui] .seg > button:active:not(:disabled), [data-ui] .seg > a:active,
  [data-ui] .check:not(.is-off):active { opacity: .7; }
}

/* A phone. Fields are 16 px, the size under which iOS Safari zooms the whole
   page when one is focused, and they size with their border so a full-width
   field stays inside the gutter. Mono captions step up to 11 px, the
   smallest a phone reads at arm's length.

   The gutter is the page's padding and nothing else. The browser's own
   default margin on <body> is 8 px, so a page that leaves it alone sits 24
   px from the screen -- 48 of a 375 px phone -- and pushes the safe-area
   maths out by the same 8 (a notched phone in landscape got 52). Zeroing it
   here, inside the phone query, buys the true 16 px without moving the
   desktop render by a pixel. It is scoped to [data-ui], which a page puts
   on <body>; the shell's bar goes full-bleed at this width, where it is
   being replaced by a phone menu in the same pass. */
@media (max-width: 720px) {
  [data-ui] { margin: 0; }
  [data-ui] .page { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
  [data-ui] .input, [data-ui] .field > input, [data-ui] .field > select, [data-ui] .field > textarea,
  [data-ui] .select > select { font-size: 16px; box-sizing: border-box; max-width: 100%; }
  [data-ui] .field > input[type="date"], [data-ui] .field > input[type="time"] { font-size: 16px; }
  [data-ui] .table-wrap { max-width: 100%; min-width: 0; overflow-x: auto; overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch; }
  [data-ui] .tile-l, [data-ui] .pill, [data-ui] .label, [data-ui] .field > label, [data-ui] .table th,
  [data-ui] .sec-eyebrow, [data-ui] .sec-note, [data-ui] .foot { font-size: 11px; }
  /* The dialog: 16 px from each edge, clear of the home indicator. */
  [data-ui].dlg-backdrop, [data-ui] .dlg-backdrop { padding: 16px 0 max(16px, env(safe-area-inset-bottom)); }
  [data-ui] .dlg { box-sizing: border-box; width: calc(100% - 32px); max-width: 440px; max-height: 100%; overflow-y: auto; }
  /* The info note: a sheet along the bottom, clear of the home indicator. */
  [data-ui] .info-pop { left: max(16px, env(safe-area-inset-left)); right: max(16px, env(safe-area-inset-right));
    top: auto; bottom: max(16px, env(safe-area-inset-bottom)); width: auto; max-width: none; max-height: 60vh;
    font-size: 14px; }
}
/* A narrow phone: the dialog's answers stack, full width, the primary on top. */
@media (max-width: 400px) {
  [data-ui] .dlg-actions { flex-direction: column-reverse; align-items: stretch; }
  [data-ui] .dlg-actions .btn { width: 100%; }
}
