/* design-tokens.css — THE portal's design system, as data.
 *
 * WHY THIS FILE EXISTS (UI2 / REG-M12, 01/09/2026). Measured 28/08/2026: 66 distinct hex
 * colours and 25 distinct font-size values across 715 lines of CSS in four files, and no
 * design-system file anywhere in the repo. A stylesheet with 26 hand-typed greys in it has no
 * design system; it has a history. Re-measured 01/09 on the NEW portal alone (shopfront.css):
 * 26 distinct hexes, 28 distinct font-size values, 447 lines.
 *
 * ORDER OF THE THREE STYLESHEETS, and it matters:
 *
 *   theme.css          the SHARED WeTalk palette — brand navy, blue, surfaces, borders.
 *                      🚨 MIRRORED INTO THE CONSOLE by tools/sync-shared.js. Editing it changes
 *                      tools/admin-panel/ too. Nothing in this file writes to it.
 *   design-tokens.css  THIS FILE. The portal's own layer, built ON theme.css's variables.
 *   shopfront.css      components only. It declares no raw colour and no raw font-size.
 *
 * THE RULE THIS FILE EXISTS TO MAKE ENFORCEABLE: a colour or a type size is named here once, and
 * every component points at the name. `scripts/test-design-tokens.js` fails the build on a raw
 * hex or a raw font-size in shopfront.css, so the next hand-typed grey is a refused commit
 * rather than the 27th grey.
 *
 * 🚨 EVERY VALUE BELOW IS THE VALUE THAT WAS ALREADY THERE, to the digit. UI2's bar is "the
 * portal rendering UNCHANGED against the mockups at the exact-match bar" — this pass moves
 * values into names and changes nothing a client can see. The measured proof is in
 * design/reference/STATUS.md: the board before and after this file are identical, screen for
 * screen. The type scale is CHANGED by REG-PORTAL-UI part 2, in this file, on purpose: that is
 * why the roles exist.
 */

:root{
  /* ---------------------------------------------------------------------------
     TYPEFACE, SHELL METRICS. Unchanged, lifted out of shopfront.css's own :root.
     No external font host is reachable from this app by policy, so a web font has
     to be served from here or not at all.
     --------------------------------------------------------------------------- */
  /* 🚨 "Inter" CAME OFF THE FRONT ON 02/09/2026, and the reason is that IT WAS NEVER LOADED.
     Nothing in this app ships an @font-face and the Content-Security-Policy is `default-src
     'self'` with no `font-src`, so a webfont from anywhere else is blocked outright. The stack
     asked for a typeface that could only ever arrive if the person's own machine happened to
     have it installed.

     So the portal rendered in Inter for somebody with Inter installed and in the system font for
     everybody else — the same page, two typefaces, decided by the visitor's font folder. Checked
     02/09: Hamish's Mac does NOT have Inter, so what he has been reviewing all along, and what
     he meant by "keep it like that font", is the SYSTEM font.

     Naming the system font first makes every machine agree with the one the design was signed
     off on. The alternative — shipping an Inter woff2 — would have been a real change to what he
     is looking at, not a fix, and it needs a ruling rather than a quiet commit.

     ⚠️ IF INTER IS EVER ACTUALLY WANTED: it has to be self-hosted (the CSP forbids Google Fonts),
     added to the served-files allowlist that pre-deploy-check.sh section 7 enforces, and it will
     change the look of every page. That is a design decision, not a tidy-up. */
  --sf-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --radius:16px; --sf-gap:16px; --sf-side:285px;

  /* ---------------------------------------------------------------------------
     INK. Six steps, darkest first. Everything that was a hand-typed grey is here.
     --------------------------------------------------------------------------- */
  --sf-navy:var(--navy);       /* headings and anything that must read as the brand */
  --sf-ink-2:#5a6a80;          /* secondary text, a touch darker than --mut */
  --sf-ink-3:#8b97a8;          /* tertiary: honesty notes, sublines, timestamps */
  --sf-ink-4:#93a0b4;          /* the palest readable grey: page sub-lines, the ask line */
  --sf-ink-off:#a6b0c0;        /* NOT-BUILT-YET. soon tags, off labels, unset cells */
  --sf-ink-faint:#c3cddb;      /* glyphs at rest, timeline dots */

  /* ---------------------------------------------------------------------------
     LINES AND SURFACES beyond theme.css's --border / --surface / --surface-2.
     --------------------------------------------------------------------------- */
  --sf-line-2:#e8edf4;         /* the lightest rules, inside cards */
  --sf-line-strong:#c9d4e2;    /* a control's border on hover */
  --sf-line-dashed:#ccd7e6;    /* the dashed drop panel */
  --sf-canvas:#FCFDFF;         /* the map canvas, a shade off white */

  /* ---------------------------------------------------------------------------
     THE APP FRAME (10/09/2026). MEASURED off design/reference/portal/home.png:
       ground  rgb(244,245,246) at every outer edge   card rgb(254,254,254)
       inset   4px left, 9px right, 9px top, 4px bottom on a 1658px canvas
       radius  11px on that canvas
     Symmetric 8px here because 4/9/9/4 is a drawing artefact, not something anyone
     would ship, and 8px sits inside the measured range on every edge.
     --------------------------------------------------------------------------- */
  --sf-ground:#f4f5f6;
  --sf-frame:8px;
  --sf-frame-radius:12px;

  /* ---------------------------------------------------------------------------
     BLUE. The accent family. ⚠️ --sf-blue-soft and --sf-blue-tint are ONE HEX APART
     (#eaf5fd / #eaf6fd) and are two different names because they were two different
     literals in the file. That is real drift, not a design decision — but collapsing
     them CHANGES PIXELS, and this pass changes none. Named so it is visible; closing
     it belongs to part 2, with the board re-measured after.
     --------------------------------------------------------------------------- */
  --sf-blue:var(--blue);
  --sf-blue-soft:#eaf5fd;      /* active nav pill + icon tiles */
  --sf-blue-tint:#eaf6fd;      /* settings sub-nav on, picked vocab, the "checking" pill */
  --sf-blue-edge:#cfe6f8;      /* the ask box's border */
  --sf-blue-line:#bfe3f7;      /* a picked chip's border */
  --sf-blue-ring:#9fd4ef;      /* the spinner's track */
  --sf-blue-ink:#0b6f9e;       /* text that must stay legible on a pale blue fill */
  --sf-on-blue:#fff;           /* text ON the solid blue: buttons, the active chip */

  /* ---------------------------------------------------------------------------
     STATUS. Three pairs, ink + fill, plus the one row tint.
     🚨 A CARD WITH NO SOURCE IS NEVER RED OR AMBER. These say "this ran and failed"
     or "this is running", never "this is unbuilt" — nothing is broken, it is unbuilt,
     and --sf-ink-off is the vocabulary for that.
     --------------------------------------------------------------------------- */
  --sf-danger-ink:#b3261e; --sf-danger-bg:#fdecea; --sf-danger-row:#fff8f7;
  --sf-ok-ink:#136b47;     --sf-ok-bg:#e4f5ec;     --sf-ok-line:#cfe6cb;
  --sf-warn-ink:#8a5a08;   --sf-warn-bg:#fdf0da;

  /* The one DESTRUCTIVE control's own states (Live run, 08/09/2026). The three above are the
     vocabulary for REPORTING something bad; these four are for a button that DOES something
     irreversible, which is a different job and needs its own resting, hover and disabled steps.
     Named here on 09/09/2026 rather than left raw in shopfront.css: the rule was written with
     the values inline and the fill was #b3261e, which is --sf-danger-ink typed out a second time
     - exactly the drift this file exists to stop. */
  --sf-danger-fill:var(--sf-danger-ink); /* resting fill: the report colour, used as a surface */
  --sf-danger-edge:#8c1d18;              /* its border, one step darker than the fill */
  --sf-danger-hover:#9c211a;             /* pressed and hovered */
  --sf-danger-off:#e6b5b1;               /* disabled: still legibly red, clearly not pressable */
  --sf-on-danger:#fff;                   /* text ON a solid danger fill */

  /* The local-preview banner. Developer-facing, never seen by a client. */
  --sf-banner-bg:#fff6e2; --sf-banner-line:#f0e0b6; --sf-banner-ink:#8a6d3b;

  /* ---------------------------------------------------------------------------
     DEPTH.
     --------------------------------------------------------------------------- */
  --sf-card-shadow:0 1px 2px rgba(10,32,63,.04), 0 8px 24px rgba(10,32,63,.05);

  /* ---------------------------------------------------------------------------
     LIFT AND MOTION (PORTAL-FEEL-1, 11/09/2026). Hamish on the automations page:
     "it just looks so bland like it should be interactive and fun... everything
     moves really cleanly."

     🚨 ONE EASING CURVE AND THREE DURATIONS, NAMED HERE, and that is the whole
     motion vocabulary. The reason it is tokens rather than values typed at each
     component is the same reason the greys are: this file was written because 26
     hand-typed greys had accumulated, and a stylesheet with nine slightly
     different transition timings in it has exactly the same problem one layer
     over. A page whose controls each ease differently reads as cheap even when
     nobody can say why.

     --sf-lift is the hover elevation. It is the resting card shadow with the
     second layer deepened and pushed down, so a card that lifts is recognisably
     the same card, not a different component.
     --------------------------------------------------------------------------- */
  --sf-lift:0 1px 2px rgba(10,32,63,.05), 0 14px 34px rgba(10,32,63,.10);
  --sf-lift-sm:0 1px 2px rgba(10,32,63,.05), 0 6px 16px rgba(10,32,63,.08);
  --sf-ease:cubic-bezier(.4,0,.2,1);   /* the one curve: quick out, settled in */
  --sf-t-fast:.12s;                    /* a press: it must feel instant */
  --sf-t:.18s;                         /* hover, colour, lift */
  --sf-t-slow:.34s;                    /* an entrance, which may be seen */

  /* 🚨 FOUR NAMES THAT WERE USED AND NEVER DECLARED (found 07/09/2026 by
     scripts/test-design-tokens.js, which had been reporting them for some time). A var() that
     points at nothing does not fall back and does not error — the WHOLE DECLARATION is thrown
     away. So `border:1px solid var(--sf-line)` drew no border at all, on the tab strip, on the
     document viewer and on the decision bar, and `background:var(--sf-tint)` painted nothing.
     Silent, and visible only by looking at the page — the exact trap `.claude/rules/deploying.md`
     warns about for a four-dashed variable.

     They are declared as ALIASES of the tokens that already exist rather than as new colours:
     nothing new is invented, and these rules now render in the values the rest of the portal
     already uses. */
  --sf-line:var(--border);        /* the hairline: tab strip, document viewer, decision bar */
  --sf-tint:var(--surface-2);     /* the pale fill behind a hovered tab and the viewer */
  --sf-ink:var(--ink);            /* a tab's text once it is hovered */
  --sf-ink-soft:var(--mut);       /* a tab's text at rest */
  --sf-modal-shadow:0 18px 50px rgba(10,32,63,.22);
  --sf-modal-scrim:rgba(10,32,63,.34);
  --sf-ask-ring:0 0 0 4px rgba(33,169,238,.06);

  /* ---------------------------------------------------------------------------
     TYPE. THE ROLES ARE THE POINT — part 2 moves these, not the components.
     🚨 THE HONEST FINDING, recorded rather than tidied away: twenty-two distinct sizes
     were in use where a scale has about eight, and five of them (13 · 13.5 · 14 · 14.5 ·
     15) sit inside a 2px band doing near-identical jobs. They are named separately here
     because naming them is what makes the duplication VISIBLE and countable; collapsing
     them moves pixels and is part 2's call, measured.
     --------------------------------------------------------------------------- */

  /* THE PAGE'S OWN VOICE. ⬆️ MOVED BY REG-PORTAL-UI PART 2, 01/09/2026, and these two values
     are the whole of that rebuild — measured, not chosen by eye. Before: 56px and 46px, which
     rendered our headings at 63–95% of the reference's cap-height on the three pages Hamish
     named. After: 105%, 103% and 93%. The board went Σ81 → Σ77 regions off. */
  --sf-fs-hero:61px;           /* the greeting */
  --sf-fs-hero-sub:22px;       /* the line under it */
  --sf-fs-page-title:53px;     /* every page heading that is not the greeting */
  --sf-fs-page-sub:17px;
  --sf-fs-stat:54px;           /* the big number on a stat tile */
  --sf-fs-stat-sm:24px;        /* the same tile, small variant (ROI) */
  --sf-fs-tally:18px;          /* a figure inside a card */
  --sf-fs-modal-title:19px;

  /* the working middle. body is the portal's default reading size. */
  --sf-fs-title-sm:16.5px;     /* a card's heading, a list row's title */
  --sf-fs-ui-lg:15px;          /* section headings, tile labels, the zoom control */
  --sf-fs-ui:14.5px;           /* nav items, table cells, filter chips */
  --sf-fs-body-lg:14px;        /* panel prose and steps */
  --sf-fs-body:13.5px;         /* THE default: card copy, buttons, fields */
  --sf-fs-meta:13px;           /* captions, legends, back links */
  --sf-fs-meta-sm:12.5px;      /* pills, "view all", tool chips */
  --sf-fs-label:12px;          /* column headers, uppercase sub-labels */
  --sf-fs-label-sm:11.5px;     /* the honesty note under a card */
  --sf-fs-label-xs:11px;       /* a panel's uppercase heading */
  --sf-fs-micro:9.5px;         /* the SOON tag, and nothing else */

  /* phone. Own tokens on purpose: a phone heading is not a desktop heading scaled,
     and part 2 must be able to move one without dragging the other. */
  --sf-fs-hero-md:38px;        /* laptop down */
  --sf-fs-hero-sm:28px;
  --sf-fs-hero-sub-sm:15px;
  --sf-fs-page-title-sm:26px;
  --sf-fs-nav-sm:13px;

  /* ---------------------------------------------------------------------------
     THE SIGN-IN GATE, named 10/09/2026 (PORTAL-TOKENS-RED).

     🚨 THESE ARE NOT PART OF THE SCALE ABOVE AND MUST NOT BE COLLAPSED INTO IT.
     The gate is a 642px card that IS the whole page, built to the reference Hamish
     sent 01/09 by copying the console's proportions rather than re-eyeballing them
     (shopfront.css says so where the block starts). Its type is sized against that
     card, not against a workspace page, which is why every value here is larger
     than anything in the working middle. Moving one of these moves the front door
     and nothing else — which is the whole reason they are named separately.

     Named, not changed: every value below is the literal that was sitting in
     shopfront.css, carried across unaltered. This pass moves no pixels, and
     scripts/test-design-tokens.js proves it by resolving both files and comparing.
     --------------------------------------------------------------------------- */
  --sf-fs-gate-title:49px;     /* "Sign in to your workspace" */
  --sf-fs-gate-lede:24px;      /* the line under it */
  --sf-fs-gate-btn:25px;       /* the two method buttons */
  --sf-fs-gate-input:20px;     /* the email box, and the link button under it */
  --sf-fs-gate-msg:19px;       /* the message line, and the footnote at the bottom */
  --sf-fs-gate-label:17px;     /* the field label, and the "or" divider */

  /* The gate on a phone. The card is the whole 390px screen, so the scale comes
     down or the two buttons and the email box cannot be reached above the fold. */
  --sf-fs-gate-title-sm:30px;
  --sf-fs-gate-lede-sm:17px;   /* the lede and the buttons meet at one size here */
  --sf-fs-gate-input-sm:16px;
  --sf-fs-gate-msg-sm:15px;    /* message, "or", label and footnote all land here */
}
