/* ============================================================================
   shell-tokens.css — CheckIt  (task #892)
   The bridge between CheckIt's OWN palette and the floating-pane shell.

   WHY THIS FILE EXISTS
   The shell standard (Shaun, 2026-08-27) is "unbroken outer chrome + rounded
   floating panes". CheckIt already has its own token set split across
   theme.css (structure) and theme-cyan.css (colour), and the names line up
   with the shell's almost exactly — --bg, --surface, --surface-2/3, --ink,
   --ink-soft, --ink-faint, --line, --line-soft, --accent, --accent-2,
   --accent-soft, --accent-ink, --ok/--warn/--danger, --sp-*, --r-*,
   --shadow / --shadow-sm / --shadow-lg. So there is almost nothing to alias.
   (#1217: never write a star followed by a slash inside this comment. The
   shadow list above used to be written as a wildcard name with a slash after
   it, which closed the comment early, leaked the rest as a selector, and
   silently dropped the whole base :root block below.)

   What the shell needs that CheckIt did NOT have is the CHROME layer: --frame,
   --frame-2, --pane, the soft scrim, the shell dimensions, motion and z-index.
   Every colour here is DERIVED from CheckIt's --bg / --surface / --accent with
   color-mix — nothing is hardcoded, so the cyan-700 skin (and its dark flip)
   carries straight through to the frame. Change theme-cyan.css and the chrome
   follows, in both themes. That is the whole point: CheckIt keeps looking like
   CheckIt.

   ⚠️ CheckIt is MOBILE-FIRST and used one-handed outdoors, so the three
   departures theme.css already documents are preserved here, NOT overwritten
   by the shell's desk-sized numbers:
     • --ctl-h / --row-h stay at 44px even on desktop. LinkIt drops its
       controls to 34px at 1024+; that is a desk size and this app gets used
       with gloves on. The shell's own chrome (title bar, status bar) shrinks
       on desktop; the CONTROLS do not.
     • --tap stays 44px everywhere.
     • rail items are 44px, never the 40px LinkIt uses when expanded.

   Load order (index.html):
     reset.css -> theme.css -> theme-cyan.css -> shell-tokens.css
     -> app.css -> shell.css
   app.css keeps every component rule; shell.css loads LAST so the frame
   selectors win. Removing the two new <link> tags reverts the whole retrofit.

   ⚠️ NEW FILE — must be in the SHELL array in service-worker.js or it 404s
   offline. `npm run check:shell` now checks CSS too and will say so.
   ========================================================================= */

:root {
  /* ── Font aliases — the shell says --font, CheckIt says --font-ui ─────── */
  --font: var(--font-ui);
  /* CheckIt has no mono token of its own; the status bar's numbers want one. */
  --font-num: ui-monospace, SFMono-Regular, "Cascadia Mono", Consolas, monospace;

  /* ── Chrome surfaces ──────────────────────────────────────────────────
     DERIVED from CheckIt's --bg, never hardcoded. --frame is one step darker
     than --bg so the pane (which is --surface, i.e. white in light) reads as
     floating ON the chrome. CheckIt light --bg is #f3f9fb, so --frame lands
     ~#e4e9eb — a barely-cyan grey that belongs to this palette, not a
     borrowed one. */
  --frame:      color-mix(in srgb, var(--bg) 94%, #000);  /* title bar, status bar, bottom nav */
  --frame-2:    color-mix(in srgb, var(--bg) 91%, #000);  /* recessed: the rail */
  --pane:       var(--surface);                            /* alias — zero new colour */
  /* CheckIt already ships --scrim in theme-cyan.css (both themes). Only the
     SOFT one is new — it is the rail overlay's backdrop, deliberately lighter
     than a modal's. Tinted toward CheckIt's deep slate-teal ink. */
  --scrim-soft: rgba(13, 36, 48, .26);

  /* ── Derived state colours ───────────────────────────────────────────── */
  --pane-ring:  color-mix(in srgb, var(--accent) 52%, transparent);
  --focus-ring: color-mix(in srgb, var(--accent) 22%, transparent);

  /* ── Shell dimensions (mobile base — overridden per breakpoint below) ──
     Mobile is FLAT: gutter 0, radius 0. The floating pane is the tablet and
     desktop enhancement, exactly as the standard says — gutters and radii
     waste scarce width on a phone, and this app's phone layout is the real
     layout. */
  --gutter:      0px;    /* workspace padding AND grid gap — one value, both jobs */
  --pane-radius: 0px;
  --titlebar-h:  56px;   /* = CheckIt's --header-height; the phone bar does not shrink */
  --statusbar-h: 0px;    /* hidden on phones */
  --bottomnav-h: 56px;   /* phones only; = CheckIt's --tabbar-height */
  --rail-w:      0px;    /* rail is tablet/desktop only */
  --tap:         44px;   /* minimum touch target, EVERYWHERE — see the header note */

  /* ── Motion ──────────────────────────────────────────────────────────── */
  --dur-1:  90ms;  --dur-2: 140ms;  --dur-3: 200ms;  --dur-4: 260ms;
  --ease-out: cubic-bezier(.2,0,0,1);
  --ease-in:  cubic-bezier(.4,0,1,1);

  /* ── Layers ───────────────────────────────────────────────────────────
     ⚠️ These sit UNDER app.css's existing numbers on purpose. app.css already
     uses 200 for .modal-overlay/.sheet-overlay and 300 for .toast-stack, and
     those are load-bearing (§9 — one positioning rule for every dialog). The
     shell's chrome must stay below them, so nothing here goes near 200. */
  --z-pane:     1;
  --z-sticky:  10;
  --z-rail:    20;
  --z-chrome:  40;   /* title bar, status bar, bottom nav — matches app.css's old header z */
  --z-drawer:  46;
  --z-scrim:   45;
  --z-popover: 60;   /* rail tooltips — above the chrome, below every dialog */
}

/* Dark. CheckIt declares dark TWICE (an OS-preference block and an explicit
   [data-theme="dark"] block) so the in-app toggle can beat the OS. The chrome
   has to follow both or a dark user gets a light frame behind dark panes.
   Different percentages from light on purpose: near black (#0b1418) there is
   far less room BELOW --bg, so 94%/91% would be an invisible step. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --frame:      color-mix(in srgb, var(--bg) 66%, #000);
    --frame-2:    color-mix(in srgb, var(--bg) 38%, #000);
    --scrim-soft: rgba(2, 10, 14, .42);
    --pane-ring:  color-mix(in srgb, var(--accent) 60%, transparent);
  }
}
:root[data-theme="dark"] {
  --frame:      color-mix(in srgb, var(--bg) 66%, #000);
  --frame-2:    color-mix(in srgb, var(--bg) 38%, #000);
  --scrim-soft: rgba(2, 10, 14, .42);
  --pane-ring:  color-mix(in srgb, var(--accent) 60%, transparent);
}

/* ── Breakpoint token overrides ───────────────────────────────────────────
   640 / 1024, NOT app.css's old 1200. That is the entire point of #892: a
   1200px breakpoint means a 768px or 1024px iPad fell through to the phone
   layout and got phone chrome. 640 is where a tablet starts. */

@media (min-width: 640px) {              /* TABLET — rail + status bar appear */
  :root {
    --gutter: 6px;  --pane-radius: var(--r-sm);   /* CheckIt's 6px */
    --titlebar-h: 52px; --statusbar-h: 26px; --bottomnav-h: 0px;
  }
  /* No-JS / pre-boot-failed fallback ONLY. Without <html data-rail> the rail
     would sit in a 0px track and vanish at 640+. Every state that DOES carry
     the attribute is handled below, so this can never match alongside them. */
  html:not([data-rail]) { --rail-w: 52px; }
}
@media (min-width: 1024px) {             /* DESKTOP — the full floating shell */
  :root {
    --gutter: 8px;  --pane-radius: var(--r-md);   /* CheckIt's 9px */
    --titlebar-h: 52px; --statusbar-h: 28px;
  }
}

/* ── Rail width — JS-owned state, NOT a media query ──────────────────────
   `data-rail` is stamped on <html> before first paint by the pre-boot script
   in index.html, and thereafter by wireRail() in js/app.js:

       off | condensed | overlay | expanded

   Width must NOT come from @media: the toggle has to be able to say
   "condensed at 1440px", and a media query would fight it on every resize.
   These win anywhere in the file — html[data-rail="…"] is (0,1,1) against
   :root's (0,1,0) — but they sit after the breakpoints for readability.

   52px condensed, not LinkIt's 48: a 44px tap target plus 4px of breathing
   room each side is CheckIt's floor (theme.css note 2), and the rail is a
   control you hit with a thumb.

   184px expanded is measured against CheckIt's own labels: the longest is
   "Checklists" at ~75px at 13px/600. 184 − 16 padding − 62 row chrome = 106px
   of label space. Don't drop below 168 without re-measuring.

   overlay keeps the 52px TRACK on purpose: the labelled rail floats OVER the
   pane, so the pane does not reflow when it opens. That is the whole point. */
html[data-rail="off"]       { --rail-w: 0px;   }
html[data-rail="condensed"] { --rail-w: 52px;  }
html[data-rail="overlay"]   { --rail-w: 52px;  }
html[data-rail="expanded"]  { --rail-w: 184px; }

/* Reduced motion — set the TOKENS as well, so any JS reading --dur-* agrees.
   theme.css already carries the blanket *{transition:none!important}. */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-1: 1ms; --dur-2: 1ms; --dur-3: 1ms; --dur-4: 1ms; }
}
