/* Design tokens (Living Blueprint): the ONE place colours, type, spacing, radii, elevation, focus, motion and layers are defined
   (Review/2026-10-03/ui-deep-dive/BRIEF.md 2.1-2.9). Every page links this file first; page files and the other stylesheets only
   use var(--…), never their own token blocks or var(--x,#hex) fallbacks (tests/test_design_tokens.py).
   Dark is the default (:root). Light lives on body.light (the product's theme class; html.light on the Terms page).
   Raw values are written once per theme. Tokens built from other tokens (aliases, materials) are declared on :root AND body,
   so each one is worked out again where the theme class sits (a custom property is resolved where it is declared).
   Two palettes live here for now: the page palette every page uses today (--bg, --panel, --panel2, --dim, --hov, --okbg, …;
   kept at today's rendered values, so no page changes look) and the Living Blueprint layers from the brief (--canvas,
   --surface-1/2/3, --hover, --text-faint, …) that the redesigned screens use. Pages move to the new names as they are redesigned. */
:root {
  /* ---- page palette (today's rendered values; light ones below) ---- */
  --bg:#1d2d3d; --panel:#1d2d3d; --panel2:#26394c; --text:#e8eef5; --dim:#a2b4c5;
  --green:#85c5a1; --red:#d98d80; --amber:#d6b26a; --blue:#94bce3; --onblue:#16222e; --oms:#c3a9ee;
  --line:rgba(232,238,245,.2); --hov:#2c455d; --grid:rgba(232,238,245,.05);
  --okbg:#22392e; --warnbg:#3b3320; --badbg:#422729; --accbg:#2c455d;
  --wms-task:#e5484d;                          /* the red task dot: its own signal red, stronger than --red text */
  /* ---- contrast fixes (brief 0, 2.3) ---- */
  --line-field:rgba(232,238,245,.42);          /* field, select and control borders: 3.1:1 on --panel2 (WCAG 1.4.11) */
  --text-faint:#97abbf;                        /* placeholders, disabled labels: 5.0:1 on --panel2 */
  --danger-fill:#a84e43; --on-danger:#ffffff;  /* filled destructive keys: 5.5:1 (Undo receipt was 2.6:1) */
  /* ---- Living Blueprint layers (brief 2.3) ---- */
  --canvas:#172533; --surface-1:#1d2d3d; --surface-2:#26394c; --surface-3:#2c455d; --hover:#243647; --rail-bg:#182634;
  --hair:rgba(232,238,245,.1); --blue-hi:#a8c9ea; --steel:#7f94a9;
  /* blueprint drawing: the sign-in floor under the drawing, the light behind the card, the ink (an r,g,b triplet so each use
     picks its own alpha) and the key's hover sheen */
  --floor:#142231; --glow:rgba(36,56,77,.55); --ink-rgb:148,188,227; --sheen:rgba(255,255,255,.75);
  /* the floor under every signed-in page (static/blueprint-plan.svg, one view per area): the plan's and the frame's ink alpha. Kept
     low enough that every text colour stays at 4.5:1 or more where a line runs under it (tests/test_floor_plan.py) */
  --floor-art:.07; --floor-rule:.08;
  --floor-show:.3;   /* the plan where no text can sit on it (Today's overview hero window) */
  /* registration cross (the "+" on card corners) */
  --plus:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='11'><path d='M5.5 0v11M0 5.5h11' stroke='%238da0b4' stroke-width='1'/></svg>");
  /* ---- Wholesale page's accent: its sun-yellow "Just in" / "New" / best-seller tags on the navy ink (the page itself is on WMS surfaces) ---- */
  --ws-navy:#17283a; --ws-sun:#f9e482;

  /* ---- type (brief 2.1). CJK falls back after Barlow. ---- */
  --fh:"Barlow Condensed","Arial Narrow","PingFang SC","Noto Sans SC",sans-serif;
  --fb:Barlow,"Segoe UI","PingFang SC","Noto Sans SC",system-ui,sans-serif;
  --mono:ui-monospace,Consolas,monospace;
  --fs-display:56px; --fs-hero:40px; --fs-num-l:36px; --fs-h1:24px; --fs-num-m:24px; --fs-h2:20px; --fs-h3:16px;
  --fs-body-l:16px; --fs-body:14px; --fs-small:13px; --fs-caption:12px; --fs-mono:13px;   /* 12 px is the floor */
  --track-caption:.12em;  /* 12 px uppercase captions, field labels, table headers */
  --track-kicker:.18em;   /* <=10.5px uppercase kickers */
  --track-caps-xs:.14em;  /* 11-11.5px uppercase labels */
  --track-caps-sm:.1em;   /* 12-13.5px uppercase labels, buttons in caps */
  --track-head-sm:.045em; /* 15-19px condensed headings */
  --track-head-md:.035em; /* 20-26px condensed headings */
  --track-head-lg:.02em;  /* 28-40px condensed headings */
  --track-display:.01em;  /* >=44px condensed numerals/display */
  --lh-display:1; --lh-head:1.1; --lh-body:1.5;

  /* ---- spacing and layout (brief 2.2): a 4-based scale, the 44 px grid unit ---- */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px; --sp-8:32px; --sp-grid:44px; --sp-16:64px;
  --gutter:24px; --header-h:64px; --touch:44px; --touch-primary:48px;
  --btn-h:40px; --btn-h-compact:36px; --field-h:40px;
  --dialog-s:440px; --dialog-m:560px; --dialog-l:960px;
  --dialog-xl:1280px;                           /* item windows only (a table or a line editor; owner 2026-10-05: "If you need more space
                                                   you can expand more left and right"), still inside the gutters (inventory.css) */
  --dialog-item-col:min(18rem,20vw);            /* the item (photo and name) in an item window's table: a long name on two lines, not
                                                   three, on a large screen; never more than a fifth of the screen (inventory.css) */
  --tabbar-h:64px;                              /* phones: the bottom tab bar that replaces the rail (navigation.css) */
  /* the screen's safe area: every app page sets viewport-fit=cover, so on an iPhone the page runs under the notch (turned) and the
     home indicator; these are 0 on every other screen. Backgrounds run under them; text, keys, the rail and fixed bars keep clear. */
  --safe-left:env(safe-area-inset-left,0px); --safe-right:env(safe-area-inset-right,0px); --safe-bottom:env(safe-area-inset-bottom,0px);
  --safe-width:calc(100vw - var(--safe-left) - var(--safe-right));   /* the screen's width clear of the notch sides: what a centred window
                                                   may use, less its margins */
  --thumb-row:40px;                             /* an item's photo square in a searchable item field's list row (inventory.css) */
  --pick-list-h:360px;                          /* a searchable item field's list (WMS.itemPicker, wms-ui.js) at most this tall, less
                                                   when the screen has less room above or below the field */
  --pick-list-w:320px;                          /* that list never narrower than this (a narrow table cell still shows whole names), never
                                                   wider than the screen less the gutters */

  /* ---- radii (brief 2.4): square, except tooltips, dots and the sidebar switch ---- */
  --r-0:0; --r-tip:6px; --r-switch:10px; --r-dot:50%;

  /* ---- focus (brief 2.6) ---- */
  --focus-w:2px; --focus-offset:2px;

  /* ---- motion (brief 2.7) ---- */
  --ease-out:cubic-bezier(.23,1,.32,1);        /* enter / exit / press */
  --ease-in-out:cubic-bezier(.77,0,.175,1);    /* on-screen morphs, theme cross-fade */
  --ease-drawer:cubic-bezier(.32,.72,0,1);     /* sheets / side panels */
  --dur-press:100ms; --dur-fast:120ms; --dur-out:150ms; --dur-base:200ms; --dur-step:240ms; --dur-slow:280ms;
  --dur-count:300ms; --dur-draw:600ms; --dur-highlight:1200ms;
  --dur-plot:1.2s;                              /* Today's overview and empty states: the floor view draws on once (brief 2.8.2: 1.2 s at most) */
  --toast-life:5s;                              /* a toast stays this long; errors stay until dismissed */
  --saved-life:2s;                              /* a "Saved ✓" beside what was saved: shown this long, fading at the end (brief 2.11 Settings) */
  --focus-watch:10s;                            /* after a confirm, how long its answer may take to redraw the key that opened it (wms-ui.js) */
  --scan-pull:3s;                               /* Scan Station: a finished box shows ✓ PULL on the wall this long, then it is free */
  --dur-shake:90ms;                             /* one half of the 6 px field shake (2 cycles = 180 ms, brief 2.7 tier C) */
  --dur-busy:1.2s;                              /* one sweep of a busy key's 2 px bar */
  --skel-delay:300ms;                           /* skeletons show only when loading takes longer than this */
  /* the sign-in sheet drafting the card once (brief 3.1): the top rule, then the construction lines (horizontal, vertical) */
  --dur-rule:400ms; --dur-lines:800ms; --lines-at:200ms; --lines-at-v:300ms;
  /* animated backgrounds (brief 2.8.1): hold after this long without input; a still frame after 3 frames this slow */
  --ambient-idle:120s; --ambient-slow-frame:50ms; --ambient-start:3s; --ambient-survey:14s; --ambient-drift:60s;
  --ambient-breathe:10s;                        /* the major grid's slow breathing */
  /* the sheet's marks and lanes fade in after the drawing (brief 2.8.1) */
  --dur-sheet-fade:.8s; --dur-sheet-lane:.9s; --sheet-marks-at:.9s; --sheet-lane-at:2.2s; --sheet-chev-at:2.4s;
  /* a weak PC gets the still frame and no intro (brief 2.8.1): this many cores or GB of memory, or fewer */
  --still-cores:2; --still-memory:2;
  /* the sign-in sheet's drawing (static/parts/blueprint-floor.html, scripts/build_blueprint.py): its viewBox, covering the window
     (slice), and the inner frame line, so the card's construction lines stop at the frame */
  --sheet-w:1440; --sheet-h:900; --sheet-inner:40;
  /* this station's place on the floor plan (static/blueprint-plan.svg: the centre of its #packing view, as a share of the sheet) */
  --plan-here-x:55.52%; --plan-here-y:80.43%;

  /* ---- layers ---- */
  --z-raised:1; --z-sticky:30; --z-nav-backdrop:39; --z-nav:40; --z-intro:1000; --z-toast:1100;
  --z-pop:50;                                   /* an open item field's list: over sticky chrome and its window's footer, under toasts */

  --wms-sticky-top:0px;                         /* height of sticky page chrome (navigation.css sets it per page) */
  --wms-dock:0px;                               /* height of fixed chrome at the bottom: the phone tab bar (navigation.css); bottom bars sit above it */
  --wms-dock-clear:max(0px,var(--safe-bottom) - var(--wms-dock));   /* the home indicator's strip the dock does not already cover: what a bar
                                                   on the dock adds below its keys (no tab bar: the whole strip) */
  color-scheme:dark;
}
/* the narrow gutter wherever the rail lies over the page (760 px or less), so full-bleed strips bleed by the page's own padding */
@media (max-width:760px) { :root { --gutter:16px; } }
@media (max-width:600px) { :root { --header-h:56px; } }

/* ---- light theme: raw values ---- */
body.light, html.light {
  --bg:#f2f2f3; --panel:#f2f2f3; --panel2:#e9eaeb; --text:#1d1f20; --dim:#60646a;
  /* WCAG AA: the same hues one step deeper, so small text on light tints and blue keys pass 4.5:1 */
  --green:#376e4f; --red:#93463d; --amber:#7c5f24; --blue:#476786; --onblue:#ffffff; --oms:#694b9a;
  --line:rgba(29,31,32,.18); --hov:#e4e6e8; --grid:rgba(29,31,32,.055);
  --okbg:#e0ece4; --warnbg:#f0e6ca; --badbg:#f1dcd8; --accbg:#dbe5ee;
  --wms-task:#c4322b;
  --line-field:rgba(29,31,32,.5);               /* 3.1:1 on --panel2, 3.2:1 on white */
  --text-faint:#62666c;                         /* 4.8:1 on --panel2, 5.8:1 on white */
  --danger-fill:#93463d; --on-danger:#ffffff;   /* 6.6:1 */
  --canvas:#eceef0; --surface-1:#f6f7f8; --surface-2:#ffffff; --surface-3:#e4e6e8; --hover:#ebeef1; --rail-bg:#e6e9ec;
  --hair:rgba(29,31,32,.09); --blue-hi:#3b5873; --steel:#6e7d8c;
  --floor:#e9ecef; --glow:rgba(255,255,255,.75); --ink-rgb:29,31,32;   /* light: lines are --text at low alpha, no glow */
  --floor-art:.05; --floor-rule:.055;                                   /* graphite on drafting paper */
  --floor-show:.24;
  --plus:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='11'><path d='M5.5 0v11M0 5.5h11' stroke='%23565a5e' stroke-width='1'/></svg>");
  color-scheme:light;
}
html:has(> body.light) { color-scheme:light; }

/* ---- built from the tokens above (declared on :root and body, so they follow the theme class) ---- */
:root, body {
  /* the brief's names for page-palette values */
  --text-dim:var(--dim); --on-blue:var(--onblue); --ok-bg:var(--okbg); --warn-bg:var(--warnbg); --bad-bg:var(--badbg);
  --accent-bg:var(--accbg);
  /* semantic aliases, defined once (they replace every var(--danger,#hex) fallback) */
  --danger:var(--red); --warning:var(--amber); --success:var(--green); --info:var(--blue); --muted:var(--dim);
  --section:var(--blue);                        /* the current section's accent: blue WMS, violet OMS */
  --focus-ring:var(--focus-w) solid var(--section);
  /* materials and elevation (machined finish) */
  --chrome:color-mix(in srgb,var(--panel) 97%,transparent);                                    /* sticky chrome */
  --chrome-heavy:color-mix(in srgb,color-mix(in srgb,var(--panel) 83%,#000) 97%,transparent);   /* sidebar rail */
  --edge-hi:rgba(232,238,245,.07);      /* 1px light catching the machined top edge */
  --edge-lo:rgba(4,10,16,.35);
  --edge-shade:rgba(8,16,24,.32);       /* scroll-edge fade under sticky chrome */
  --key:inset 0 1px 0 rgba(255,255,255,.24),inset 0 -1px 0 rgba(8,16,24,.16);   /* filled key */
  --key-pressed:inset 0 1px 2px rgba(8,16,24,.3);
  --elev-1:0 0 #0000;                   /* flat panels sit level with the canvas: the 1px rule is the edge */
  --elev-2:inset 0 1px 0 var(--edge-hi),0 1px 0 var(--edge-lo),0 12px 28px -20px rgba(4,10,16,.8);
  --elev-3:inset 0 1px 0 var(--edge-hi),0 2px 6px -2px rgba(4,10,16,.5),0 32px 72px -28px rgba(4,10,16,.85);
  --e1:inset 0 1px 0 var(--edge-hi);    /* a card one step above the canvas (Living Blueprint) */
  --shadow:0 22px 48px -24px rgba(5,10,16,.8);
  --scrim:rgba(8,16,24,.62);
  --scroll-thumb:rgba(232,238,245,.26);
}
body.light, html.light, html.light body {
  --chrome-heavy:color-mix(in srgb,color-mix(in srgb,var(--panel) 96%,var(--text)) 97%,transparent);
  --edge-hi:rgba(255,255,255,.8);
  --edge-lo:rgba(29,31,32,.1);
  --edge-shade:rgba(29,31,32,.09);
  --key:inset 0 1px 0 rgba(255,255,255,.26),inset 0 -1px 0 rgba(0,0,0,.14);
  --key-pressed:inset 0 1px 2px rgba(0,0,0,.24);
  --elev-2:inset 0 1px 0 var(--edge-hi),0 1px 0 var(--edge-lo),0 12px 28px -20px rgba(29,31,32,.35);
  --elev-3:inset 0 1px 0 var(--edge-hi),0 2px 6px -2px rgba(29,31,32,.16),0 32px 72px -28px rgba(29,31,32,.4);
  --e1:0 1px 2px rgba(29,31,32,.06),inset 0 1px 0 var(--edge-hi);
  --shadow:0 22px 48px -26px rgba(29,31,32,.35);
  --scrim:rgba(29,31,32,.34);
  --scroll-thumb:rgba(29,31,32,.28);
}
/* A dialog's backdrop: declared on ::backdrop itself, because older Chrome (before 122) gives ::backdrop no inherited values. */
::backdrop { --scrim:rgba(8,16,24,.62); --backdrop-solid:#142330; }
body.light ::backdrop { --scrim:rgba(29,31,32,.34); --backdrop-solid:#e9eaeb; }
html[data-wms-section="oms"] body { --section:var(--oms); --focus-ring:var(--focus-w) solid var(--oms); }

/* ---- accessibility preferences ---- */
@media (prefers-contrast:more) {
  html body:not(.light) { --line:rgba(232,238,245,.55); --line-field:rgba(232,238,245,.7); --dim:#c3d0dc; --edge-hi:transparent; }
  html body.light { --line:rgba(29,31,32,.55); --line-field:rgba(29,31,32,.75); --dim:#45494e; --edge-hi:transparent; }
}
