/* ============================================================================
 * apliteni-ui — design tokens. Single source of truth for the Apliteni deck theme,
 * with viz/'s colour semantics: purple accent, near-black surfaces, green = live,
 * cyan = link/flag. Two themes, dark (default) and light, toggled with `data-theme`
 * on <html>. Everything downstream references the SEMANTIC tokens, never the ramp.
 * ========================================================================== */

:root {
  /* -- Brand ramp (theme-invariant hues) ---------------------------------- */
  --purple-900: #4c1f94;
  --purple-700: #6a2dcc;
  --purple-500: #9b5dff;
  --purple-400: #b479ff;
  --cyan-500:   #20dcf5;
  --green-500:  #98ff8f;

  /* -- Radius scale ------------------------------------------------------- */
  --radius-xs: 6px;
  --radius-sm: 9px;
  --radius-md: 12px;
  --radius-lg: 16px;
  --radius-xl: 18px;
  --radius-2xl: 24px;
  --radius-pill: 999px;

  /* -- Spacing scale (4px base) ------------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* -- Measure ------------------------------------------------------------
   * --container is the page, gutter to gutter; --measure is the reading column
   * INSIDE a track, beside a sidebar. Different axes, never interchangeable.
   * why: docs/foundations.md#widths */
  --container: 1120px;
  --measure: 860px;

  /* -- Typography ---------------------------------------------------------
   * Two roles, not one family. --font-display is the brand voice — headings,
   * brand lockups, large readouts — and --font-sans is what an application is
   * actually made of: tables, fields, paragraphs, chat. Poppins is a geometric
   * display grotesque and holds its character at heading sizes; at 13-14px it
   * smears, worst of all in Cyrillic, which is where the kit spends most of its
   * pixels. IBM Plex Sans is humanist and narrower, and its Cyrillic was drawn
   * by the same team as its Latin.
   * why: docs/foundations.md#typefaces */
  --font-display: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-sans: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --text-xs:   11px;
  --text-sm:   13px;
  --text-base: 14.5px;
  --text-md:   15.5px;
  --text-lg:   18px;
  --text-xl:   22px;
  --text-2xl:  30px;
  --text-3xl:  40px;
  --text-4xl:  56px;

  --weight-light: 300;
  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  --leading-tight: 1.2;
  --leading-snug: 1.4;
  --leading-normal: 1.62;

  --tracking-tight: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  --tracking-caps: 0.14em; /* nothing in the kit reads it since #268; consumer rules still may */

  /* -- Motion -------------------------------------------------------------
   * The kit's legacy --dur-* and --ease names alias onto the brand's
   * --duration-* and --easing-* primitives, so every component consumes one
   * vocabulary; the fallbacks keep tokens.css self-sufficient when imported
   * without brand.generated.css. Delays are the kit's own, and the reusable
   * effect layer lives in styles/motion.css.
   * Change generated brand tokens upstream in apliteni/design-system. */
  --ease: var(--easing-ease-in-out, cubic-bezier(0.4, 0, 0.2, 1));
  --ease-out: var(--easing-ease-out, cubic-bezier(0, 0, 0.2, 1));
  --ease-in: var(--easing-ease-in, cubic-bezier(0.4, 0, 1, 1));
  --ease-sharp: var(--easing-sharp, cubic-bezier(0.4, 0, 0.6, 1));
  --ease-spring: var(--easing-spring, cubic-bezier(0.34, 1.56, 0.64, 1));

  --dur-instant: var(--duration-instant, 0.08s); /* 80ms — press, tick */
  --dur-fast: var(--duration-fast, 0.15s);   /* 150ms — hover, press */
  --dur-med: var(--duration-normal, 0.25s);  /* 250ms — panels, dropdowns */
  --dur-slow: var(--duration-slow, 0.4s);    /* 400ms — enters, reveals */

  --delay-1: 60ms;
  --delay-2: 120ms;
  --delay-3: 180ms;
  --delay-4: 240ms;
  --delay-5: 300ms;

  /* -- Elevation (z) ------------------------------------------------------ */
  --z-base: 1;
  --z-sticky: 10;
  --z-dropdown: 30;
  --z-overlay: 100;
  --z-toast: 200;
}

/* ============================================================================
 * DARK THEME (default) — deck palette from viz/index.html
 * ========================================================================== */
:root,
:root[data-theme="dark"] {
  color-scheme: dark;

  --purple: #6a2dcc;
  /* The ramp moves up one step so --accent is --purple-light again, the shape light
     Nebula and light Ocean already ship; left alone the two tokens would resolve to
     one colour. #bd8cff becomes the ramp's top step instead. See issue #157. */
  --purple-light: #b479ff;
  --purple-mid: #bd8cff;
  --cyan: #20dcf5;
  --green: #98ff8f;
  /* Lighter than it looks like it should be: --pink is read mostly ON its own 16%
     glow, and that wash lifts the ground faster than the hue lifts the ink, so danger
     moved AWAY from the canvas. Light moves the opposite way. See issue #131. */
  --pink: #e97ca5;
  --amber: #ffcf6a;

  /* The elevation ladder, bottom to top. A surface says how high it is with its step
     and, IN DARK, with the hairline around it; --muted caps how far the ladder can go.
     Nothing casts in dark below the floating step, and the floating step adds
     --elev-drop under its inner line. why: docs/foundations.md#elevation */
  --bg: #0e0d14;
  --table-bg: var(--bg);
  /* A dark table is flush with the page, so the reading surface an inline code chip has
     left inside one is the card. Light's table is white, so there it is the page. */
  --table-code-bg: var(--surface);
  /* A translucent wash paints BEHIND a chip, so it moves the ground and not the chip: the
     pair has to be read against the wash composited over whatever opaque surface is under
     it. Dark's washes lift a near-black ground away from the page, so the page is what the
     chip has left; light's darken white toward the page, so the card is. Both directions
     hold over EVERY opaque ground, which is why this is a token and not a context rule.
     Measured in stories/code-chip.test.js. */
  --wash-code-bg: var(--bg);
  --surface-2: #161520;     /* non-text sunken marks and tracks */
  --surface: #211e2d;       /* the card */
  --bg-elevated: #2a2639;   /* FLOATING — menus, panels, drawer, modal, toasts */
  --surface-3: #2d293c;     /* non-text quiet fills */
  --seg-active-bg: #383350; /* raised pill — clearly above the inset track in dark */
  /* The raised handle on a control track (switch knob). White in both themes and under
     every accent: it reads on the plain track AND on the accent fill of an on control. */
  --control-knob: #ffffff;
  --border: #332f45;
  --border-strong: #453f5c;

  /* WHICH EDGE EACH LEVEL DRAWS. One name per level, so a sheet never has to ask
     which theme it is in. Dark answers all four with the hairline, because a drop
     on a near-black page reaches 1.20 at its core and has nowhere else to go.
     Light draws one line and adds a faint short drop. why: docs/foundations.md#elevation */
  --card-edge: var(--border);          /* a card */
  --rail-edge: var(--border);          /* the shell's rail */
  --float-edge: var(--border-strong);  /* a floating surface, outer line */
  --float-edge-inner: var(--border);   /* a floating surface, inner line */
  --modal-edge: transparent;           /* the modal: the deep scrim is its edge */

  /* Fields use the card surface and an edge in both themes. why: docs/foundations.md#elevation */
  --field-bg: var(--surface);
  --field-edge: var(--border);
  --field-edge-hover: var(--border-strong);
  --control-edge: var(--border);

  /* How much of its own colour a tinted card mixes in. Dark mixes upward off a mid-grey
     card, so it can afford this much. why: docs/foundations.md#elevation */
  --card-tint: 9%;

  --text: #e9e7f0;
  --strong: #ffffff;
  --dim: #c6c2d6;
  /* Picked against the TOP of the ladder above, not against the page: #948fa8 cleared the
     two floating steps by hundredths. Same violet-grey, fourteen steps up every channel.
     why: docs/foundations.md#elevation */
  --muted: #a29db6;

  /* The paint of a control that is off. NOT an opacity: `opacity` is a group property,
     so it fades label and box toward the ground TOGETHER — a disabled primary button
     measured 1.48:1 that way. These three are aliases that composite predictably, the
     ink read on the surface beside it. Held by guidelines/accessibility-floor.test.js.
     why: docs/foundations.md#colour-and-contrast */
  --disabled-ink: var(--muted);
  --disabled-surface: var(--surface);
  /* One rung below the hairline, so an off box is not the live box with quieter words
     in it: dark answered both with --border. 1.16:1 on the card against the live
     1.27:1, and as far down as the headroom goes. #564
     why: docs/foundations.md#colour-and-contrast */
  --disabled-border: var(--surface-3);
  /* The ink of a disabled control that paints no box of its own — a ghost button. With
     no surface beside it, it is read on whatever is behind it, so it is set to clear the
     floor on the dullest ground there is (--surface-3). #273
     why: docs/foundations.md#colour-and-contrast */
  --disabled-ink-bare: #a39eb7;

  /* Lifted from #9b5dff, which cleared the flat surfaces and failed on its own wash over
     a card; the value was already in the ramp. --ring-color is var(--accent) and follows by
     reference. Held by stories/accent-contrast.test.js. #157.
     why: docs/foundations.md#colour-and-contrast */
  --accent: #b479ff;
  --accent-strong: #7c3aed; /* button bg — white text clears WCAG AA at 5.70:1 */
  --accent-contrast: #ffffff;

  /* Ink that reads on a SIGNAL colour once that colour becomes a fill — the glyph in a
     success circle, or on a toast's status circle. One near-black ink clears all five in
     dark; danger keeps its own token because LIGHT still needs one.
     why: docs/foundations.md#colour-and-contrast */
  --signal-contrast: #0c0c0c;
  --danger-contrast: var(--signal-contrast);

  --glow-green: rgba(152, 255, 143, 0.16);
  /* Dropped from 0.18: the wash, not the surface beneath it, is what put --accent under
     AA. Re-tinted from the new --accent, which signal-contrast.test.js requires. #157. */
  --glow-purple: rgba(180, 121, 255, 0.12);
  --glow-cyan: rgba(32, 220, 245, 0.14);
  --glow-pink: rgba(233, 124, 165, 0.16);

  /* Status-chip paint — the ink + fill of a badge / pill. Dark tints with the signal's
     own glow; light needs a solid, deepened pair, which is why these are a token pair. */
  --chip-success-ink: var(--green);
  --chip-success-fill: var(--glow-green);
  --chip-warn-ink: var(--amber);
  --chip-warn-fill: color-mix(in srgb, var(--amber) 15%, transparent);
  /* Not --pink: that reads 4.23:1 on this fill over a floating panel, under the 4.5:1 badge
     floor. Same hue lifted toward white — 8.64 page / 7.02 card / 6.30 panel. The signal
     and the solid-toast pair keep --pink. why: docs/foundations.md#colour-and-contrast, #453 */
  --chip-danger-ink: #f5aec6;
  --chip-danger-fill: var(--glow-pink);
  --chip-info-ink: var(--cyan);
  --chip-info-fill: var(--glow-cyan);
  /* The fill of a chip with no status to carry. The themes match on SEPARATION, not on
     alpha — 12% here is 1.22:1 off the card, 15% in light is 1.23:1 — because --muted is
     a light violet-grey in dark and a mid slate in light.
     why: docs/foundations.md#colour-and-contrast, #453 */
  --chip-neutral-fill: color-mix(in srgb, var(--muted) 12%, transparent);

  /* Solid signal surfaces — a status that has stopped being ink and become the FILL (a
     solid toast). Fill and ink are ONE pair, never two independent picks: the fill is the
     status at this theme's extreme and the ink the pole opposite it, so a single ink
     clears all five. --muted is already its own fill-strength form. See #131, #149. */
  --signal-solid-ink: var(--signal-contrast);
  --signal-solid-success: var(--green);
  --signal-solid-danger: var(--pink);
  --signal-solid-warn: var(--amber);
  --signal-solid-info: var(--cyan);
  --signal-solid-neutral: var(--muted);

  /* Person hues: the eight fills an Avatar takes from a hash of the person's key. Fixed
     values and not accent tints, so a person keeps one hue under every accent and in
     every app. Each is an existing kit value for this theme, and --signal-solid-ink
     holds 4.5:1 on all eight. why: docs/components.md#avatar */
  --person-0: #bd8cff;
  --person-1: #5ab0ff;
  --person-2: #20dcf5;
  --person-3: #3ad9a0;
  --person-4: #98ff8f;
  --person-5: #ffcf6a;
  --person-6: #ff8a5c;
  --person-7: #f5aec6;

  /* DEPRECATED since #295: no surface below the floating step casts, and the floating
     step reads --elev-drop rather than any of these. Published still, so a consumer
     reading one gets nothing rather than an unresolved var(), and a consumer who wants a
     cast shadow sets them. Nothing in src/ reads them.

     A transparent shadow, not `none`, because these are read in a LIST — a surface's
     edge and its drop are two layers of one declaration — and `none` is valid only
     alone, so it makes the whole declaration invalid and takes the layers beside it
     with it. `0 0 #0000` composes. why: docs/foundations.md#elevation */
  --shadow-sm: 0 0 #0000;
  --shadow-md: 0 0 #0000;
  --shadow-lg: 0 0 #0000;
  --shadow-seg: 0 0 #0000;
  --shadow-card: 0 0 #0000;
  /* ONE band, drawn as a real OUTLINE, and no halo. Artur took the halo off on #578
     after #557 drew a scroll region's band without one. An outline leaves its offset
     UNPAINTED, so the 1px between the control and the band is whatever surface the
     control is already standing on — which is what retired --ring-gap and the
     per-surface recomposition behind it, and what leaves forced colors a real outline
     to repaint instead of a transparent stand-in.
     why: docs/foundations.md#the-focus-ring */
  --ring-width: 2px;
  --ring-color: var(--accent);
  --ring-gap-width: 1px;
  --ring: var(--ring-width) solid var(--ring-color);
  --ring-offset: var(--ring-gap-width);
  /* What a scroll region inside a surface takes: the same band, drawn inward rather
     than outward, because an inset shadow is painted under the box's own children and
     a table scrolled under one erases it. Only the offset differs. Chosen by Artur on
     #531 round r30. why: docs/foundations.md#the-focus-ring */
  --ring-scroll: var(--ring);
  --ring-scroll-offset: calc(-1 * (var(--ring-gap-width) + var(--ring-width)));

  /* The ink a cast shadow is made of, and the specular white that reads as gloss on a
     raised surface. Effects mix these instead of writing rgba(). */
  --shadow-ink: #000000;
  --sheen: #ffffff;

  /* The drops of the floating treatment, in Primer's --shadow-floating-* order:
     the inner half of the two-step edge, then these. The line is NOT in this
     token and cannot be — a var() inside a custom property is substituted on the
     element that DECLARES it, so an --elev-edge read here resolves at :root and
     nothing below could re-point it. A floating surface writes the pair itself:
       box-shadow: inset 0 0 0 1px var(--elev-edge, var(--float-edge-inner)), var(--elev-drop);
     Dark spends 62% / 50% of the ink and reaches 1.20 at the drop's core, having
     nowhere to go on a near-black page. why: docs/foundations.md#elevation */
  --elev-drop:
    0 14px 30px -12px color-mix(in srgb, var(--shadow-ink) 62%, transparent),
    0 3px 9px -4px color-mix(in srgb, var(--shadow-ink) 50%, transparent);

  /* The ladder's two resting rungs, which only light climbs. Transparent here and
     not `none`, for the reason the deprecated --shadow-* tokens are: these are read
     in a layer list, and `none` is valid only alone — it would invalidate the whole
     declaration and take the layers beside it with it. why: docs/foundations.md#elevation */
  --elev-rest: 0 0 #0000;   /* a card */
  --elev-rail: 0 0 #0000;   /* the shell's rail, cast sideways */

  /* Backdrop that dims the page behind an overlay (drawer, modal, composer). */
  --scrim: rgba(0, 0, 0, 0.58);

  /* Accent gradient stops (hero headline, marketing) — overridden per sub-theme.
     --grad-from is pinned to a literal rather than tracking --purple-light, which #157
     moved up a step; every --grad-from in accents.css is a literal for the same reason. */
  --grad-from: #9b5dff;
  --grad-to: var(--cyan);
}

/* ============================================================================
 * LIGHT THEME — deck light palette from viz/account.mjs
 * ========================================================================== */
:root[data-theme="light"] {
  color-scheme: light;

  --purple: #6a2dcc;
  --purple-light: #6a2dcc;
  --purple-mid: #7a3be0;
  --cyan: #0c8fa8;
  --green: #1c8a2c;
  /* Deeper than the dark pink for the same reason dark's is lighter: the wash under it
     is the page, so the ink comes down to meet it. Down a second step at #295, which
     took the page off white. See issues #131 and #295. */
  --pink: #a92d59;
  --amber: #b5730a;

  /* The same ladder, run the only way light can run it: nothing is brighter than
     white, so light moves DOWN from it. #307 ran it downwards from the CARD, which
     put the page at #eef0f5 and left the card at #f8f9fc — a grey canvas under a
     surface only 1.08:1 above it, so the grey was what the screen read as and the
     card never arrived. The card takes the white instead, and the page is the
     lightest ground that still leaves it a step: 1.11:1, on a page lighter and less
     blue than the one it replaces. Light spends its white on the surface you read
     ON, and separates the panel that floats over it by role — its two-step edge and
     its drop — rather than by a rung it has nothing left to pay for. See issue #448.
     why: docs/foundations.md#elevation */
  --bg: #f2f3f6;
  --table-bg: #ffffff;
  --table-code-bg: var(--bg);
  --wash-code-bg: var(--surface);
  --surface-2: #e9ecf3;     /* non-text sunken marks and tracks */
  --surface: #ffffff;       /* the card */
  --bg-elevated: #ffffff;   /* FLOATING — menus, panels, drawer, modal, toasts */
  --surface-3: #eef0f5;     /* non-text quiet fills */
  --seg-active-bg: #ffffff; /* white pill raised above the grey track in light */
  --control-knob: #ffffff;
  --border: #e4e7ee;
  --border-strong: #cdd2dc;

  /* Light draws each LEVEL with one line and a faint short shadow. The line is half
     way between --border and --border-strong. Decided on #730.
     why: docs/foundations.md#elevation */
  --level-line: color-mix(in srgb, var(--border) 50%, var(--border-strong));
  --card-edge: var(--level-line);
  --rail-edge: var(--level-line);
  --float-edge: var(--level-line);
  --float-edge-inner: transparent;
  --modal-edge: var(--float-edge);

  /* Light draws a field with its EDGE, because since #448 it has no well left to draw it
     with: a card and a panel are both white, the sunken step falls two rungs under either,
     and --border on it measures 1.047:1. why: docs/foundations.md#elevation */
  --field-bg: var(--surface);
  --field-edge: var(--border-strong);
  --field-edge-hover: var(--muted);
  --control-edge: var(--border-strong);

  /* Light mixes DOWN from white, so tint costs lightness: 5% is the most a card can spend
     and stay above the page. why: docs/foundations.md#elevation */
  --card-tint: 5%;

  --text: #1a1e27;
  --strong: #0c0e13;
  --dim: #3a404b;
  --muted: #5c6270;

  /* Disabled text stays on the card surface; its ink marks the unavailable state. */
  --disabled-ink: var(--muted);
  --disabled-surface: var(--surface);
  /* The hairline, where dark takes the rung under it: light's field edge is already
     --border-strong, so the two states read 1.52:1 and 1.24:1. #564 */
  --disabled-border: var(--border);
  --disabled-ink-bare: #585e6c;

  --accent: #6a2dcc;
  --accent-strong: #6a2dcc; /* already dark enough for white text */
  --accent-contrast: #ffffff;

  --signal-contrast: #0c0c0c;
  --danger-contrast: #ffffff;

  /* Re-tinted from --green; it was rgba(30, 150, 50, .1), a colour that exists nowhere
     else in the kit while the other three light glows are exact tints of their own token.
     The wash over white moves at most two levels on a channel and no verdict moves with
     it. Gated for all four glows in stories/signal-contrast.test.js. */
  --glow-green: rgba(28, 138, 44, 0.1);
  --glow-purple: rgba(106, 45, 204, 0.09);
  --glow-cyan: rgba(12, 143, 168, 0.1);
  --glow-pink: rgba(169, 45, 89, 0.1);   /* an exact tint of --pink above */

  /* Solid chip pairs for the light app. Each ink is deepened past its signal hue so 11px
     chip text clears WCAG AA on its own pale fill, and on the soft toast's wash, which
     #131 gave the same ink. Three came down again at #295 with the page; danger did not
     need to. */
  /* Success is held at the 7:1 body aim rather than the 4.5:1 floor: 7.17:1 on its own
     fill, 8.33:1 on the card. Was #1c7034 at 5.29:1. The fill did not move.
     why: docs/foundations.md#colour-and-contrast, #453 */
  --chip-success-ink: #145a26;
  --chip-success-fill: #dff3e4;
  --chip-warn-ink: #825900;
  --chip-warn-fill: #fbedd2;
  --chip-danger-ink: #b7295f;
  --chip-danger-fill: #fbe0ea;
  /* Info was the one signal family without a pair, so the info badge painted --cyan on
     --glow-cyan over white and missed AA. This pair sits in the band the other three
     already occupy. See issue #131. */
  --chip-info-ink: #096a7c;
  --chip-info-fill: #ddeff3;
  /* See the dark block for why the two alphas differ. */
  --chip-neutral-fill: color-mix(in srgb, var(--muted) 13%, transparent);

  /* Light runs the same rule the other way. The signals are mid-tone here, so NO ink
     rescues them and the fill is what has to move: it takes the deepened form the chip
     pair already carries, and white clears every one. A future status supplies one
     --signal-solid-* value dark enough for white and inherits the ink. See #131, #149. */
  --signal-solid-ink: #ffffff;
  --signal-solid-success: var(--chip-success-ink);
  --signal-solid-danger: var(--chip-danger-ink);
  --signal-solid-warn: var(--chip-warn-ink);
  --signal-solid-info: var(--chip-info-ink);

  /* Person hues, light: the deepened forms, so white holds on every one. */
  --person-0: #6a2dcc;
  --person-1: #005ab4;
  --person-2: #096a7c;
  --person-3: #076c48;
  --person-4: #145a26;
  --person-5: #825900;
  --person-6: #a8370c;
  --person-7: #b7295f;
  --signal-solid-neutral: var(--muted);

  /* Deprecated and unread — see the dark block. */
  --shadow-sm: 0 0 #0000;
  --shadow-md: 0 0 #0000;
  --shadow-lg: 0 0 #0000;
  --shadow-seg: 0 0 #0000;
  --shadow-card: 0 0 #0000;
  /* No --ring here. :root's band is var(--accent), and light re-points --accent. */

  --shadow-ink: #1e1e32;
  --sheen: #ffffff;

  /* THE LIGHT LADDER. Three rungs, each two layers: a wide faint one and a short one.
     Each layer is offset on one axis, blurred at least twice as wide as it is offset,
     and held in by a negative spread. None is a glow — a glow is a zero-offset layer of
     the signal's own colour. Each rung is short and faint, because the level's line
     marks the edge and the rung only adds lift. Decided on #730.
     why: docs/foundations.md#elevation */
  --elev-rest:
    0 2px 6px -1px color-mix(in srgb, var(--shadow-ink) 6%, transparent),
    0 1px 3px -1px color-mix(in srgb, var(--shadow-ink) 4%, transparent);
  --elev-rail:
    3px 0 8px -3px color-mix(in srgb, var(--shadow-ink) 6%, transparent),
    1px 0 3px -1px color-mix(in srgb, var(--shadow-ink) 4%, transparent);
  --elev-drop:
    0 12px 32px -12px color-mix(in srgb, var(--shadow-ink) 16%, transparent),
    0 1px 8px -3px color-mix(in srgb, var(--shadow-ink) 9%, transparent);

  --scrim: rgba(20, 22, 40, 0.38);

  --grad-from: var(--purple-light);
  --grad-to: var(--cyan);
}

/* ============================================================================
 * WIDTHS BELOW THE PAGE — the box, and the line. Two scales, and one rule for
 * choosing between them: THE UNIT SAYS WHICH SCALE YOU ARE ON.
 *
 *   a box that holds a COMPONENT   ->  --panel-*   (px)
 *   a box that holds a LINE        ->  --prose-*   (ch)
 *
 * Both are theme-invariant, so they sit outside the palette blocks.
 * why: docs/foundations.md#boxes-below-the-page
 * ========================================================================== */
:root {
  /* -- Panel widths -------------------------------------------------------
   * Not a new scale: the drawer has shipped sm/md/lg at these three values, and
   * confirm, the auth card and the toast each wrote one out again (#208). */
  --panel-sm: 320px;
  --panel-md: 420px;
  --panel-lg: 560px;

  /* -- Prose measures -----------------------------------------------------
   * ch resolves against the font-size of the element it is DECLARED on, so a step
   * goes on the paragraph itself, never on a wrapper holding two type sizes. The
   * four steps are the reading band (44–72ch), named for what is being read:
   *   caption  one or two sentences under a glyph, centred
   *   lede     the line under a title
   *   body     a left-aligned column of copy
   *   dense    reference prose set below 13px, where the band runs wider
   * --prose-display is NOT a measure — it is where a display headline rags. */
  --prose-display: 14ch;
  --prose-caption: 44ch;
  --prose-lede: 54ch;
  --prose-body: 62ch;
  --prose-dense: 72ch;
}

/* An inline code chip is text on a chip, so #455 leaves it two grounds and no grey: the
 * page and the card. It cannot read the one it is on — a var() inside a custom property is
 * substituted on the element that DECLARES it — so the painted container hands it the one
 * it is not using itself, and the chip keeps a step wherever it is written. The page hands
 * over the card below; every painted container hands over the page, in the recipe under it.
 * Held by stories/code-chip.test.js. why: docs/foundations.md#elevation */
:root { --code-bg: var(--surface); }

/* Every painted container hands an inline code chip the page. One recipe keeps surface
 * propagation cheap and consistent. The ring is not in this list since #578: an outline
 * paints no gap of its own, so a focused control needs nothing handed down to it. */
.amenu,
.dtsw,
.rx-modal,
.ui-app__rail,
.ui-auth__card,
.ui-callout,
.ui-card,
.ui-card--accent,
.ui-card--live,
.ui-cmdk__panel,
.ui-confirm__panel,
.ui-drawer__footer,
.ui-drawer__panel,
.ui-dropdown__panel,
.ui-fbcomposer,
.ui-filter-bar__chip,
.ui-footer--app,
.ui-seg,
.ui-snippet,
.ui-snippet--reveal,
.ui-sx,
.ui-table,
.ui-table-scroll,
.ui-table--sticky thead th,
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
.ui-table--zebra tbody tr:nth-child(even) td,
.ui-toast,
.ui-toast--soft,
.ui-toast--outline,
.ui-toast--solid,
.vsw__menu {
  --code-bg: var(--bg);
}

/* The two painted grounds that are not a plain card, and what each has left to hand over.
 *
 * A table paints the page in dark and white in light and follows its card when it is in
 * one, so its hand-off travels with --table-bg as a token pair (src/styles/table.css
 * re-points both). A TINTED surface mixes its colour INTO the card, so the card is the
 * surface it still has: light mixes the tint down from white, which moves a tinted card
 * toward the page and leaves the page 1.02 away, while the card it is a variant of stays
 * 1.07-1.14 off in both themes. Measured in stories/code-chip.test.js. */
.ui-table,
.ui-table-scroll,
.ui-table--sticky thead th,
.ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
.ui-table--zebra tbody tr:nth-child(even) td { --code-bg: var(--table-code-bg); }
/* A neutral hovered row gives an inline code chip the card surface. The step from
 * --surface-2 clears 1.1:1 in both themes, even when the table follows a card. */
.ui-table--hover tbody tr:hover:not(.is-target),
.ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th),
.ui-table-scroll > .ui-table--hover tbody tr:hover:not(.is-target) > :is(td, th) {
  --code-bg: var(--surface);
}
.ui-card--accent,
.ui-card--live,
.ui-snippet--reveal { --code-bg: var(--surface); }

/* A wash is not a rung: it is a layer the kit paints OVER one, and it paints behind a chip
 * rather than under it, so the chip's ground moves and the chip does not. These five take
 * caller markup — callout() and the success panel hand their body straight through — so a
 * chip inside one is ordinary product markup rather than a shape anybody hand-places. */
.ui-callout--info,
.ui-callout--success,
.ui-callout--warn,
.ui-callout--danger,
.ui-success { --code-bg: var(--wash-code-bg); }

/* React badges and pills accept inline code on opaque or translucent status fills. */
.ui-badge,
.ui-badge--live,
.ui-badge--soon,
.ui-badge--info,
.ui-badge--warn,
.ui-badge--danger,
.ui-badge--archive,
.ui-badge--success,
.ui-badge--pending,
.ui-badge--neutral,
.ui-pill,
.ui-pill--live,
.ui-pill--soon { --code-bg: var(--wash-code-bg); }
