/* Design tokens. Two layers, deliberately:
 *   1. LEGACY — slice-1 neutrals still consumed by the slice 1–5 stand-in
 *      styles. They retire as slice 7+ restyles each surface onto the
 *      foundation tokens below.
 *   2. THE FOUNDATION — the Aug 27–29 design sitting, transcribed slice 6c.
 *      design/invoice-edit.html WAS the spec (deleted Aug 31; the built page is
 *      the spec now, git has the prototype); every value below was its :root,
 *      derived as written: the 8px unit, one content width, THE line, four
 *      tints from one brand hue.
 */

/* ── the faces (licensed Aug 31: Mass-Driver Commercial, up to 5 people).
   WOFF2 only, per the foundry's own self-hosting guidance; filenames are
   family-weight, lowercase, no diacritics (macOS NFD vs Linux NFC never
   gets a vote). Family strings are ours and drop the accent too — "MD
   Lorien" — so no encoding survives anywhere in the pipeline. Exactly the
   styles the app uses: 400 everywhere, 500 for UI/IO emphasis; display is
   Lorien Regular by ruling (Aug 31 A/B). ── */
@font-face{font-family:"MD UI";src:url("/fonts/mdui-regular.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"MD UI";src:url("/fonts/mdui-medium.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"MD IO";src:url("/fonts/mdio-regular.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"MD IO";src:url("/fonts/mdio-medium.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"MD Lorien";src:url("/fonts/mdlorien-regular.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"MD Lorien";src:url("/fonts/mdlorien-book.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap}   /* Book at the 500 slot (bought Sep 8: the Serif set puts Lorien in the UI role, which asks for 500) */
/* THE OFFERED SETS beyond ours (ruled Sep 8: Degular · Swear · Retail · Softie, from OH no Type — variable builds, one file per family carrying the weight range; Cilati is Swear's italic, loaded as the same family's italic style) */
@font-face{font-family:"Degular";src:url("/fonts/degular.woff2") format("woff2");font-weight:200 900;font-style:normal;font-display:swap}
@font-face{font-family:"Swear";src:url("/fonts/swear.woff2") format("woff2");font-weight:300 900;font-style:normal;font-display:swap}
@font-face{font-family:"Swear";src:url("/fonts/swear-cilati.woff2") format("woff2");font-weight:300 900;font-style:italic;font-display:swap}
@font-face{font-family:"Retail";src:url("/fonts/retail.woff2") format("woff2");font-weight:300 900;font-style:normal;font-display:swap}
@font-face{font-family:"Softie";src:url("/fonts/softie.woff2") format("woff2");font-weight:300 900;font-style:normal;font-display:swap}
/* THE SIGNATURE FACE (ruled Sep 16: Tilda Grande, licensed — Jessica's file) — the one script face; typing is signing, and the name renders in it on both sides of the sign block and on the certificate. Grande is the display cut: Petite, the small-size cut, read heavy at 34px (measured in Chrome on prod, Sep 16) — its file sits beside this one in /fonts, undeclared. Replaces Hipster Script (Sep 8). */
@font-face{font-family:"Tilda Grande";src:url("/fonts/tilda-grande.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap}

/* ── legacy (slices 1–5 stand-ins) ── */
html{font-size:100%}   /* THE ROOT (Sep 28): every length in the app is a rem of this — type, spacing, strokes, breakpoints. A scaling tier for an environment is one declaration here, never a rule elsewhere. */
:root {
    --color-ink: #322d2a;
    --color-paper: #fffdf8;
    --color-accent: #fcff28;
    /* --color-error RETIRED Sep 8 (Kickoff 11): ONE RED — every error reads --late, the overdue rust. */
    --font-text: "GT Alpina", Georgia, serif;
    --font-ui: "Circular", system-ui, sans-serif;
    --space: 1rem;
}

/* ── the foundation (Aug 27–29, transcribed slice 6c) ── */
:root {
    /* Type. REFRESH layer — faces are Chris-selected, never a session's call.
       The licensed families (the @font-face block above — declared ONCE, here,
       with font-display: swap; Caddy serves /fonts/* with a year-long immutable
       cache header), honest fallbacks last. The "Trial" bridges for machines
       carrying the trial installs are GONE (Kickoff 26, Sep 11): every face is
       licensed and shipped, so a local trial could only mask a missing file. Weights
       are PINNED to styles the faces actually have (A/B'd in Chrome, Aug 31):
       display = Lorien REGULAR (400 everywhere); UI/IO emphasis = MEDIUM
       (500); nothing bolder, no italics — and nothing bolder is LICENSED, so
       a future style asking for 600+ must buy the style, not synthesize. */
    --ui: "MD UI", system-ui, sans-serif;
    --display: "MD Lorien", serif;
    --mono: "MD IO", monospace;
    /* The ONE signature face (the proposal sitting, Sep 3): theater, no
       per-document choice — typing is signing, and the name renders in it
       on both sides of the sign block. RULED Sep 16: Tilda Grande (the
       @font-face above), replacing Hipster Script (Sep 8), which replaced
       the Snell Roundhand stand-in; at 34px on the slot line it reads as a
       signature and stays legible. The old stand-ins stay as fallbacks
       while the face loads. The face's ligatures and word-edge strokes are
       asked for where the signature renders (paper.css's signature rule). */
    --script: "Tilda Grande", "Snell Roundhand", "Apple Chancery", "Brush Script MT", cursive;

    /* Ink and paper. */
    --paper: #fff;
    --ink: #17171a;
    /* The grey LADDER (Aug 31, evening): ink2 and ink3 are mixes of ink into
       the panel — the darkest common ground — so their contrast is a property
       of the math: 7.8:1 and 4.9:1 on the panel, higher on the tint and the
       paper, for any brand. Fixed hexes (#5c5b57, #9a9892) retired: ink3 had
       fallen to 2.3:1. Side effect, welcome: the greys take the ground's cast. */
    --ink2: color-mix(in oklab, var(--ink) 75%, var(--panel));
    --ink3: color-mix(in oklab, var(--ink) 60%, var(--panel));
    --hint: oklch(from var(--brand) 0.55 calc(c * 0.5) h);   /* PLACEHOLDER TEXT (ruled Sep 18): the brand's hue at a FIXED lightness — 0.55 is the lightest L that holds 4.5:1 on a white field for ANY brand (worst case, a pure green: 4.57:1; 0.56 falls to 4.38), and half the chroma keeps every brand inside sRGB, so the number is the math's, not a gamut map's. The border (--field, ~2:1) was asked for and cannot carry text. WHITE GROUNDS ONLY: on --highlight it falls under 4.5 — a focused .f keeps --ink3. */
    --rule2: #cfcbc2;   /* the one soft grey the tints don't derive (checkbox border) */

    /* THE brand hue. The palette sitting changes this one variable and every
       tint follows. OURS (ruled Sep 14, Kickoff 44): the Studioworks blue —
       Sapphire, #3E45A3 (Kickoff 43) — is what the shell wears with no studio
       acting (the door pages, the styleguide). The Faculty green stand-in the
       prototype pinned on Aug 29 for old-vs-new comparison is retired here;
       Email\Acting::DEFAULT_BRAND mirrors this value for mail. */
    --brand: #3E45A3;
    /* THE BRAND AS A FILLED SURFACE (ruled Sep 8, the olive — Kickoff 11; NAMED Sep 24, issue #53, the second sit): the
       brand under a RELAXED cap (L ≤ .82 — a pale brand still fills visibly, a saturated yellow stops being a highlighter).
       What the logo's tint (.tinted — and mail's raster, Email\Lockup, through its tone) and OUR OWN MARK in the rail wear —
       never --fill: green buttons must not turn a burgundy logo green. */
    --brand-fill: oklch(from var(--brand) min(l, 0.82) c h);
    /* BUTTONS (ruled Sep 24, issue #53 — studios.buttons, Green · Brand; Studio\Buttons): the color of anything you can do —
       the primary button, links, ticks, the acting cell. --green is THE ONE GREEN: the oldest "go" there is — the old app was
       green for everyone (#00AA3F), so green is continuity and a nicer green is an upgrade nobody reads as a change (the
       board's #347738 leaned olive). BrandStyle emits the studio's --fill at body level: var(--green), or oklch(from
       var(--brand) min(l, 0.55) c h) — the brand's hue just dark enough for white text, a dark brand itself. A studio that
       never chose gets the null rule: Brand when the brand's hue is in the green band (h 120°–200°, chroma ≥ .05 — two greens
       is silly), else Green. Ours (no studio acting: the door pages, the styleguide) is the same rule on Sapphire: green.
       Every button is dark by construction, so --on-fill is WHITE (if a light fill ever returns, the text on it is the INK,
       not black) and --acting IS --fill — links, ticks, the acting cell follow the button: one color, one job. This retires
       the Aug 31 acting cap (the brand at L ≤ .5) as a token; it survives only inside --field, the line, below. */
    --green: oklch(0.54 0.15 152);
    --fill: var(--green);
    --on-fill: #fff;
    --acting: var(--fill);
    --late: #8a3b12;       /* OVERDUE — the one color that isn't the brand's, used sparingly (prototypes/hub.html's .late); a token so no component carries the literal. ONE RED (ruled Sep 8, Kickoff 11): the flash's error, the field error's label · border · message all read THIS — --color-error retired, so there is one red to adjust (or, later, to let a studio adjust within bounds). ALERT IS PARKED (Sep 24, issue #53): Rust for every studio; the clash-band derivation is recorded in prototypes/settings.html's ALERT block for a later issue. */
    --highlight: #fff388;  /* the studio's HIGHLIGHT — where you are (active nav, field focus, hover). Renamed from --yellow Aug 31: a token names a role, never a value — the studio will choose this (the palette settings vision). The three-contrast rule: ink on highlight must read. */

    /* ── framework (Aug 28): 8px unit, one app-wide content width, fluid
       outer padding only ── */
    --u: .5rem;                     /* 8 — REM EVERYWHERE (Sep 28, Jessica's law): the unit is half the root, so the root is the one lever that scales the whole system */
    --stroke: .125rem;              /* 2 — the chrome's line, every field's border; a stroke, not a gap, so it is not on the ramp */
    --hairline: .0625rem;           /* 1 — the paper's rule (the sitting that reconciles the two strokes is still open; until then each has its name) */
    --content: 59rem;               /* 12 × 64 + 11 × 16 — a ceiling, not a target */

    /* ── the spacing ramp (Sep 28): every step a multiple of the unit, named by its place on the ramp, never its
       value — whole units carry the plain names, the half- and quarter-units carry between-step names from their
       neighbors (xs-sm, sm-md, md-lg, lg-xl, xxl-xxxl). The top is slotted by use, not by the unit (Sep 28): 48 and 64
       are the paper's and the chrome's rhythm (19 and 13 readers), 40 is rare (three, and the card's padding), so 40 is
       the between-step and the ramp tops at xxxxl. A spacing literal in a sheet is a finding; the usage-named tokens
       below read the ramp, so the ramp is the one source. ── */
    --space-xxs: calc(0.25 * var(--u));  /* 2 */
    --space-xs: calc(0.5 * var(--u));    /* 4 */
    --space-xs-sm: calc(0.75 * var(--u));/* 6 */
    --space-sm: var(--u);                /* 8 — also THE TWO-CELL GAP (ruled Sep 29, issue #78 §2; the design branch's ladder names it so): the one gap between the controls of an action group — the bar's ··· · SAVE · PUBLISH, the end row's Cancel · verb, the phone mast's two pickers and two action cells. A picker (.mode, .seg) is one object and keeps touching. */
    --space-sm-md: calc(1.25 * var(--u));/* 10 */
    --space-md: calc(1.5 * var(--u));    /* 12 */
    --space-md-lg: calc(1.75 * var(--u));/* 14 */
    --space-lg: calc(2 * var(--u));      /* 16 */
    --space-lg-xl: calc(2.5 * var(--u)); /* 20 */
    --space-xl: calc(3 * var(--u));      /* 24 */
    --space-xxl: calc(4 * var(--u));     /* 32 */
    --space-xxl-xxxl: calc(5 * var(--u));/* 40 */
    --space-xxxl: calc(6 * var(--u));    /* 48 */
    --space-xxxxl: calc(8 * var(--u));   /* 64 */

    /* ── the type ramp (Sep 28, Jessica's 01-typography, re-tuned): size only — line-height, weight and tracking are the
       call site's until the roles are bundled. Her eight steps with the app's values where the app's are the tuned ones
       (xxs 11 is the eyebrow, xxxl 34 the numeral); the between-steps carry the real recurring odd sizes. 13 folded into
       sm, 15 and 17 into md, 24 into xl, 28 into xxl (ruled Sep 28: one pixel apart is one step). ── */
    --text-xxs: .6875rem;           /* 11 */
    --text-xs: .75rem;              /* 12 */
    --text-sm: .875rem;             /* 14 */
    --text-md: 1rem;                /* 16 — the body */
    --text-lg: 1.125rem;            /* 18 */
    --text-lg-xl: 1.25rem;          /* 20 */
    --text-xl: 1.375rem;            /* 22 */
    --text-xxl: 1.625rem;           /* 26 */
    --text-xxl-xxxl: 1.875rem;      /* 30 */
    --text-xxxl: 2.125rem;          /* 34 */
    --text-xxxxl: 3rem;             /* 48 — the receipt's sum, a size above the numeral */
    /* the script face is its own family with its own sizes (her law): the signature at 48, 36 and 28 by the name's length
       (Signature::sizeClass); each size's seat on its line is measured in paper.css and is a type metric, not spacing */
    --script-lg: 3rem;              /* 48 */
    --script-md: 2.25rem;           /* 36 */
    --script-sm: 1.75rem;           /* 28 */

    /* ── tracking (Sep 28): em factors, her names. wide is the app's .08 — her ramp's wide is .04, ours was set with the
       face (Aug 29) and stands. ── */
    --tracking-wide: .08em;

    /* ── roles (Sep 28, her 01-typography): thin bundles over the ramps — a role names a FUNCTION, never a size; a call
       site reads the bundle whole and adds nothing of its own but color (and a pinned line box where a row is built
       around it). EYEBROW: the small tracked caps over a block — a list's head, CLIENT and PROJECT on the paper, the
       column heads, a segment's label, INVOICE NO. over the numeral. ── */
    --eyebrow-font: 500 var(--text-xxs)/1 var(--ui);
    --eyebrow-tracking: var(--tracking-wide);
    --eyebrow-casing: uppercase;
    /* ACTION: text as a control — a button, a bar's cell, a segment's label, a summary row, a list's head, an act in a
       row. A step up from the eyebrow, the same tracking and casing, on one line (every site is a fixed-height cell or
       nowrap, so the leading is 1; the 1.4 eight of them carried was never reached). */
    --action-font: 500 var(--text-xs)/1 var(--ui);
    --action-tracking: var(--tracking-wide);
    --action-casing: uppercase;
    /* WEIGHTS: the three faces ship 400 and 500 and nothing heavier (Chris, Aug 31) — her Light is 400 here, her Semibold
       and Bold 500, stated once; every sheet's b and strong read 500 so nothing is ever synthesized. Her remaining roles,
       each a step · weight · leading · face, ruled Sep 28 (Row 1.4; Label 500; Explainer 1.5 to try; no Section Title —
       the app's section title is the eyebrow on a rule). */
    --title-font: 400 var(--text-xxxl)/1.1 var(--display);      /* PAGE TITLE: the page's h1, the certificate's — nowhere else */
    --item-title-font: 400 var(--text-xl)/1.25 var(--display);  /* ITEM TITLE: a document's heading, a party's name, a package's */
    --paragraph-font: 400 var(--text-md)/1.5 var(--ui);         /* PARAGRAPH: prose you read — the body, a note; 16 on a 24 box, the grid's */
    --row-font: 400 var(--text-md)/1.4 var(--ui);               /* ROW: a list row's line, a field's text — one line, the tighter box */
    --label-font: 500 var(--text-sm)/1 var(--ui);               /* LABEL: a field's caption — names a thing, never wraps into prose */
    --explainer-font: 400 var(--text-xs)/1.5 var(--ui);         /* EXPLAINER: the small prose — a hint, a fact list, a footer line */
    --metadata-font: 400 var(--text-xs)/1.4 var(--ui);          /* METADATA: a date, a count, a trailing detail */
    --figure-font: 400 var(--text-sm) var(--mono);              /* FIGURE: a number in a row — the leading is its row's */
    --sum-font: 500 var(--text-lg-xl)/1 var(--mono);            /* SUM: a total, and its two size variants — */
    --sum-font-lg: 500 var(--text-xxxl)/1.1 var(--mono);        /*   the money box's */
    --sum-font-xl: 500 var(--text-xxxxl)/1 var(--mono);         /*   the receipt's, the paper's largest figure */
    --edge-fluid: clamp(var(--space-lg), 3vw, var(--space-xxl-xxxl));   /* the only fluid value in the app: the outer padding, frame to card */
    --edge-inset: var(--space-xl);                 /* the inset from the fluid edge to the content: 3u above the 856 breakpoint (was 5u; Jessica, Sep 28: the sections sat too far in), 1u below it (the mobile pass, Sep 15) */
    --gx: var(--edge-fluid);                /* the fluid value under the name the grid gaps read */
    --rail-w: 11.5rem;                /* 23u */

    /* ── field system "C": tinted ground, white fields — four tints from the
       one brand hue ── */
    --tint: color-mix(in oklab, var(--brand) 6%, white);
    --panel: color-mix(in oklab, var(--brand) 14%, white);   /* THE GROUND (ruled Aug 31, evening): the content panel sits deeper than the frame, so the white fields are windows cut into it — "makes the page feel much more obvious" (Chris). Rail + bar stay on --tint: a light L holding a deeper panel; the paper stays white, the brightest thing by design. Ceiling is the line: past ~24% the 40% line fades into the ground. */
    --rail: color-mix(in oklab, var(--brand) 10%, white);   /* SUPERSEDED Aug 31 — the rail reads --tint; kept for the styleguide's tint ladder */
    --rule: color-mix(in oklab, var(--brand) 18%, white);
    --field: color-mix(in oklab, oklch(from var(--brand) min(l, 0.5) c h) 40%, white);   /* THE line — FROM THE BRAND, never from acting (ruled Sep 24, issue #53): green buttons on a burgundy brand must not turn the chrome's rules green; the L ≤ .5 cap keeps the chrome from fading with a pale palette */
    --outside: color-mix(in oklab, var(--brand) 22%, white);   /* the ground OUTSIDE the frame (past ~1300): deeper than the panel it frames (was 12%, now lighter than the panel — moved Aug 31) */
    --bg: var(--tint);
    --fh: calc(6 * var(--u));       /* 48 — every chrome rectangle and every field */
    --bar: calc(9 * var(--u));      /* 72 — the masthead's cell (ruled Sep 3): the lockup and the bar share one row; its 48 cells sit with 12 of air above and below */
    --mast: calc(var(--bar) + var(--stroke)); /* the masthead is the one sticky exception to the border rule — its line travels with it, so it is sized as its cell PLUS its line */
    --foot: calc(var(--bar) + var(--stroke)); /* the footer: a cell plus its line, the masthead's height — the frame's top and bottom bands match (prototypes/home.html, Chris, Sep 3; the kickoff's --fh + 2px is FLAGGED as the alternative — one token) */
    --line: var(--stroke) solid var(--field); /* THE line — chrome and fields are made of the same stroke */
    --content-edge: calc(var(--edge-fluid) + var(--edge-inset));  /* where content begins — the two edges summed; the bar's tabs and primary share it, and .sec's bleed reads it */
    --pick-w: 7.875rem;              /* 126 — the widest picker cell at 375 (PROPOSALS: 12 + the word + 32, in its lines), measured Sep 30 (Chrome, MD UI loaded); a part of --mast-min */
    --mast-min: calc(2 * var(--content-edge) + 4 * var(--u) * 294.2 / 40.2 + var(--space-lg) + 2 * var(--pick-w) + var(--space-sm));   /* THE ONE-ROW MAST'S MINIMUM (issue #86): the two content edges + the wordmark at 4u (its viewBox's 294.2:40.2) + the brand's 16 + two pickers + the cell gap — 558.2 at 375's edges. Documentary: a media query can't read it, so studio.css writes its value (559, 34.9375rem) at the mark's switch, and MastMinimumTest holds the two together */

    /* ── the client hub (the sitting of Sep 2) ── */
    --side: calc(48 * var(--u));    /* the client's column: 384. Not a grid number — it isn't on the grid, the same way the rail's 184 isn't. Sized for the Payment Element (Stripe's fields want ~330 of room) and the fee disclosure beside it; the paper flexes with what's left. */
}

@media (max-width:53.4375rem){:root{--edge-inset:var(--u)}}   /* the fold: the inset drops to 1u, and every --content-edge reader follows (the h1 lands at 2 + 16 + 8 = 26 on a 360 doc) */

/* ── THE DERIVATIONS, RE-DECLARED ON BODY (Kickoff 11, Sep 8; the prototype's own note): a custom property resolves where
   it is declared, so the :root derivations above compute from :root's --brand and would NOT follow a --brand set on body.
   The studio's brand block (Studio\BrandStyle) declares --brand · --highlight · --ink and the three faces on body.studio, and
   the Brand tab's live preview (body:has(input[name=theme]…:checked){--brand…}) overrides them there — so every token that
   derives from the brand is declared HERE too, at body level, in the same relative-color form as above (tokens.css stays
   the one truth; this block is the same expressions at the level the override happens). --line is a compound token and
   rides along for the same reason. THE FACES TOO (issue #121, Sep 30): the type roles read --display · --ui · --mono, which
   BrandStyle sets on body.studio and the Brand tab's font-set preview overrides there — declared on :root alone they
   computed from the platform's faces and a studio's set never reached an h1, an eyebrow or a figure. BodyDerivationsTest
   derives the rule: every :root property that reads a body-set variable, directly or through another, is repeated here,
   the identical expression. ── */
body.studio {
    --ink2: color-mix(in oklab, var(--ink) 75%, var(--panel));
    --ink3: color-mix(in oklab, var(--ink) 60%, var(--panel));
    --hint: oklch(from var(--brand) 0.55 calc(c * 0.5) h);
    --brand-fill: oklch(from var(--brand) min(l, 0.82) c h);
    --acting: var(--fill);   /* --fill itself is the studio's, emitted by BrandStyle on this element (issue #53); --on-fill is a constant and inherits */
    --tint: color-mix(in oklab, var(--brand) 6%, white);
    --panel: color-mix(in oklab, var(--brand) 14%, white);
    --rail: color-mix(in oklab, var(--brand) 10%, white);
    --rule: color-mix(in oklab, var(--brand) 18%, white);
    --field: color-mix(in oklab, oklch(from var(--brand) min(l, 0.5) c h) 40%, white);
    --outside: color-mix(in oklab, var(--brand) 22%, white);
    --bg: var(--tint);
    --line: var(--stroke) solid var(--field);
    --eyebrow-font: 500 var(--text-xxs)/1 var(--ui);
    --action-font: 500 var(--text-xs)/1 var(--ui);
    --title-font: 400 var(--text-xxxl)/1.1 var(--display);
    --item-title-font: 400 var(--text-xl)/1.25 var(--display);
    --paragraph-font: 400 var(--text-md)/1.5 var(--ui);
    --row-font: 400 var(--text-md)/1.4 var(--ui);
    --label-font: 500 var(--text-sm)/1 var(--ui);
    --explainer-font: 400 var(--text-xs)/1.5 var(--ui);
    --metadata-font: 400 var(--text-xs)/1.4 var(--ui);
    --figure-font: 400 var(--text-sm) var(--mono);
    --sum-font: 500 var(--text-lg-xl)/1 var(--mono);
    --sum-font-lg: 500 var(--text-xxxl)/1.1 var(--mono);
    --sum-font-xl: 500 var(--text-xxxxl)/1 var(--mono);
}
