/* Design tokens — the console's theme contract (Appearance theming, 2026-09-22).
 *
 * Five layers, on purpose:
 *   1. Palette          (--violet-500 …)   raw values. No component reads these.
 *   2. Theme inputs     (--paper-* / --ramp-*)  the chosen light theme's paper ladder and the
 *                       chosen dark theme's 10-step ramp. One set is live at a time per mode.
 *   3. Mode             color-scheme from data-mode; light-dark() then resolves layer 4.
 *   4. Semantic         (--chrome-bg, --surface, --ink …)  what components use, declared ONCE
 *                       as light-dark(<light input>, <dark input>).
 *   5. Density          (--sidebar-w, --pane-pad-* …)  the sizes that tighten on a laptop, each
 *                       written once around one switch (--dc). See section 5.
 *
 * The root carries the person's appearance, rendered server-side (layout.jte):
 *   <html data-mode="light|dark|system"
 *         data-light-theme="blink|haze|wash"
 *         data-dark-theme="obsidian|midnight|espresso"
 *         data-workspace-flavor="skills|social|platform|org|msp|none"
 *         data-density="auto|comfortable|compact">
 * data-mode picks the branch of every light-dark(); the two theme attributes pick the inputs.
 * No JavaScript is involved — "system" is color-scheme: light dark and the browser resolves it.
 * An absent attribute is the default (light · Blink · Obsidian), so a frame rendered before the
 * preference is known is already correct.
 *
 * The theme-variant selectors below are deliberately written without a :root prefix: the
 * Appearance chips put data-light-theme / data-dark-theme on a button, and the same rule then
 * scopes that theme's inputs to the chip so its swatch previews the theme (account/settings/appearance.jte).
 *
 * The chrome (sidebar + stage head) is dark in every mode — the light-chrome variant is retired.
 * Rule: a component never holds a raw color. Add a semantic token instead.
 *
 * Browser floor: this layer assumes light-dark() (Chrome 123 · Safari 17.5 · Firefox 120) and
 * relative colour syntax, oklch(from …) (Firefox 128, the last engine to ship it). No @supports
 * fallback is provided — by decision, an engine below that floor is out of support rather than
 * served a second token layer (Appearance theming, 2026-09-22).
 */

:root {
  /* ---------- 1. palette ---------- */
  --white: #ffffff;
  --ink-950: #1a1033;
  --ink-900: #241d3d;
  /* the prototype's two middle ink steps, verbatim (proto 871: --ink-2 / --ink-3) — the console
     had neither, so table body text and a quiet action both fell back to a neighbour */
  --ink-800: #3f3a52;
  --ink-700: #5b5570;
  --ink-500: #6f6a86;
  --ink-300: #9b96ad;
  /* the dark chrome's running text ink, the prototype's --chrome-ink (proto 880) */
  --lilac-200: #d6d3ea;
  /* the dark chrome's two muted inks */
  --lilac-300: #b7b1d6;
  --lilac-350: #9a92c0;   /* the prototype's --chrome-muted (decoded 880): between lilac-300 and lilac-400 */
  --lilac-400: #8f88b3;
  /* the two workspace section inks: each workspace accent desaturated until it reads as a label
     rather than a highlight (prototype WS[…].section — proto 20022-20023) */
  --clay-400: #c09a80;    /* Skills */
  --lilac-450: #8a82b0;   /* Social */
  --violet-600: #7c5cf0;
  --violet-500: #8b5cf6;
  --violet-100: #f0eafd;
  --violet-50: #f5f0fe;   /* one step lighter than --violet-100: the quietest accent fill (proto 3287) */
  /* the focus/hover ring a quiet control wears: the prototype's --ring on paper (proto 899), and the
     same ring on dark paper (proto 20244: the accent's hue at 50% saturation, 40% lightness) */
  --violet-300: #c9b8f5;
  --violet-800: #493399;
  /* the dark side of the accent: fixed, not derived from the workspace (prototype consolePalette) */
  --violet-400: #876af1;   /* --accent on dark paper */
  --violet-950: #1d1636;   /* --accent-soft on dark paper */
  --purple-600: #9333ea;
  --purple-500: #9c40ed;   /* the gradient's far stop on dark paper */
  --orange-500: #f97316;
  --hot-600: #c2440f;
  --hot-400: #f28454;
  --hot-100: #fdeee2;
  --green-600: #16a34a;
  --green-400: #5de991;
  --amber-700: #b45309;
  --amber-400: #f69851;
  --red-600: #dc2626;
  --red-400: #e56161;
  --blue-500: #3b82f6;
  --blue-400: #5d83e9;
  /* the two billing-model pairs the workspaces directory adds, verbatim (proto 24580: Seats #1d4ed8 on
     #e8f0fe, Ecosystem #0f766e on #d5f3ec). Audience is the console's own violet and needs no palette
     step of its own. */
  --blue-700: #1d4ed8;
  --blue-100: #e8f0fe;
  --teal-700: #0f766e;
  --teal-100: #d5f3ec;
  /* the two colours the member avatars add to the palette, verbatim (proto 24720) */
  --teal-500: #14b8a6;
  --rose-600: #e11d48;
  --sky-500: #38bdf8;
  /* the Partner tier's chip, verbatim (proto 21480: TIER.ink #0369a1 on TIER.tint #e0f2fe) */
  --sky-700: #0369a1;
  --sky-100: #e0f2fe;
  --navy-800: #1e3a8a;
  --pink-500: #ec4899;
  --linkedin-600: #0a66c2;
  --night-800: #17122d;
  --plum-900: #271244;
  /* the chrome gradient's two stops, verbatim (prototype consoleThemes().chromeLight; proto 20729 · 879) */
  --chrome-grad-a: #170d33;
  --chrome-grad-b: #241245;
  --teal-900: #0e2f45;
  /* the person card's avatar ground, the prototype's avWash (proto 26025 · 1683) */
  --peach-100: #fde8d0;
  /* The level gold: the prototype's LEVEL_COLOR.platform verbatim (proto 22290; "Sidebar to the prototype",
     2026-09-29, decision 2). The Blinklink row, the platform scope and the --platform-* family below sit on it. */
  --gold-500: #c9962b;
  /* The gold's two text steps (WCAG AA 4.5:1 for every text use of the gold, "Sidebar to the prototype",
     2026-09-29): the level colour is a fill, border and header colour, and as text on its own soft ground it
     falls under AA, so text takes the gold lifted for dark paper and a step below the chip's ink for paper
     (--platform-ink, --platform-ink-soft below). */
  --gold-400: #e2a83a;
  /* the system tier's chip, verbatim (proto 21479: TIER.ink #8a5f0b on TIER.tint #f7ead0) */
  --gold-700: #8a5f0b;
  --gold-800: #7a5309;
  --gold-100: #f7ead0;

  /* The Feeds screens' palette ("Feeds click-through", 2026-09-29), verbatim from the prototype (proto 907-984 and
     the inline literals of viewFeeds / create-feed / customize-feed / feed-settings, decoded 1766-15810). Named for the
     hue; the roles they play are the --fd-* / --feed-tone-* / --mock-* tokens in section 4. */
  --green-500: #22c55e;     /* --ok-2: the live signal and a whole day's uptime bar */
  --green-800: #166534;     /* --icon-green: the Component Preview's grid glyph */
  --amber-500: #f59e0b;     /* the waiting dot (feedStateDefs.setup) and a dipped day */
  --amber-600: #d97706;     /* --warn-9: the Product funnel feed */
  --amber-900: #8a6a2f;     /* --warn-7: the "Platform needed" note's text */
  --red-500: #ef4444;       /* a failed day in the uptime bars; the last seed colour */
  --red-700: #b91c1c;       /* --bad-3: the danger zone's heading */
  --red-900: #8f2424;       /* --bad-4: the deactivated banner's text */
  --rosewood-500: #8a6262;  /* --bad-5: the danger zone's sentence */
  --indigo-500: #6366f1;    /* a seed colour (17628) */
  --teal-600: #0d9488;      /* --teal: the Article funnel feed and the Video Grid rail glyph */
  --pink-600: #db2777;      /* --pink: the Related funnel feed */
  --pink-400: #d977a6;      /* the Playback rail glyph (28782) */
  --ochre-500: #d98a2b;     /* the Player Menu rail glyph (28783) */
  --azure-500: #2f7fe0;     /* --icon-blue: the Shareability rail glyph (28784) */
  --violet-700: #6d3ee0;    /* --accent-deep */
  --slate-400: #8b8fa3;     /* --icon: the search and globe glyphs */
  --ink-200: #b6b2c4;       /* --dim-5: a disabled grey — chevrons, an off frame's glyph, the uptime scale */
  --lilac-110: #edecf3;     /* --fill-11: a frame that is not live */
  --lilac-120: #e5e2ee;     /* --toggle-off-2: Save Changes before anything changed; the mock's captions */
  --lilac-150: #e6e3f2;     /* the label ink on the dark tiles and the snippet's Copy */
  --lilac-250: #c9c4d8;     /* the Configure platform card's sentence */
  --lilac-500: #9b8fc4;     /* --muted-2: "Generative unlocks" */
  --mint-100: #dff3f0;      /* the Create Feed promo wash's first stop (14632) */
  --orchid-100: #f2e8fb;    /* …and its second */
  --night-900: #17141f;     /* --surface-dark-2: the embed snippet's ground */
  --smoke-200: #e2e2ea;     /* the promo's placeholder mark (14636) */
  /* the Configure panel's platform card, verbatim (1987: 120deg, #0c0a12 30%, #2b1a10 75%, #c2410c 130%) */
  --ember-950: #0c0a12;
  --ember-900: #2b1a10;
  --ember-600: #c2410c;
  /* the share channels' brand dots (efShareOpts 29285): Email is the console violet, LinkedIn --linkedin-600 */
  --facebook-500: #1877f2;
  --whatsapp-500: #25d366;
  --x-900: #17141f;
  --reddit-500: #ff4500;
  --teams-400: #8b9dd6;
  /* Round 2 ("Feeds as the workspace's home", 2026-09-29): the Platform panel, What is it?, Manage Whitelist */
  --green-350: #4ade80;     /* the Platform tab's on-disc, first stop (--ok-grad) */
  --mint-50: #e9f9ef;       /* --ok-ring-2: the ring round the on-disc */
  --lilac-115: #eceaf3;     /* --hairline-3: the off-disc */
  --lilac-105: #f6f5fa;     /* --hover-12: the ring round it */
  --lilac-130: #f0eef6;     /* --fill-2: a whitelist row's globe tile */
  --ochre-700: #b7900f;     /* --warn-10: a locked module's glyph and the locked note */
  --cream-100: #f0e3bd;     /* --warn-line-8: a locked module's edge */
  --cream-50: #fffdf5;      /* a locked module's wash, first stop (28434) */
  --cream-75: #fbf6e4;      /* …and its second */
  --cream-90: #fbf3dd;      /* a locked module's glyph tile */
  --rosewood-600: #8a5555;  /* --bad-8: the Remove page confirm's sentence */
  --rose-50: #fdf7f7;       /* --bad-bg-3: the danger zone's and the Remove confirm's wash */
  --rose-150: #f3d4d4;      /* --bad-line-3: the Remove confirm's edge */
  --steel-300: #a9b6d9;     /* the LMS hero's mortarboard (2201) */
  /* What is it?'s dark side, verbatim (16561: 165deg, #241f33 0%, #141119 60%, #1d1426 100%) */
  --dusk-800: #241f33;
  --dusk-950: #141119;
  --dusk-900: #1d1426;
  --slate-450: #767f97;     /* the prototype's placeholder ink (869): every Feeds and Conversions field and search (--fd-placeholder) */
  --violet-110: #efe9fc;    /* --accent-chip: Whitelist (N), the plan chip and a selected Platform tab (1783 · 1975 · 28419) */

  /* The Conversions screens' palette ("Conversions click-through", 2026-09-30), verbatim from the prototype (proto 888-946);
     the roles they play are the --cv-* tokens in section 4. */
  --mint-150: #e3f5ea;      /* --ok-bg-2: the form's section tiles and Create's Dynamic tile (2558 · 25969) */
  --lilac-160: #d9d7e2;     /* --fill-10: the preview's phone and the dialog's preview well (2645 · 2729) */
  --lilac-260: #c9c6d4;     /* --edge-3: a swatch with no bar yet, and Show icon off (28257 · 28286) */

  /* The Uploads screens' palette ("Uploads click-through", 2026-09-30), verbatim from the prototype (proto 884-986, 17473,
     22537, 8253, 23810); the roles they play are the --upl-* tokens in section 4. */
  --lilac-125: #e6e4ee;     /* --fill-3: the empty queue's disc (7430) */
  --ink-600: #4b465e;       /* --ink-5: the glyph on it (7431) */
  --lilac-270: #c6c2d6;     /* --dim-7: the review panel's pager discs (7539) */
  --lilac-265: #c9c4dc;     /* --dim-4: Send back before a reason or a note (29885) */
  --lilac-420: #8b86a0;     /* --icon-2: the dialogs' lines (7786 · 7806) */
  --lilac-60: #fbfaff;      /* --hover-4: Manage Category's footer (8202) */
  --violet-40: #faf8ff;     /* --hover: the upload form's drop zone (8089) */
  --violet-200: #dcd0fb;    /* --accent-tint: the drop zone's picture (8090) */
  --cream-110: #fdf3e3;     /* --warn-bg: Edit, Request revision and the Revision card (7598 · 7769 · 7750) */
  --cream-200: #f3dfb3;     /* --warn-line: their edges (7750 · 7769) */
  --rose-100: #fdecec;      /* --bad-bg: the bin and Custom Source's tile (7601 · 7574) */
  --rose-200: #fecaca;      /* --bad-line: the Reported card's edge and Delete upload's (7735 · 23680) */
  --rose-40: #fdf6f6;       /* --bad-bg-7: the Reported card (7735) */
  --rose-180: #f6c6c3;      /* --bad-line-7: Manage Category's Remove (8206) */
  --plum-700: #4b3a72;      /* a tile with no poster yet, the second stop (dmQueueRow 17473) */
  --slate-700: #31404f;     /* the phone once a file is attached (assetGrads[0], 22537) */
  --slate-950: #131c24;
  --steel-350: #a8bfd0;     /* the chosen CTA's link card thumbnail (8253) */
  --steel-700: #4d6a83;
  /* the seven tag pastels (uplPastels 23810) and their dark-paper steps (TH.pastel: the hue at 12–22% saturation and 19%
     lightness, 21108) */
  --pastel-yellow: #fdeec3;   --pastel-yellow-dark: #3b3626;
  --pastel-teal: #d5f0ea;     --pastel-teal-dark: #263b36;
  --pastel-blue: #d9e9f9;     --pastel-blue-dark: #26303b;
  --pastel-peach: #fde3c3;    --pastel-peach-dark: #3b3226;
  --pastel-pink: #f9d6e0;     --pastel-pink-dark: #3b262c;
  --pastel-green: #dcf2cf;    --pastel-green-dark: #2e3b26;
  --pastel-lavender: #e6e0f8; --pastel-lavender-dark: #2b263b;

  /* The Assets screens' palette ("Assets click-through", 2026-09-30), verbatim from the prototype (proto 884-986, 7113-7355,
     24005 · 24025-24034); the roles they play are the --as-* tokens in section 4. */
  --cyan-500: #06b6d4;      /* three of the editor's twelve feed colours (feedIconColors, 24005) */
  --lime-500: #84cc16;
  --purple-450: #a855f7;
  --indigo-600: #4f46e5;    /* the Social platform feed's frame, second stop (24034) */
  --lilac-140: #efedf6;     /* --fill-8: Added and the Manual chip (22880 · 22824) */
  --lilac-230: #d5cdea;     /* --edge-5: the Icon button's edge and the empty playlist's dashes (7118 · 7286) */
  --lilac-240: #ddd9ea;     /* --edge-7: the LMS note's dashes (5639) */
  --lilac-55: #f8f6fd;      /* --hover-5: the search's × under the pointer (5417) */
  --mint-60: #eafaf0;       /* --ok-bg-3: the Live pill (5625 · 7275) */
  --mint-300: #a7e3c0;      /* --ok-line: its edge */
  --mint-120: #e6f7f4;      /* a tag row's chip ground (TH.tint('#0d9488', '#e6f7f4'), 22825) */
  --clay-100: #f3d8c8;      /* --warn-line-7: the platform feed's edge (24025) */
  --orchid-110: #f6e6f8;    /* the platform feed's ground, second stop (24026: 120deg, #fdeee2, #f6e6f8) */
  --brick-600: #b03a3a;     /* --bad-6: the prompt's Reset (7178) */
  --brick-700: #c0392b;     /* --bad-7: the row menu's Remove (7332) */
  --rose-45: #fdf3f2;       /* --bad-bg-4: Reset's ground */
  --rose-90: #fbe9e7;       /* --bad-bg-5: …under the pointer */
  --rose-110: #fdecea;      /* --bad-bg-6: Remove under the pointer */
  --rose-160: #f2cfcb;      /* --bad-line-5: Reset's edge */

  /* Blink paper — the platform's own light ladder, verbatim (prototype consoleThemes().blink).
   * The Blink light theme maps --paper-* onto these; see the stage block below for how the
   * console's semantic tokens now sit on it. */
  --blink-surface:    #ffffff;
  --blink-fill:       #f5f4f9;
  --blink-canvas:     #f1ecfa;
  --blink-hairline:   #eceaf5;
  --blink-hairline-2: #e7e4f2;
  --blink-divider:    #f3f1f9;
  --blink-hover:      #faf9fd;
  --blink-edge:       #d9d5ea;
  /* the pane wash's two far stops (prototype consoleLightPaper washA/washB; proto 19958) */
  --blink-wash-a:     #f3f0fb;
  --blink-wash-b:     #ece6fa;
}

/* ---------- 2a. theme inputs: the light paper ladder ----------
 *
 * Ten steps, lightest to darkest: the content card (surface), the row hover on it, the fill, the
 * divider between rows, the canvas the card sits on, the two hairlines, the control edge, and the
 * pane wash's two far stops — the 55% and 100% stops of --wash-grad-2, which fall either side of
 * the canvas (proto 20147). Ordered by lightness the ladder reads
 * surface > hover > fill > divider > hairline (proto 860-864).
 *
 * Blink is authored; Haze and Wash are recipes — they recast Blink's ladder in the current
 * workspace accent's hue, so a workspace colour that does not exist yet still gets a readable
 * light theme (prototype consoleLightPaper). Ported to oklch because oklch's L *is* perceptual
 * lightness: the prototype's luminance-parity correction (which darkened a tint that came out
 * brighter than the neutral it replaced) is unnecessary here — one L per step serves every hue.
 *
 *   lightness  the L of Blink's own step, minus the family's drop. The prototype's
 *              drop/minDrop/dropMax collapse to a constant in oklch: Haze ≈ 0.007 below Blink,
 *              Wash ≈ 0.022 below it (Wash is the family that has to read across a whole screen
 *              of white table rows).
 *   chroma     the recipe's tint (Haze 0.075, Wash 0.125) carried into oklch chroma at the same
 *              ratio: 0.020 and 0.034. HSL gives a hue-dependent chroma, oklch an even one.
 *   hue        h from --flavor, so the papers follow Skills, Social and every workspace colour
 *              still to come.
 *   surface    Haze leaves the card white (surfaceTint 0); Wash tints it (surfaceTint 0.04 →
 *              chroma 0.011), which is what makes Wash read as a theme rather than a shade.
 *   hover      the row hover is a near-surface step, so it carries half the family's chroma —
 *              the ratio the prototype's own recipes hold between hover and divider in both
 *              families (haze .0067/.0160, wash .0134/.0271 for Skills; the same for Social).
 *   wash-a/b   Blink's own washA/washB are L 0.961 / 0.936; each family takes the same drop it
 *              takes on every other step, so the wash keeps its place in the ladder
 *              (fill > wash-a > canvas > wash-b). Note this reads L ≈ .95/.93 for Haze and
 *              ≈ .94/.91 for Wash rather than one pair for both — one pair would put Wash's
 *              wash-a above its own fill and invert the ladder.
 */
:root,
[data-light-theme="blink"] {
  --paper-surface:    var(--blink-surface);
  --paper-fill:       var(--blink-fill);
  --paper-canvas:     var(--blink-canvas);
  --paper-hairline:   var(--blink-hairline);
  --paper-hairline-2: var(--blink-hairline-2);
  --paper-divider:    var(--blink-divider);
  --paper-hover:      var(--blink-hover);
  --paper-edge:       var(--blink-edge);
  --paper-wash-a:     var(--blink-wash-a);
  --paper-wash-b:     var(--blink-wash-b);
}

[data-light-theme="haze"] {
  --paper-surface:    var(--white);
  --paper-fill:       oklch(from var(--flavor) 0.962 0.020 h);
  --paper-canvas:     oklch(from var(--flavor) 0.944 0.020 h);
  --paper-hairline:   oklch(from var(--flavor) 0.933 0.020 h);
  --paper-hairline-2: oklch(from var(--flavor) 0.915 0.020 h);
  --paper-divider:    oklch(from var(--flavor) 0.955 0.020 h);
  --paper-hover:      oklch(from var(--flavor) 0.977 0.010 h);
  --paper-edge:       oklch(from var(--flavor) 0.879 0.020 h);
  --paper-wash-a:     oklch(from var(--flavor) 0.954 0.020 h);
  --paper-wash-b:     oklch(from var(--flavor) 0.929 0.020 h);
}

[data-light-theme="wash"] {
  --paper-surface:    oklch(from var(--flavor) 0.980 0.011 h);
  --paper-fill:       oklch(from var(--flavor) 0.948 0.034 h);
  --paper-canvas:     oklch(from var(--flavor) 0.928 0.034 h);
  --paper-hairline:   oklch(from var(--flavor) 0.916 0.034 h);
  --paper-hairline-2: oklch(from var(--flavor) 0.891 0.034 h);
  --paper-divider:    oklch(from var(--flavor) 0.940 0.034 h);
  --paper-hover:      oklch(from var(--flavor) 0.962 0.017 h);
  --paper-edge:       oklch(from var(--flavor) 0.860 0.034 h);
  --paper-wash-a:     oklch(from var(--flavor) 0.939 0.034 h);
  --paper-wash-b:     oklch(from var(--flavor) 0.914 0.034 h);
}

/* ---------- 2b. theme inputs: the dark ramps ----------
 *
 * The platform's own three dark palettes, verbatim (prototype consoleThemes().DARK). Ten steps
 * with fixed meaning, darkest first:
 *   0 canvas · 1 bg · 2 panel · 3 card · 4 pill · 5 line · 6 navy · 7 ink · 8 ink2 · 9 ink3
 * Obsidian is the default, so it is also the ramp the root carries with no attribute.
 */
:root,
[data-dark-theme="obsidian"] {
  --ramp-0: #0c0a10; --ramp-1: #131118; --ramp-2: #1a1622; --ramp-3: #211d2a; --ramp-4: #2d2837;
  --ramp-5: #332e3e; --ramp-6: #3d3849; --ramp-7: #f2f0f5; --ramp-8: #b6b2c0; --ramp-9: #8d8999;
}

[data-dark-theme="midnight"] {
  --ramp-0: #070b14; --ramp-1: #0d1220; --ramp-2: #131a2b; --ramp-3: #1a2235; --ramp-4: #232e45;
  --ramp-5: #2a3550; --ramp-6: #33405e; --ramp-7: #eef1f8; --ramp-8: #b3bccf; --ramp-9: #8290ab;
}

[data-dark-theme="espresso"] {
  --ramp-0: #0e0a08; --ramp-1: #16100d; --ramp-2: #1d1512; --ramp-3: #241b17; --ramp-4: #2f241f;
  --ramp-5: #362a24; --ramp-6: #41332c; --ramp-7: #f5f0ec; --ramp-8: #c4b8af; --ramp-9: #94887f;
}

/* ---------- 3. mode ----------
 * color-scheme is the only switch: every semantic token below is one light-dark() and the
 * browser picks the branch. "system" leaves the choice to the operating system with no JS.
 * No attribute = light, so an unauthenticated or pre-preference render is the console's default.
 */
:root { color-scheme: light; }
:root[data-mode="light"] { color-scheme: light; }
:root[data-mode="dark"] { color-scheme: dark; }
:root[data-mode="system"] { color-scheme: light dark; }

:root {
  /* ---------- 4. semantic: chrome (sidebar + stage header) ----------
   * Dark in every mode. In light it is the brand night; in dark it is the chosen ramp's two
   * darkest steps, so the chrome deepens with the stage instead of floating above it. */
  --chrome-bg: light-dark(var(--night-800), var(--ramp-0));
  /* The chrome the shell actually paints: one gradient down the whole sidebar + top bar, which is
   * why neither has a background of its own (proto 990 · 1509 · 1701). Light is the brand night, dark
   * is the chosen ramp's two darkest steps (proto 20889 · 20965). --chrome-bg stays the flat ground
   * behind it (body). */
  --chrome-grad: linear-gradient(160deg,
      light-dark(var(--chrome-grad-a), var(--ramp-0)) 0%,
      light-dark(var(--chrome-grad-b), var(--ramp-1)) 100%);
  /* The brand chrome as a fixed value — the prototype's chromeLight[0], never remapped by the
   * dark ramp. The Appearance light swatches show the chrome that is actually in force whatever
   * theme is chosen, so they must not follow the dark theme being previewed. One consumer:
   * .theme-dot (console.css). Now that the palette carries chromeLight[0] itself, it is that
   * value rather than the near-neighbour --night-800 the swatch used before. */
  --chrome-bg-fixed: var(--chrome-grad-a);
  --chrome-fg: light-dark(var(--white), var(--ramp-7));
  /* The sidebar's running text ink — what it passes down to anything that does not name an ink of its
     own, and the tenant line on the person card: the prototype's --chrome-ink (#d6d3ea light, the ramp's
     ink2 dark — proto 880 / 20966; used at 1509 and 1688). Between --chrome-fg and --chrome-fg-muted. */
  --chrome-fg-text: light-dark(var(--lilac-200), var(--ramp-8));
  --chrome-fg-muted: light-dark(var(--lilac-300), var(--ramp-8));
  /* Fourth chrome ink, the prototype's --chrome-muted (#9a92c0 light, ramp ink-3 dark — proto 880 / 20966): level
     labels, the ladder switch and the person card's role line. Sits between --chrome-fg-muted and --chrome-fg-faint. */
  --chrome-fg-soft: light-dark(var(--lilac-350), var(--ramp-9));
  --chrome-fg-faint: light-dark(var(--lilac-400), var(--ramp-9));
  /* White alphas — the prototype's glass family (proto 881-882 · 922 · 20879). They read on any dark
   * ground, so they do not switch with the mode. A lit nav row or ladder rung is NOT in here: it
   * is the level's own colour mixed to the prototype's alpha, at the component (console.css).
   * --chrome-fg is the prototype's --chrome-strong and --chrome-fg-faint its --chrome-muted:
   * the same values in dark, within 10 units of #9a92c0 in light. */
  --glass: rgba(255, 255, 255, 0.06);         /* a nav row's hover */
  --glass-1: rgba(255, 255, 255, 0.05);       /* the ladder card and the person card */
  --glass-line: rgba(255, 255, 255, 0.08);    /* their hairline, and the rule between nav groups */
  --glass-line-2: rgba(255, 255, 255, 0.16);  /* the ladder's spine */
  --glass-hover: rgba(255, 255, 255, 0.10);   /* a chrome button's hover */
  /* The keyboard focus ring on the dark chrome: the prototype's --ring (proto 911), which reads on the chrome in
     either mode because the chrome is dark in both ("Sidebar to the prototype", 2026-09-29). */
  --chrome-ring: var(--violet-300);
  --chrome-button-bg: rgba(255, 255, 255, 0.07);
  --chrome-button-line: rgba(255, 255, 255, 0.16);

  /* --- semantic: stage (the content panel) ---
   * The Blink ladder above is the reference, and these tokens are seated on it as the prototype
   * seats them. That moves three of them one rung from the console's earlier hand-rolled
   * mapping: --surface-2 (was #eceaf5, now the fill #f5f4f9), --line (was #e7e4f2, now the
   * hairline #eceaf5) and --line-strong (was #d6d3ea, now the edge #d9d5ea). Deliberate: the
   * ladder is the shared contract, the old mapping was not (Appearance theming, 2026-09-22).
   * The pane wash is the prototype's --wash-grad-2 (proto 3198/20147/20233): the card, a step
   * below it, and a step below that — paper on light, ramp 3 → 2 → 1 on dark. It is the panel's
   * ground, which is why the flat canvas step no longer has a token of its own. */
  --surface: light-dark(var(--paper-surface), var(--ramp-3));
  --surface-2: light-dark(var(--paper-fill), var(--ramp-4));
  /* The pane's ink ladder, all five steps of it (Pane typography, 2026-09-23). --ink-body is the
   * prototype's --ink-2 — table body text, the ink a row of data is set in; --ink-quiet its
   * --ink-3 — the crumb you are on, a quiet button, a neutral status pill. The console had
   * neither, so both roles used to borrow --ink or --ink-2 (= the prototype's --ink-4).
   * On dark paper the ramp has fewer ink steps than the light ladder does and the prototype
   * collapses them the same way (proto 20237: --ink-2 = ramp ink2, --ink-3 = ramp ink3), so
   * --ink-body meets --ink-2 and --ink-quiet meets --muted there. That is the ramp, not an
   * oversight: weight and position carry the distinction in dark. */
  --ink: light-dark(var(--ink-900), var(--ramp-7));
  --ink-body: light-dark(var(--ink-800), var(--ramp-8));
  --ink-2: light-dark(var(--ink-500), var(--ramp-8));
  --ink-quiet: light-dark(var(--ink-700), var(--ramp-9));
  --muted: light-dark(var(--ink-300), var(--ramp-9));
  --line: light-dark(var(--paper-hairline), var(--ramp-5));
  /* The second hairline (proto --hairline-2): the edge a pane control draws — the search field, a
   * quiet button. Darker than --line on paper, the ramp's navy step on dark paper (proto 20224). */
  --line-2: light-dark(var(--paper-hairline-2), var(--ramp-6));
  --line-strong: light-dark(var(--paper-edge), var(--ramp-6));
  /* Inside a table: the rule between two rows, quieter than --line, and the ground a clickable row
   * lifts to under the pointer (proto 3370). Dark takes the ramp step just under --line for the
   * divider and the one just over the card for the hover — both land on ramp 4. */
  --divider: light-dark(var(--paper-divider), var(--ramp-4));
  --hover-2: light-dark(var(--paper-hover), var(--ramp-4));
  --wash-grad-2: linear-gradient(165deg,
      var(--surface) 0%,
      light-dark(var(--paper-wash-a), var(--ramp-2)) 55%,
      light-dark(var(--paper-wash-b), var(--ramp-1)) 100%);

  /* --- semantic: accents ---
   * The accent does not follow the workspace: it is the console's violet on paper and the one
   * fixed lift of it on any dark ramp (prototype consolePalette). */
  --accent: light-dark(var(--violet-600), var(--violet-400));
  --accent-2: light-dark(var(--purple-600), var(--purple-500));   /* gradient partner */
  /* the primary fill, the prototype's --grad-primary (proto 900): a primary button, and the Conversions form's Next and
     Add Conversion, which the prototype hard-codes blue → violet (2586 · 2616) — a bug not copied, so they follow the
     theme like every other primary ("Conversions click-through", 2026-09-30) — and its Show icon switch when on */
  --grad-primary: linear-gradient(90deg, var(--accent), var(--accent-2));
  --accent-soft: light-dark(var(--violet-100), var(--violet-950));
  /* The quieter of the two accent fills: the pill a section's action wears (proto 3287), which hovers
     onto --accent-soft, so the lift is a step up rather than a colour change. The dark ramps have no
     step below --accent-soft, so on dark paper this is the accent at a low alpha, the way --ok-soft and
     --hot-soft are built below. */
  --accent-soft-2: light-dark(var(--violet-50), rgba(135, 106, 241, 0.1));
  --ring: light-dark(var(--violet-300), var(--violet-800));   /* a quiet control's hover edge */
  --accent-fg: var(--white);              /* ink on any saturated fill: primary button, filled tile */
  --flavor: var(--violet-600);            /* the current workspace's flavor; remapped below */
  --flavor-soft: rgba(124, 92, 240, 0.18);
  /* The ink a nav group header wears (proto 22317 NAV.sectionColor · 34597). At a console level it is the
     level's own colour; a workspace names a quieter one of its own, so this is a token rather than
     just --flavor. Remapped with --flavor below; the default covers a flavor that names neither. */
  --flavor-section: var(--flavor);
  /* The workspace colours as themselves, for a row or pill that names one rather than sits in it.
   * -soft is the ladder/tile ground (18%), -wash the lighter ground a type pill wears (12%). */
  --skills: var(--orange-500);
  --skills-soft: rgba(249, 115, 22, 0.18);
  --skills-wash: rgba(249, 115, 22, 0.12);
  --skills-section: var(--clay-400);
  --social: var(--violet-600);
  --social-soft: rgba(124, 92, 240, 0.18);
  --social-wash: rgba(124, 92, 240, 0.12);
  --social-section: var(--lilac-450);
  --feed: var(--blue-500);
  --feed-soft: rgba(59, 130, 246, 0.18);
  --feed-wash: rgba(59, 130, 246, 0.12);
  /* The three billing models a workspace is metered by ("Workspaces directory", 2026-09-25; proto 24580):
   * Seats blue, Audience the console's own violet, Ecosystem teal. Light is the prototype's own pair; dark
   * lifts the ink to the step that reads on a dark ramp and keeps the ground at the 18% the status tones
   * use, which is what the prototype's TH.tint does on dark paper (proto 20352). */
  --model-seats: light-dark(var(--blue-700), var(--blue-400));
  --model-seats-soft: light-dark(var(--blue-100), rgba(93, 131, 233, 0.18));
  --model-audience: light-dark(var(--violet-600), var(--violet-400));
  --model-audience-soft: light-dark(var(--violet-100), rgba(135, 106, 241, 0.18));
  --model-ecosystem: light-dark(var(--teal-700), var(--teal-500));
  --model-ecosystem-soft: light-dark(var(--teal-100), rgba(20, 184, 166, 0.18));
  --platform: var(--gold-500);           /* the Blinklink row and the platform-wide scope */
  --platform-soft: rgba(201, 150, 43, 0.18);
  /* the hairline that closes a platform tile's soft ground: the level gold at half alpha, as the
     prototype draws every level tile (proto 22331 `tileBorder`) */
  --platform-line: rgba(201, 150, 43, 0.5);
  /* Text in the level gold ("Sidebar to the prototype", 2026-09-29: every text use is at least 4.5:1 in both
     modes). --platform-ink is the scope chip's, on --platform-wash: the prototype's own pair on paper (4.74:1)
     and the lifted gold on the dark wash (5.59:1 at worst, Midnight). --platform-ink-soft is a monogram's on
     the 18% --platform-soft ground (the team head tile, the platform row in the person menu), which is
     darker than the chip's opaque tint on paper and so needs the deeper step there (4.69:1 at worst). */
  --platform-ink: light-dark(var(--gold-700), var(--gold-400));
  --platform-ink-soft: light-dark(var(--gold-800), var(--gold-400));
  --platform-wash: light-dark(var(--gold-100), rgba(201, 150, 43, 0.18));
  --msp: var(--sky-500);                  /* an MSP row in the hierarchy */
  --msp-soft: rgba(56, 189, 248, 0.2);
  --msp-ink: light-dark(var(--sky-700), var(--sky-500));
  /* light is the prototype's own TIER.tint for the Partner chip (#e0f2fe, proto 21480); dark keeps
     the level colour at the alpha the platform chip uses, as TH.tint does on dark paper */
  --msp-wash: light-dark(var(--sky-100), rgba(56, 189, 248, 0.16));
  --org: var(--violet-500);               /* the organisation row */
  --org-soft: rgba(139, 92, 246, 0.2);
  --avatar-bg: var(--peach-100);
  --avatar-fg: var(--ink-950);
  /* The member avatars' colour pool, in the prototype's order (proto 24720: accent · #3b82f6 ·
   * #14b8a6 · #f97316 · #e11d48), cycled by position in the list. Tone 0 is the accent itself and
   * has no token of its own. Flat and identical in both modes, as the prototype draws them — they
   * name a person, not a state, and --accent-fg reads on all five ("Blinklink Team", 2026-09-25). */
  --avatar-tone-1: var(--blue-500);
  --avatar-tone-2: var(--teal-500);
  --avatar-tone-3: var(--orange-500);
  --avatar-tone-4: var(--rose-600);
  /* The business monogram tile (Account Details) — a deep, brand-neutral ground the initial sits on. */
  --monogram-bg: var(--navy-800);
  --monogram-fg: var(--white);
  /* A media placeholder waiting for an upload (profile avatar): the ground and the glyph on it. */
  --placeholder-bg: light-dark(var(--paper-hairline-2), var(--ramp-4));
  --placeholder-fg: light-dark(var(--ink-300), var(--ramp-9));
  --gradient-badge: linear-gradient(135deg, var(--blue-500), var(--violet-500));
  /* The Feeds screens' blue → violet call to action: the same two stops laid left to right, as the prototype draws
     Create Feed's Continue, Configure Platform's Create and Manage Whitelist's Sync Now (14062 · 13991 · 14945) */
  --fd-grad-cta: linear-gradient(90deg, var(--blue-500), var(--violet-500));
  /* Social chips in the settings footer — decorative, deferred (2026-09-22). Brand colours, so
   * they are the same in both modes. */
  --social-instagram: linear-gradient(135deg, var(--orange-500), var(--pink-500));
  --social-x: var(--ink-950);
  --social-linkedin: var(--linkedin-600);

  /* --- semantic: status ---
   * Light is the value the console has always drawn. Dark keeps the hue and rises to a level
   * that reads on dark paper, over the same hue at 18% (prototype consolePalette stInk/stBg). */
  --ok: light-dark(var(--green-600), var(--green-400));
  --ok-soft: light-dark(rgba(22, 163, 74, 0.12), rgba(93, 233, 145, 0.18));
  --warn: light-dark(var(--amber-700), var(--amber-400));
  --warn-soft: light-dark(rgba(180, 83, 9, 0.12), rgba(246, 152, 81, 0.18));
  --danger: light-dark(var(--red-600), var(--red-400));
  --danger-soft: light-dark(rgba(220, 38, 38, 0.1), rgba(229, 97, 97, 0.18));
  --info: light-dark(var(--blue-500), var(--blue-400));
  --info-soft: light-dark(rgba(59, 130, 246, 0.12), rgba(93, 131, 233, 0.18));
  /* "hot" — an attention tone that is neither a warning nor a failure: the prototype's TH.hot /
   * TH.hotBg (#c2440f on #fdeee2), which the 2FA "Required" pill wears. Named for what it is
   * rather than folded into --warn, because --warn is amber and this tone is deliberately
   * orange-red (Account Settings, 2026-09-22). */
  --hot: light-dark(var(--hot-600), var(--hot-400));
  --hot-soft: light-dark(var(--hot-100), rgba(242, 132, 84, 0.18));

  /* --- semantic: transient surfaces ---
   * A toast is a dark chip in both modes: the console's near-black on paper, the ramp's pill
   * step on dark paper so it still lifts off the card behind it.
   * A switch knob is the light disc on its track.
   * The scrim is what a modal dims the page with: the prototype's own veil on paper (proto 3613,
   * rgba(18,12,38,0.4)), and plain black on dark paper, where a violet veil reads as a smudge —
   * the same reasoning as --shadow-menu above ("Blinklink Team", 2026-09-25). */
  --toast-bg: light-dark(var(--ink-900), var(--ramp-4));
  --toast-fg: light-dark(var(--white), var(--ramp-7));
  --toast-hover: rgba(255, 255, 255, 0.1);
  --knob-fg: light-dark(var(--white), var(--ramp-7));
  --scrim: light-dark(rgba(18, 12, 38, 0.4), rgba(0, 0, 0, 0.6));

  /* --- semantic: auth surface (sign-in / sign-up) ---
   * A dark glass page that stands outside the console chrome: it is deliberately
   * theme-independent, so neither mode nor theme remaps these. */
  --auth-bg-gradient: linear-gradient(25deg, var(--plum-900) 0%, var(--teal-900) 100%);
  --auth-card-bg: rgba(255, 255, 255, 0.10);
  --auth-card-blur: 22px;
  --auth-card-radius: 20px;
  --auth-field-bg: rgba(255, 255, 255, 0.10);
  --auth-fg: var(--white);
  --auth-fg-muted: rgba(255, 255, 255, 0.6);
  --auth-fg-placeholder: rgba(255, 255, 255, 0.7);
  --auth-tile-bg: rgba(0, 0, 0, 0.10);
  --auth-tile-radius: 12px;
  --auth-line: rgba(255, 255, 255, 0.10);
  /* The gradient a saturated auth button wears (proto 1006). Blue into violet rather than the console's
     accent pair, because this surface is not themed — it is the same on every appearance. */
  --auth-primary: linear-gradient(90deg, #2196f3, #8b5cf6);

  /* --- semantic: sign-up ("Sign-up click-through", 2026-09-25) ---
   * The two-pane flow (proto 969-1228). Every value is the prototype's, at the decoded line named after
   * it; the console's own names for them are these tokens, so console.css stays free of raw colour. */
  --auth-split-bg: linear-gradient(150deg, #0b1327 0%, #10142e 45%, #151233 65%, #2c1a41 100%);  /* proto 970 */
  --auth-rail-bg: rgba(255, 255, 255, 0.045);        /* proto 973 */
  --auth-rail-line: rgba(255, 255, 255, 0.06);       /* proto 973 */
  --auth-rail-field-bg: rgba(255, 255, 255, 0.06);   /* proto 999 */
  --auth-rail-field-line: rgba(255, 255, 255, 0.12); /* proto 999 */
  --auth-rail-tile-bg: rgba(255, 255, 255, 0.04);    /* proto 1012 — an SSO tile and the role row */
  --auth-rail-tile-line: rgba(255, 255, 255, 0.10);  /* proto 1012 */
  --auth-rail-tile-icon-bg: #1c2438;                 /* proto 1013 — the square a brand logo sits on */
  --auth-ghost-bg: rgba(255, 255, 255, 0.04);        /* proto 1126 — the Back button */
  --auth-ghost-line: rgba(255, 255, 255, 0.2);       /* proto 1126, and the role pill at 1069 */
  --auth-dashed: rgba(255, 255, 255, 0.25);          /* proto 1008 "Or", 1165 the connector */
  --auth-progress-track: rgba(255, 255, 255, 0.14);  /* proto 990 */
  --auth-progress: #22c55e;                          /* proto 991 */
  --auth-dot: #8b5cf6;                               /* proto 1166 — the violet dot on the connector */
  /* the preview's two cards, their footer strip and the pills on it */
  --auth-preview-bg: rgba(255, 255, 255, 0.055);     /* proto 1139 */
  --auth-strip-bg: rgba(255, 255, 255, 0.04);        /* proto 1192 */
  --auth-strip-line: rgba(255, 255, 255, 0.05);      /* proto 1192 */
  --auth-strip-divider: rgba(255, 255, 255, 0.12);   /* proto 1205 */
  --auth-pill-bg: rgba(255, 255, 255, 0.07);         /* proto 1194 — the workspace type chip */
  --auth-role-pill-bg: rgba(255, 255, 255, 0.08);    /* proto 1211 */
  --auth-role-pill-line: rgba(255, 255, 255, 0.14);  /* proto 1211 */
  --auth-org-tile: #1e3a8a;                          /* proto 1141 — the organisation's monogram tile */
  --auth-avatar-fg: #1a1033;                         /* proto 1403 — the ink on a team row's pastel tile */
  /* a card still waiting for what you have not typed yet (proto 1153-1157): the tile, the bold bar, the quiet one */
  --auth-skel-tile: rgba(255, 255, 255, 0.09);
  --auth-skel-strong: rgba(255, 255, 255, 0.22);
  --auth-skel-soft: rgba(255, 255, 255, 0.14);
  /* the two workspace types as themselves — a chosen card's edge and the ground its orb's tile sits on
     (proto 1199-1208 Skills, 1209-1218 Social). Not --skills/--social: those are themed console tokens
     and this surface is theme-independent. */
  --auth-skills: #f97316;
  --auth-skills-soft: rgba(249, 115, 22, 0.15);
  --auth-social: #8b5cf6;
  --auth-social-soft: rgba(139, 92, 246, 0.15);
  /* the five quiet inks the flow writes in (proto 987, 988, 1005, 1009, 1196) and the ink an outline
     icon inside a field takes (proto 1001) */
  --auth-ink-quiet: #9aa3bb;
  --auth-ink-faint: #8b93aa;
  --auth-ink-help: #7d86a0;
  --auth-ink-soft: #c6cbda;
  --auth-ink-strip: #e8eaf2;
  --auth-icon: #aab2c8;
  --auth-option-bg: #151b30;                         /* proto 1079 — a native option's ground on a dark field */
  --auth-radio-on: #3b82f6;                          /* proto 1099 — the chosen card's ring */
  --auth-radio-dot: linear-gradient(135deg, #3b82f6, #8b5cf6);  /* proto 1100 — the dot inside it */

  /* --- semantic: the six-step sign-up ("Six-step sign-up", 2026-10-07; proto 1051-1435, 27893-28078) --- */
  --auth-divider-ink: rgba(255, 255, 255, 0.40);     /* proto 1083 — "Single sign-on" */
  --auth-divider-line: rgba(255, 255, 255, 0.16);    /* proto 1082/1084 — the hairlines fading into it */
  --auth-control-bg: rgba(255, 255, 255, 0.05);      /* proto 1117 — Replace image, Upload logo, Remove; Add another's hover */
  --auth-control-line: rgba(255, 255, 255, 0.14);    /* proto 1117 */
  --auth-control-hover: rgba(255, 255, 255, 0.10);   /* proto 1123 */
  --auth-control-radius: 9px;                        /* proto 1117 — the picture controls and the source chips */
  --auth-logo-radius: 16px;                          /* proto 1156 — the company logo's tile */
  --auth-danger-ink: #f87171;                        /* proto 1126/1167 — a refused file, the logo's bin */
  --auth-danger-hover: rgba(239, 68, 68, 0.12);      /* proto 1166 — the bin under the pointer */
  --auth-card-idle-bg: rgba(255, 255, 255, 0.03);    /* proto 28037 — a type card not chosen */
  --auth-radio-off: rgba(255, 255, 255, 0.3);        /* proto 28038 — its ring */
  --auth-skills-card: linear-gradient(135deg, rgba(249, 115, 22, 0.14), rgba(139, 92, 246, 0.08));  /* proto 28037 */
  --auth-social-card: linear-gradient(135deg, rgba(139, 92, 246, 0.14), rgba(59, 130, 246, 0.08));  /* proto 28040 */
  --auth-row-invalid: rgba(248, 113, 113, 0.75);     /* proto 27965 — a refused invite row's edge */
  --auth-menu-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);  /* proto 1245 — the role menu */
  --auth-menu-hover: rgba(255, 255, 255, 0.07);      /* proto 1247 */
  --auth-menu-on: rgba(139, 92, 246, 0.16);          /* proto 27971 — the chosen role */
  --auth-menu-check: #a78bfa;                        /* proto 1252 */
  --auth-add-line: rgba(255, 255, 255, 0.22);        /* proto 1260 — Add another's dashed edge */
  --auth-step-error: #fca5a5;                        /* proto 1267 — the team step's sentence */
  --auth-chip-hover: rgba(255, 255, 255, 0.08);      /* proto 1279 */
  --auth-chip-on-bg: rgba(139, 92, 246, 0.2);        /* proto 28004 — the chosen source */
  --auth-chip-on-line: #8b5cf6;                      /* proto 28005 */
  --auth-skel-faint: rgba(255, 255, 255, 0.12);      /* proto 1421 — the team card's second skeleton bar */
  /* the team card's six pastel tiles, in turn (proto 27936 suAv) */
  --auth-team-tone-0: #fde8d0;
  --auth-team-tone-1: #dbeafe;
  --auth-team-tone-2: #dcfce7;
  --auth-team-tone-3: #fce7f3;
  --auth-team-tone-4: #ede9fe;
  --auth-team-tone-5: #fef3c7;

  /* --- semantic: the Feeds screens ("Feeds click-through", 2026-09-29) ---
   * Light is the prototype's value (its role literal in brackets); dark lifts the ink or drops the ground to the
   * ramp the way the rest of this section does. Tints of a status are colour-mixed from that status over the card,
   * so they follow both the mode and the light theme's paper. */
  /* a feed's colour, by its place in the workspace (FeedTone: the seed's colours in the seed's order, 17622-17629) —
     it names the feed, like an avatar tone, so it is the same in both modes */
  --feed-tone-green: var(--green-600);
  --feed-tone-blue: var(--blue-500);
  --feed-tone-teal: var(--teal-500);
  --feed-tone-violet: var(--violet-500);
  --feed-tone-pink: var(--pink-500);
  --feed-tone-orange: var(--orange-500);
  --feed-tone-indigo: var(--indigo-500);
  --feed-tone-red: var(--red-500);
  /* the thumbnail (feedFrame 22467-22480): the grey of a frame that is not live, the gloss and shimmer a live one
     wears, the light play glyph on it and its shadow */
  --fd-frame-ground: light-dark(var(--lilac-110), var(--ramp-4));
  --fd-frame-gloss: linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0%, rgba(255, 255, 255, 0) 42%, rgba(0, 0, 0, 0.1) 100%);
  --fd-frame-shimmer: linear-gradient(105deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.85) 50%, rgba(255, 255, 255, 0) 100%);
  --fd-play-light: var(--white);
  --fd-play-shadow: rgba(20, 12, 40, 0.22);
  /* inks: the glyph grey [--icon], the disabled grey [--dim-5], the waiting dot, the live signal, the deep accent */
  --fd-icon: light-dark(var(--slate-400), var(--ramp-9));
  --fd-dim: light-dark(var(--ink-200), var(--ramp-9));
  --fd-dot-warn: light-dark(var(--amber-500), var(--amber-400));
  --fd-signal-on: light-dark(var(--green-500), var(--green-400));
  --fd-accent-deep: light-dark(var(--violet-700), var(--violet-400));
  /* grounds: the platform card's glass [--surface-glass], a hovered option [--hover], the two rails [--hover-2 /
     --hover-6], the editor's canvas [--canvas], and the flavor's own soft ground [wsAccentSoft] with its second
     accent [wsAccent2], which the platform mark's second ellipse is drawn in */
  --fd-surface-glass: light-dark(rgba(255, 255, 255, 0.75), var(--ramp-3));
  --fd-hover: light-dark(var(--paper-hover), var(--ramp-4));
  --fd-rail-bg: light-dark(var(--paper-hover), var(--ramp-2));
  --fd-canvas: light-dark(var(--paper-canvas), var(--ramp-1));
  --fd-flavor-soft: color-mix(in srgb, var(--flavor) 11%, var(--surface));
  --fd-flavor-2: color-mix(in srgb, var(--flavor) 70%, var(--white));
  /* the dark tiles (--tile-dark / --tile-dark-2) and the Configure panel's platform card with what sits on it */
  --fd-tile-dark: linear-gradient(140deg, #2c2937, #141218);
  --fd-tile-dark-2: linear-gradient(140deg, #1d1b26, #0e0d13);
  --fd-platform-card: linear-gradient(120deg, var(--ember-950) 30%, var(--ember-900) 75%, var(--ember-600) 130%);
  --fd-on-dark-soft: var(--lilac-250);
  --fd-on-dark-label: var(--lilac-150);
  --fd-on-dark-glass: rgba(255, 255, 255, 0.1);
  --fd-on-dark-line: rgba(255, 255, 255, 0.16);
  --fd-on-dark-faint: rgba(255, 255, 255, 0.55);
  /* the module tiles' vignettes (22439-22446): a picture, drawn the same in both modes */
  --fd-vig-pill-bg: rgba(10, 7, 20, 0.5);
  --fd-vig-line: rgba(255, 255, 255, 0.14);
  --fd-vig-label: var(--lilac-150);
  --fd-vig-live: #4ade80;
  --fd-vig-off: #8a8598;
  --fd-vig-os-off: #6b6580;
  --fd-vig-gold: #fbbf24;
  --fd-vig-ring-track: rgba(255, 255, 255, 0.12);
  --fd-vig-card: rgba(124, 92, 240, 0.22);
  --fd-vig-card-lit: rgba(124, 92, 240, 0.4);
  --fd-vig-card-line: rgba(255, 255, 255, 0.16);
  --fd-vig-card-play: rgba(255, 255, 255, 0.85);
  /* the later funnel feeds' tiles and CMS chips (2037-2068): Search green, Product amber, Article teal, Related pink */
  --fd-funnel-search: var(--ok);
  --fd-funnel-search-soft: var(--ok-soft);
  --fd-funnel-product: light-dark(var(--amber-600), var(--amber-400));
  --fd-funnel-product-soft: var(--warn-soft);
  --fd-funnel-article: light-dark(var(--teal-600), var(--teal-500));
  --fd-funnel-article-soft: color-mix(in srgb, var(--teal-600) 13%, var(--surface));
  --fd-funnel-related: light-dark(var(--pink-600), var(--pink-500));
  --fd-funnel-related-soft: color-mix(in srgb, var(--pink-600) 10%, var(--surface));
  /* the Customize rail's glyph inks (cfRailRows 28779-28789) */
  --fd-rail-layout: var(--accent);
  --fd-rail-grid: light-dark(var(--teal-600), var(--teal-500));
  --fd-rail-playback: var(--pink-400);
  --fd-rail-menu: var(--ochre-500);
  --fd-rail-share: var(--azure-500);
  --fd-rail-personalization: light-dark(var(--purple-600), var(--purple-500));
  /* the notes and washes: the Referrer note [--edge-6 on --hover-11], "Platform needed" [--warn-line-2 on
     --warn-bg-2, --warn-7], Generative's box [--accent-line on --wash-accent] and "Generative unlocks" [--muted-2] */
  --fd-note-bg: color-mix(in srgb, var(--accent) 4%, var(--surface));
  --fd-note-line: color-mix(in srgb, var(--accent) 14%, var(--surface));
  --fd-warn-note-bg: color-mix(in srgb, var(--warn) 7%, var(--surface));
  --fd-warn-note-line: color-mix(in srgb, var(--warn) 24%, var(--surface));
  --fd-warn-ink: light-dark(var(--amber-900), var(--amber-400));
  --fd-accent-line: color-mix(in srgb, var(--accent) 20%, var(--surface));
  --fd-accent-wash: linear-gradient(120deg, color-mix(in srgb, var(--accent) 3%, var(--surface)), color-mix(in srgb, var(--accent) 9%, var(--surface)));
  --fd-muted-2: light-dark(var(--lilac-500), var(--ramp-9));
  /* the deactivated banner [--bad-bg, --bad-line-2, --bad-4] and the danger zone [--bad-bg-3, --bad-3, --bad-5] */
  --fd-bad-wash: color-mix(in srgb, var(--danger) 9%, var(--surface));
  --fd-bad-wash-soft: light-dark(var(--rose-50), color-mix(in srgb, var(--danger) 3%, var(--surface)));
  --fd-bad-line: color-mix(in srgb, var(--danger) 24%, var(--surface));
  --fd-bad-ink: light-dark(var(--red-700), var(--red-400));
  --fd-bad-ink-deep: light-dark(var(--red-900), var(--red-400));
  --fd-bad-ink-muted: light-dark(var(--rosewood-500), var(--ramp-8));
  /* Create Feed's preview: the draft card [--ok-bg-9], its glyph tile [--ok-bg-10] and glyph [--icon-green], the
     promo's wash (14632) and its placeholder mark */
  --fd-ok-wash: color-mix(in srgb, var(--ok) 9%, var(--surface));
  --fd-ok-wash-2: color-mix(in srgb, var(--ok) 19%, var(--surface));
  --fd-ok-deep: light-dark(var(--green-800), var(--green-400));
  --fd-promo-wash: linear-gradient(120deg, light-dark(var(--mint-100), var(--ramp-3)), light-dark(var(--orchid-100), var(--ramp-2)));
  --fd-promo-mark: var(--smoke-200);
  /* Feed Settings: Save Changes before a change [--toggle-off-2], the uptime bars (upBars 22488) and the snippet */
  --fd-save-idle: light-dark(var(--lilac-120), var(--ramp-5));
  --fd-bar-ok: var(--green-500);
  --fd-bar-warn: var(--amber-500);
  --fd-bar-bad: var(--red-500);
  /* a day web-embed has no data for (UptimeDay NO_DATA, "Embedded feeds on the feeds module", 2026-10-16) */
  --fd-bar-none: var(--line-strong);
  --fd-snippet-bg: var(--night-900);
  --fd-snippet-ink: var(--blink-edge);
  /* Round 2 ("Feeds as the workspace's home", 2026-09-29). The Platform tab's module states (2098-2110): the on-disc
     and its rings, the off-disc, and a locked module's edge, wash, tile and ink; the Upgrade pill's glow. */
  --fd-ok-grad: linear-gradient(135deg, var(--green-350), var(--green-600));
  --fd-ok-ring: light-dark(var(--mint-50), rgba(93, 233, 145, 0.14));
  --fd-ok-glow: rgba(22, 163, 74, 0.5);
  --fd-off-disc: light-dark(var(--lilac-115), var(--ramp-5));
  --fd-off-ring: light-dark(var(--lilac-105), var(--ramp-4));
  --fd-locked-line: light-dark(var(--cream-100), color-mix(in srgb, var(--warn) 30%, var(--surface)));
  --fd-locked-wash: linear-gradient(120deg, light-dark(var(--cream-50), var(--ramp-3)), light-dark(var(--cream-75), var(--ramp-4)));
  --fd-locked-tile: light-dark(var(--cream-90), var(--warn-soft));
  --fd-locked-ink: light-dark(var(--ochre-700), var(--amber-400));
  --fd-shadow-upgrade: 0 3px 10px color-mix(in srgb, var(--accent) 30%, transparent);
  /* the hero and What is it? (2158-2162 · 16560-16568): the play disc on a dark picture, its badge, the dialog's dark
     side, the LMS picture's ink, and the scrim and shadow the dialog sits on */
  --fd-hero-disc: rgba(255, 255, 255, 0.12);
  --fd-hero-disc-line: rgba(255, 255, 255, 0.6);
  --fd-hero-badge: rgba(0, 0, 0, 0.45);
  --fd-hero-lms: var(--steel-300);
  --fd-about-art: linear-gradient(165deg, var(--dusk-800) 0%, var(--dusk-950) 60%, var(--dusk-900) 100%);
  --fd-about-glyph: rgba(255, 255, 255, 0.85);
  --fd-about-caption: rgba(255, 255, 255, 0.9);
  --fd-about-duration: rgba(255, 255, 255, 0.7);
  --fd-about-disc-line: rgba(255, 255, 255, 0.65);
  --fd-scrim-about: light-dark(rgba(14, 10, 30, 0.6), rgba(0, 0, 0, 0.65));
  --fd-shadow-about: 0 40px 110px light-dark(rgba(18, 10, 50, 0.5), rgba(0, 0, 0, 0.7));
  /* Manage Whitelist (15465-15612): its scrim and shadow, a row's globe tile, the row menu's shadow, the Remove
     confirm's edge and sentence */
  --fd-scrim-wl: light-dark(rgba(19, 13, 38, 0.5), rgba(0, 0, 0, 0.6));
  --fd-shadow-wl: 0 30px 80px -20px light-dark(rgba(18, 12, 40, 0.5), rgba(0, 0, 0, 0.7));
  --fd-globe-tile: light-dark(var(--lilac-130), var(--ramp-4));
  --fd-accent-chip: light-dark(var(--violet-110), var(--accent-soft));
  /* the prototype's placeholder ink, #767f97 in and out of its App shell (869, and --placeholder in the shell): the
     Feeds and Conversions search pills, every Feeds field (.fd-input), the Customize switcher's search, Manage
     Whitelist's two fields and the Conversions form's fields — measured on the prototype at 1920 ("Conversions click-through", 2026-09-30) */
  --fd-placeholder: light-dark(var(--slate-450), var(--ramp-9));
  /* the selected filter chip: the prototype's toast ink (TH.toastBg, 28530), a step darker than the console's toast */
  --fd-chip-dark: light-dark(var(--night-900), var(--ramp-7));
  --fd-chip-dark-fg: light-dark(var(--white), var(--ramp-0));
  --fd-shadow-row-menu: 0 14px 36px light-dark(rgba(20, 10, 60, 0.18), rgba(0, 0, 0, 0.6));
  --fd-bad-line-soft: light-dark(var(--rose-150), color-mix(in srgb, var(--danger) 19%, var(--surface)));
  --fd-bad-ink-soft: light-dark(var(--rosewood-600), var(--ramp-8));
  /* the share channels' dots */
  --fd-channel-email: var(--violet-600);
  --fd-channel-linkedin: var(--linkedin-600);
  --fd-channel-facebook: var(--facebook-500);
  --fd-channel-whatsapp: var(--whatsapp-500);
  --fd-channel-x: var(--x-900);
  --fd-channel-reddit: var(--reddit-500);
  --fd-channel-teams: var(--teams-400);
  /* shadows: a card (--shadow-11), the platform card (--shadow-12), a frame (--shadow-18), the search pill (--shadow-16),
     Configure's glow (--accent-glow), the editor's primary (--accent-glow-2), the switcher (--shadow-20), the page
     list (--shadow-15), the mocks (15358). Violet haze on paper, plain black on dark paper (--shadow-menu's rule). */
  --fd-shadow-card: 0 4px 14px light-dark(rgba(50, 35, 110, 0.06), rgba(0, 0, 0, 0.3));
  --fd-shadow-platform: 0 8px 26px light-dark(rgba(50, 35, 110, 0.07), rgba(0, 0, 0, 0.3));
  --fd-shadow-frame: 0 2px 7px -2px light-dark(rgba(30, 20, 70, 0.18), rgba(0, 0, 0, 0.5));
  --fd-shadow-search: 0 1px 3px light-dark(rgba(30, 20, 70, 0.05), rgba(0, 0, 0, 0.2));
  --fd-shadow-cta: 0 6px 18px rgba(124, 92, 240, 0.35);
  --fd-shadow-primary: 0 6px 16px -6px rgba(124, 92, 240, 0.5);
  --fd-shadow-popover: 0 18px 50px -12px light-dark(rgba(30, 20, 70, 0.28), rgba(0, 0, 0, 0.7));
  --fd-shadow-list: 0 14px 40px light-dark(rgba(40, 25, 90, 0.14), rgba(0, 0, 0, 0.6));
  --fd-shadow-mock: 0 12px 34px rgba(30, 20, 70, 0.14);
  /* the editor's canvas mocks (15355-15453): the marketer's own page, not the console — the same in both modes */
  --mock-frame: #3a3844;
  --mock-bar: #2b2933;
  --mock-address: #413e4b;
  --mock-close: #f87171;
  --mock-min: #fbbf24;
  --mock-max: #34d399;
  --mock-page: var(--white);
  --mock-ink: #1c1a24;
  --mock-caption: var(--lilac-120);
  --mock-rule: #f0eef6;
  --mock-control: #d5d2e0;
  --mock-tile-1: linear-gradient(160deg, #8fa8b8, #41586b);
  --mock-tile-2: linear-gradient(160deg, #d9e2e4, #7f9aa3);
  --mock-tile-3: linear-gradient(160deg, #f3b96e, #a24f2c);
  --mock-tile-4: linear-gradient(160deg, #9fb98f, #4c6b41);
  --mock-tile-5: linear-gradient(160deg, #b8935f, #503a20);
  --mock-phone-tile-1: linear-gradient(160deg, #c8b195, #6e5136);
  --mock-phone-tile-2: linear-gradient(160deg, #7a4a5c, #3c1f2c);
  --mock-phone-tile-3: linear-gradient(160deg, #95a8b5, #4a5b68);

  /* --- semantic: the Conversions screens ("Conversions click-through", 2026-09-30) ---
   * What the Feeds tokens above do not already name. A CTA's own colours are not here: they are the customer's, and reach
   * CSS as the custom properties a template sets on .cv-design (console.css "conversions"); these are the defaults that
   * element reads before one is set — the Conversion Icon dialog's own (#3b82f6 and white, 26000-26005). */
  --cv-default-bar: var(--blue-500);
  --cv-default-ink: var(--white);
  /* the form's section tiles and Create's Dynamic tile [--ok-bg-2], an empty swatch and Show icon off [--edge-3], the
     dialog's preview well and placeholder phone [--fill-10], and the picked preset's edge [--accent-alt] */
  --cv-ok-tile: light-dark(var(--mint-150), var(--ok-soft));
  --cv-edge: light-dark(var(--lilac-260), var(--ramp-6));
  --cv-dialog-well: light-dark(var(--lilac-160), var(--ramp-4));
  --cv-picked: light-dark(var(--violet-500), var(--violet-400));
  /* the form's preview is the customer's clip, drawn the same in both modes (2645-2659): the phone, the skeleton bar
     and its marks, and Show icon's knob */
  --cv-phone: var(--lilac-160);
  --cv-skeleton: rgba(120, 118, 132, 0.5);
  --cv-skeleton-ink: var(--lilac-115);
  --cv-knob: var(--white);
  /* shadows: a card's bar (--shadow-25), a form section (--shadow-10) and the Select Icon popover (--shadow-25) — violet
     haze on paper, plain black on dark paper (--shadow-menu's rule) */
  --cv-shadow-bar: 0 2px 8px light-dark(rgba(20, 15, 40, 0.15), rgba(0, 0, 0, 0.3));
  --cv-shadow-section: 0 2px 10px light-dark(rgba(50, 35, 110, 0.04), rgba(0, 0, 0, 0.25));
  --cv-shadow-picker: 0 14px 40px light-dark(rgba(20, 15, 40, 0.15), rgba(0, 0, 0, 0.6));

  /* --- semantic: the Uploads screens ("Uploads click-through", 2026-09-30) ---
   * What the Feeds and Conversions tokens above do not already name. Light is the prototype's value (its role literal in
   * brackets); dark takes the hue at 18% over the card the way the prototype's TH.tint does (21104), or the ramp step the
   * rest of this section uses for the role. A clip's poster and the pictures over it are the same in both modes. */
  /* the top bar's pile pill (1712-1714): it sits on the chrome, which is dark in every mode [--glass-2, --glass-line-3] */
  --upl-pill-bg: rgba(255, 255, 255, 0.07);
  --upl-pill-line: rgba(255, 255, 255, 0.14);
  --upl-pill-ink: rgba(255, 255, 255, 0.72);
  --upl-pill-glow: 0 2px 10px rgba(124, 92, 240, 0.45);
  /* a tile (7446, 23578-23581): its ground before a poster, the scrim over one (DM_SCRIM 17227), its drop, the ring round
     the lit tile and its bloom, the tick box's two grounds [gradient-badge] and the title's shadow */
  --upl-tile-ground: linear-gradient(135deg, var(--ink-900), var(--plum-700));
  --upl-scrim: linear-gradient(180deg, rgba(6, 3, 16, 0.55), rgba(6, 3, 16, 0.12) 42%, rgba(6, 3, 16, 0.72));
  --upl-shadow-tile: 0 4px 14px light-dark(rgba(50, 35, 110, 0.08), rgba(0, 0, 0, 0.3));
  --upl-ring: var(--violet-500);
  --upl-ring-glow: 0 10px 30px rgba(139, 92, 246, 0.45);
  --upl-tick-off: rgba(0, 0, 0, 0.28);
  --upl-on-picture: var(--white);
  --upl-picture-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
  /* the empty queue's disc and glyph [--fill-3, --ink-5] */
  --upl-empty-disc: light-dark(var(--lilac-125), var(--ramp-4));
  --upl-empty-glyph: light-dark(var(--ink-600), var(--ramp-8));
  /* the clip box's play disc (7675) */
  --upl-play-disc: rgba(0, 0, 0, 0.42);
  --upl-play-line: rgba(255, 255, 255, 0.38);
  --upl-play-shadow: 0 6px 20px rgba(4, 2, 12, 0.4);
  /* the amber family: Edit, Request revision and the Revision card [--warn-bg, --warn-line, --warn-9] */
  --upl-warn-bg: light-dark(var(--cream-110), color-mix(in srgb, var(--amber-600) 18%, var(--surface)));
  --upl-warn-line: light-dark(var(--cream-200), color-mix(in srgb, var(--amber-600) 34%, var(--surface)));
  --upl-warn-ink: light-dark(var(--amber-600), var(--amber-400));
  /* the red family: the bin and Custom Source's tile, the Reported card, Delete upload and Remove [--bad-bg, --bad-2,
     --bad-bg-7, --bad-line, --bad-line-7] */
  --upl-bad-bg: light-dark(var(--rose-100), color-mix(in srgb, var(--danger) 18%, var(--surface)));
  --upl-bad-glyph: light-dark(var(--red-500), var(--red-400));
  --upl-bad-wash: light-dark(var(--rose-40), color-mix(in srgb, var(--danger) 8%, var(--surface)));
  --upl-bad-line: light-dark(var(--rose-200), color-mix(in srgb, var(--danger) 30%, var(--surface)));
  --upl-bad-line-2: light-dark(var(--rose-180), color-mix(in srgb, var(--danger) 36%, var(--surface)));
  /* Approve's green, the same in both modes (modBtn 23679) */
  --upl-approve: var(--green-500);
  /* "Processing failed" over a clip's ground, which is dark in both modes ("Uploads on content-v5", 2026-10-07) */
  --upl-failed-ink: var(--red-400);
  /* quiet inks and grounds: the pager discs [--dim-7], Send back before it is ready [--dim-4], the dialogs' lines
     [--icon-2], Cancel [--hairline-3] and Manage Category's footer [--hover-4] */
  --upl-disc: light-dark(var(--lilac-270), var(--ramp-6));
  --upl-dim: light-dark(var(--lilac-265), var(--ramp-6));
  --upl-line-ink: light-dark(var(--lilac-420), var(--ramp-9));
  --upl-cancel-bg: light-dark(var(--lilac-115), var(--ramp-4));
  --upl-foot-bg: light-dark(var(--lilac-60), var(--ramp-2));
  /* the dialogs (7783 · 7803 · 8165): the revision and Manage Category scrims [--scrim-2, with a 6px blur], the confirm's
     [--scrim-4], and their shadow [--shadow-8]; Manage Category's palette popover [--shadow-5] */
  --upl-scrim-dialog: light-dark(rgba(18, 12, 38, 0.5), rgba(0, 0, 0, 0.6));
  --upl-scrim-confirm: light-dark(rgba(18, 12, 38, 0.45), rgba(0, 0, 0, 0.6));
  --upl-shadow-dialog: 0 40px 100px light-dark(rgba(20, 10, 50, 0.4), rgba(0, 0, 0, 0.7));
  /* Manage Category's, a shade bluer [--shadow-9, 8165] */
  --upl-shadow-mgr: 0 40px 100px light-dark(rgba(20, 10, 60, 0.4), rgba(0, 0, 0, 0.7));
  --upl-shadow-palette: 0 12px 34px light-dark(rgba(20, 12, 50, 0.18), rgba(0, 0, 0, 0.6));
  /* the seven tag pastels, and a chosen chip's edge (23830: rgba(36, 29, 61, 0.22)) and the swatch's chevron (8181) */
  --upl-tag-yellow: light-dark(var(--pastel-yellow), var(--pastel-yellow-dark));
  --upl-tag-teal: light-dark(var(--pastel-teal), var(--pastel-teal-dark));
  --upl-tag-blue: light-dark(var(--pastel-blue), var(--pastel-blue-dark));
  --upl-tag-peach: light-dark(var(--pastel-peach), var(--pastel-peach-dark));
  --upl-tag-pink: light-dark(var(--pastel-pink), var(--pastel-pink-dark));
  --upl-tag-green: light-dark(var(--pastel-green), var(--pastel-green-dark));
  --upl-tag-lavender: light-dark(var(--pastel-lavender), var(--pastel-lavender-dark));
  --upl-tag-edge: light-dark(rgba(36, 29, 61, 0.22), rgba(255, 255, 255, 0.18));
  --upl-swatch-ink: light-dark(rgba(36, 29, 61, 0.55), rgba(255, 255, 255, 0.55));
  /* a chip row's right-edge fade (--fade-right, 8153): the card's own paper */
  --upl-fade: linear-gradient(90deg, color-mix(in srgb, var(--surface) 0%, transparent), var(--surface) 72%);
  /* the drop zone's ground [--hover] and its picture (8089 · 8090) [--accent-alt at 70%, --accent-tint] */
  --upl-drop-bg: light-dark(var(--violet-40), var(--ramp-4));
  --upl-drop-art: var(--violet-500);
  --upl-drop-ink: light-dark(var(--violet-200), var(--violet-950));
  /* the form's Preview (8283-8330): the phone once a file is attached, its skeleton bar and marks, the lines and chips
     under it until there is one [--fill-12, --hairline-3], and the chosen CTA's link card thumbnail */
  --upl-phone-file: linear-gradient(160deg, var(--slate-700), var(--slate-950));
  --upl-phone-skeleton: rgba(90, 88, 102, 0.55);
  --upl-phone-mark: var(--mock-control);
  --upl-phone-mark-2: var(--lilac-120);
  --upl-skeleton-strong: light-dark(var(--lilac-120), var(--ramp-5));
  --upl-skeleton: light-dark(var(--lilac-115), var(--ramp-4));
  --upl-link-thumb: linear-gradient(160deg, var(--steel-350), var(--steel-700));

  /* --- semantic: the Assets screens ("Assets click-through", 2026-09-30) ---
   * What the Feeds, Conversions and Uploads tokens above do not already name. Light is the prototype's value (its role
   * literal in brackets); dark takes the hue at 18% over the card the way the prototype's TH.tint does (21104), or the
   * ramp step the rest of this section uses for the role. A poster and the pictures over it are the same in both modes. */
  /* the editor's twelve feed colours (feedIconColors, 24005): seven are the Feeds page's tones to the digit, five are
     the editor's own — they name a feed, like an avatar tone, so they are the same in both modes */
  --as-color-amber: var(--amber-500);
  --as-color-green: var(--green-500);
  --as-color-cyan: var(--cyan-500);
  --as-color-lime: var(--lime-500);
  --as-color-purple: var(--purple-450);
  /* Manage Content (5612-5641): the platform feed's ground and edge [--warn-line-7], its frame per flavor, the lit row's
     ground (24025-24034), the frame's drop [--shadow-23] and the LMS note's dashes [--edge-7] */
  --as-platform-bg: linear-gradient(120deg, light-dark(var(--hot-100), color-mix(in srgb, var(--hot) 10%, var(--surface))), light-dark(var(--orchid-110), color-mix(in srgb, var(--accent) 10%, var(--surface))));
  --as-platform-line: light-dark(var(--clay-100), color-mix(in srgb, var(--hot) 30%, var(--surface)));
  --as-platform-skills: linear-gradient(135deg, var(--orange-500), var(--red-500));
  --as-platform-social: linear-gradient(135deg, var(--violet-600), var(--indigo-600));
  --as-selected-bg: linear-gradient(120deg, var(--accent-soft-2), light-dark(var(--violet-40), var(--accent-soft-2)));
  --as-shadow-frame: 0 2px 7px -2px light-dark(rgba(20, 12, 40, 0.25), rgba(0, 0, 0, 0.5));
  --as-note-line: light-dark(var(--lilac-240), var(--ramp-6));
  /* the Live pill [--ok-bg-3, --ok-line] */
  --as-live-bg: light-dark(var(--mint-60), var(--ok-soft));
  --as-live-line: light-dark(var(--mint-300), color-mix(in srgb, var(--ok) 36%, var(--surface)));
  /* the search's × under the pointer [--hover-5] */
  --as-clear-hover: light-dark(var(--lilac-55), var(--ramp-4));
  /* the editor (7113-7355): the Icon button's edge and the empty playlist's dashes [--edge-5], its hover [--accent-alt on
     --hover], the quiet fill Added and the Manual chip wear [--fill-8], a tag row's chip [--teal on its tint], the
     prompt's Reset [--bad-6 on --bad-bg-4, --bad-line-5] and the menu's Remove [--bad-7, --bad-bg-6], the tip over a
     thumbnail [--surface-dark-2] and the shadows of the Icon menu, the row menu, the head's frame and the tip */
  --as-edge: light-dark(var(--lilac-230), var(--ramp-6));
  --as-hover: light-dark(var(--violet-40), var(--ramp-4));
  --as-quiet-fill: light-dark(var(--lilac-140), var(--ramp-5));
  --as-tag-ink: light-dark(var(--teal-600), var(--teal-500));
  --as-tag-bg: light-dark(var(--mint-120), color-mix(in srgb, var(--teal-600) 18%, var(--surface)));
  --as-reset-ink: light-dark(var(--brick-600), var(--red-400));
  --as-reset-bg: light-dark(var(--rose-45), color-mix(in srgb, var(--danger) 10%, var(--surface)));
  --as-reset-bg-hover: light-dark(var(--rose-90), color-mix(in srgb, var(--danger) 16%, var(--surface)));
  --as-reset-line: light-dark(var(--rose-160), color-mix(in srgb, var(--danger) 30%, var(--surface)));
  --as-remove-ink: light-dark(var(--brick-700), var(--red-400));
  --as-remove-hover: light-dark(var(--rose-110), color-mix(in srgb, var(--danger) 16%, var(--surface)));
  --as-tip-bg: light-dark(var(--night-900), var(--ramp-6));
  --as-shadow-icons: 0 16px 40px light-dark(rgba(20, 10, 60, 0.18), rgba(0, 0, 0, 0.6));
  --as-shadow-menu: 0 14px 34px light-dark(rgba(20, 10, 60, 0.18), rgba(0, 0, 0, 0.6));
  --as-shadow-head-frame: 0 2px 6px -2px light-dark(rgba(20, 12, 40, 0.28), rgba(0, 0, 0, 0.5));
  --as-shadow-tip: 0 10px 26px light-dark(rgba(10, 5, 30, 0.4), rgba(0, 0, 0, 0.6));

  /* --- shape & type --- */
  /* a focus ring's corner on a text action — inline links and quiet actions ("Partners click-through", 2026-10-03) */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;
  --font: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  /* a menu's drop shadow is a violet haze on paper and plain black on dark paper, where a
   * tinted shadow reads as a smudge */
  --shadow-menu: 0 12px 32px -12px light-dark(rgba(20, 12, 50, 0.45), rgba(0, 0, 0, 0.7));
  --shadow-knob: 0 1px 3px rgba(0, 0, 0, 0.25);
  --font-serif: Georgia, "Times New Roman", serif;
  /* the monospace the prototype sets URLs and the embed line in ("Feeds click-through", 2026-09-29; proto 1848) */
  --font-mono: "SF Mono", ui-monospace, Menlo, monospace;
}

/* ---------- 5. density (Density, 2026-09-23) ----------
 *
 * One switch: --dc is 0 in comfortable, 1 in compact. Every size below is written ONCE, as
 *
 *     calc(<comfortable> - <delta> * var(--dc))
 *
 * so compact is a set of deltas rather than a second block of tokens to keep in step with the
 * first — and a third density later moves the switch (--dc becomes a scale: 0 · 1 · 2, or a
 * fractional step) without touching a single token. There is deliberately no compact block.
 *
 * Auto is the default and needs no attribute: under 1536px the console reads compact unless the
 * person asked for comfortable. The two explicit choices pin it either way, on any screen —
 * which is why [data-density="compact"] comes after the query rather than inside it.
 * layout.jte stamps data-density on <html> server-side, so the first paint is already right.
 *
 * Out of scope on purpose: anything at or below 11.5px (a label that is already at its floor),
 * icons, radii, pills and the 64px rail.
 *
 * The auth surface joined this layer on 2026-09-25 (decision "Sign-up click-through"): it is not a shell,
 * but it is a full-height screen with a fixed-width column and a 52px field, which reads as heavy on a
 * laptop for exactly the reason the console does. It takes the same switch — no page of its own. What
 * joined with it is every size that moves on those two pages, all of it below: the rail's column,
 * padding, title and field height; its type ladder (--auth-text-xs … --auth-text-lg) and its rhythm
 * (the form's gap, the cards' and type list's gap, the tiles' gap, a control's padding, the ghost
 * button's x-padding, the progress bar's gap, the Or divider's margin, the role row's padding, the
 * brand mark, the logo target); the
 * preview's inset, width, lift, card padding, org tile, org initial, title, workspace tile and
 * workspace name; and sign-in's card (width, gap, x-padding, brand, field height, title, footer inset),
 * which the sign-up inbox and unidentified cards reuse — the inbox's Back row on the shared quiet step.
 * Everything left as a literal in the .auth-* and .signup-* blocks is deliberate: a size at the 12px floor
 * of that ladder, a radius/border/icon, a length that is
 * the same in both densities (a field's 16px inset, the 32px avatar, the skeletons' geometry), or
 * sign-in's inner rem rhythm, which is the console's base rhythm and not a sign-in size.
 *
 * The Team page and the modal joined on 2026-09-25 (decision "Blinklink Team"): the head's rhythm and
 * its two monograms, a member row's inset and gap, the badge's and chip's insets, a section's spacing,
 * the type steps a row moves on, and every size of the dialog — its column, insets, rhythm, controls
 * and type. What stays literal there is the same class of thing as above: the 40px head tile and the
 * 34px avatar are icon boxes (only the letters in them move), the 12px badge, chip and sub-line sit at
 * this layer's floor, and the 2px nudge under a name and the 1rem gap of a head row are below it.
 *
 * The spacing pass of 2026-09-25 (a browser measurement of the Team page against the prototype) brought
 * in the furniture the generic admin pane is made of, which the Partner and organisation overviews draw
 * too: the stat grid's gap and the space under it, the toolbar's two gaps, its search field and select,
 * and the pill a section heading's action wears. It also gave the footer note a step of its own,
 * --text-note, at the prototype's 11.5px — the one size below the ladder's floor, with delta 0.
 *
 * The Workspaces directory joined on 2026-09-25 (decision "Workspaces directory"): its toolbar's two
 * departures from the house one, every size of its nine-column row — the row's inset, the gap between
 * columns, the fixed actions column, the two pills and the two buttons a row carries — the strip under
 * the card, the wider Manage dialog, and the usage meter (--meter-*). Two of its type steps sit under
 * this layer's 11.5px floor (the model chip at 10.5px and the line under the usage headline at 11px) and
 * so have a delta of 0, as --text-note does. What stays literal is the class of thing named above: the
 * 30px and 22px tiles in a row (and the 11px monogram inside the small one), the 12px on the Manage button and on the Open pill are icon boxes and the floor, the 9px
 * button radius and the 6px tile radius are radii, and the row's rules are 1px.
 *
 * The organisation's page joined on 2026-09-28 ("Org as a stop"): the space under the way back out, every
 * size of the identity card (its inset, its gaps, the org's name and the monogram on its tile), the tab
 * strip (its gap, the space under it, and how far a label sits above its underline), the space under each
 * of the Overview's cards, and the Admins table's trailing column. The 52px tile and its 13px radius, the
 * identity card's own 16px radius (the prototype draws that card a step rounder than the 14px --radius-lg a
 * list card wears), the 2px underline and the 1px rule under the strip are the class of thing named above
 * and stay literal; the tab's label, the meta line and both tables are steps this layer already names.
 *
 * The Feeds screens joined on 2026-09-29 ("Feeds click-through"): the list, its right panel, Create Feed, the
 * Customize editor and Feed Settings. They are drawn to the prototype's own sizes, which are many and small, so they
 * take a ladder rather than a token per rule: --fd-space-N is the prototype's N px of padding, gap or margin and
 * --fd-text-N its N px type step (a "-5" is a half pixel), each written once as calc(N - delta * var(--dc)) — the
 * spacing loses about a sixth in compact, the type half a pixel up to 15.5px, a pixel to 17px and two above. The
 * widths the prototype fixes in px (a card, a rail, a column) move the same way under their own names; the ones it
 * writes against its --u (the right panel, the task views' horizontal insets) are calc(N * var(--u)) and do not
 * take --dc, as the sidebar's width does not. What the Feeds rules keep literal is the class named above: type at
 * or under 12px, radii, 1px rules, icon boxes, and the drawings — the thumbnail, the module vignettes and the
 * editor's browser and phone — which are pictures at the prototype's geometry.
 *
 * The Conversions screens joined on 2026-09-30 ("Conversions click-through") on the Feeds screens' terms: the same
 * ladder, one step added to it (--fd-space-40), their own widths and control boxes under --cv-*, and the same exempt
 * class, whose pictures there are the form preview's phone and the Conversion Icon dialog's placeholder phone.
 *
 * The Uploads screens joined on 2026-09-30 ("Uploads click-through") on the same terms: the ladder, with one spacing and
 * one type step added (--fd-space-52, --fd-text-19), their widths and control boxes under --upl-*, and the exempt class,
 * whose pictures there are a tile and the clip box with what is drawn on them (the tick box, the play disc), the form
 * preview's phone and its skeleton lines and chips, and Manage Category's colour swatches. The pile pill sits in the top
 * bar, so it is chrome and reads --dc-chrome.
 *
 * The Assets screens joined on 2026-09-30 ("Assets click-through") on the same terms: the ladder as it stands, their
 * own widths under --as-*, and the exempt class, whose pictures there are the tiles and the clip box (the Uploads
 * pieces), Manage Content's feed frames and the playlist editor's thumbnails, frame and colour swatches.
 *
 * THE CHROME IS THE EXCEPTION ("Sidebar to the prototype", 2026-09-29, decisions 1 and 3; the top bar joined
 * the same day). The sidebar and the top bar are drawn to the prototype, and the prototype does not tighten
 * either on a laptop: the sidebar's width follows the viewport on a structural scale of its own (--u
 * below), and everything inside it — rows, group headers, type, the ladder, the person card — and the top
 * bar's height stay at the comfortable size on every screen. So the chrome reads its own switch,
 * --dc-chrome, which only the person's explicit Compact sets: the 1536px auto tier leaves it at 0, and a
 * person who chose Compact still gets a tighter chrome, which is what keeps the density rule true for the
 * preference. One switch rather than per-rule overrides: every chrome size that moves is written once,
 * against --dc-chrome — the sidebar block and the top bar's padding below. The pane is not chrome and
 * keeps --dc.
 */
:root { --dc: 0; --dc-chrome: 0; }
@media (max-width: 1536px) {
  :root:not([data-density="comfortable"]) { --dc: 1; }
}
:root[data-density="compact"] { --dc: 1; --dc-chrome: 1; }

:root {
  /* The prototype's structural unit (proto 899): 1px at a 1920px viewport, 0.84px at 1366px and below,
     linear in between. A length rather than a ratio because CSS cannot turn vw into a unitless number. */
  --u: clamp(0.84px, calc(0.4455px + 0.0289vw), 1px);
  /* The sidebar (proto 900: --nav-w 258 units expanded; proto 1509 / 26830: 64px rail). The width is the
     prototype's in every density — 258px at 1920, 216.7px at 1366 — and so is the rail, which holds 36px
     tiles that do not shrink. */
  --sidebar-w: calc(258 * var(--u));
  --sidebar-w-collapsed: 64px;
  /* Inside the sidebar: the sizes that tighten only when the person chose Compact (--dc-chrome above).
     A nav row (proto 34607: 8px 12px); the group header takes the same x so the labels stay in one column. */
  --nav-row-pad-y: calc(8px - 1px * var(--dc-chrome));
  --nav-row-pad-x: calc(12px - 1px * var(--dc-chrome));
  /* the ladder card and the row you stand on (proto 26831: 4px; proto 25765: 46px). The lit row's text inset
     is what reaches that height: comfortable is the prototype's 6px (proto 25765 `pad`); compact loses the
     4.875px between the prototype's 46.875px row and 42px as 0.625 from the name's step and 2.125 from
     each inset. */
  --ladder-pad: calc(4px - 1px * var(--dc-chrome));
  --rung-lit-h: calc(46px - 4px * var(--dc-chrome));
  --rung-lit-pad-y: calc(6px - 2.125px * var(--dc-chrome));
  /* the person card (proto 26836: 10px) */
  --usercard-pad: calc(10px - 2px * var(--dc-chrome));
  /* the 13.5px step a nav row and the rung you stand on are set in (proto 1574 · 25769) — the sidebar's
     own copy of --text-body, which the pane goes on tightening under the auto tier */
  --chrome-text-body: calc(13.5px - 0.5px * var(--dc-chrome));
  /* The rail's toggle block (proto 1651-1653): its top inset, how far it bleeds into the sidebar's padding,
     the button's inset and its icon. Constants rather than --dc-chrome sizes: the rail is out of the density
     layer (section header), and these are its geometry. */
  --rail-toggle-pad-top: 6px;
  --rail-toggle-bleed: 4px;
  --rail-toggle-pad-y: 9px;
  --rail-toggle-icon: 18px;
  /* the top bar's height is its padding (proto 1701); it is chrome, so it reads --dc-chrome (section note) */
  --bar-pad-top: calc(14px - 2px * var(--dc-chrome));
  --bar-pad-bottom: calc(12px - 2px * var(--dc-chrome));
  /* the pane's inset (proto 3334) */
  --pane-pad-y: calc(24px - 4px * var(--dc));
  --pane-pad-x: calc(28px - 4px * var(--dc));
  /* a stat tile (proto 3255) */
  --card-pad-y: calc(14px - 2px * var(--dc));
  --card-pad-x: calc(16px - 2px * var(--dc));
  /* a list cell, measured from the card's edge (proto 3365-3370) */
  --cell-pad-y: calc(11px - 2px * var(--dc));
  --cell-pad-x: calc(18px - 2px * var(--dc));
  --th-pad-y: calc(12px - 2px * var(--dc));
  /* The furniture the generic admin pane is built from, shared by the Team page and the Partner and
     organisation overviews (proto 3241 · 3265-3266 · 3287). The stat grid: the gap between its four
     cards and the space under it. */
  --tiles-gap: calc(12px - 2px * var(--dc));
  --tiles-space-below: calc(24px - 4px * var(--dc));
  /* the toolbar above a list: row gap first (it only shows when the controls wrap), then column gap */
  --toolbar-gap-y: calc(10px - 2px * var(--dc));
  --toolbar-gap-x: calc(12px - 2px * var(--dc));
  /* its two controls: the search field's width and the floor it shrinks to, and the select's inset */
  /* compact keeps the prototype's 280px (proto 3772), which is what fits its placeholders (W3b, 2026-10-06) */
  --search-w: calc(300px - 20px * var(--dc));
  --search-min-w: calc(180px - 20px * var(--dc));
  --select-pad-y: calc(9px - 1px * var(--dc));
  --select-pad-x: calc(12px - 2px * var(--dc));
  /* the pill a section heading's action wears; its label is on --text-xs below */
  --section-pill-pad-y: calc(7px - 1px * var(--dc));
  --section-pill-pad-x: calc(16px - 3px * var(--dc));
  /* the four type steps that move: the page title (proto 3213), the 13.5px body step a cell title,
     a member's name and a notice title share (the sidebar has its own, --chrome-text-body), the lede under a title (proto 3216), and the quiet step the
     smallest text on a page is set on — the settings notes and help lines, and the label on a section
     heading's pill. It is the floor: at compact it reads 12px and nothing that moves goes below. */
  --text-title: calc(21px - 2px * var(--dc));
  --text-body: calc(13.5px - 0.5px * var(--dc));
  --text-lede: calc(13px - 0.5px * var(--dc));
  --text-xs: calc(12.5px - 0.5px * var(--dc));
  /* The one step under that floor: the note a page ends on, which the prototype sets at 11.5px (proto
     3307) and the console's own stat sub-line already reads at. It does not move — delta 0 — because
     11.5px is where this ladder stops; it is a token so the size is named in one place, not typed
     into a rule. */
  --text-note: calc(11.5px - 0px * var(--dc));

  /* the sign-up flow: the rail's column and the sizes inside it (proto 973, 985, 999, 1012, 1093) */
  --auth-rail-w: calc(432px - 32px * var(--dc));
  --auth-rail-pad: calc(34px - 6px * var(--dc));
  --auth-title: calc(25px - 3px * var(--dc));
  /* a text field (proto 1076: 15px insets around the line its inputs fall back to) and the taller select and
     handle box, which carry the flow's own font (proto 1185, 1217) */
  --auth-field-h: calc(48px - 4px * var(--dc));
  --auth-select-h: calc(53px - 5px * var(--dc));
  --auth-card-pad: calc(18px - 4px * var(--dc));
  --auth-tile-pad: calc(12px - 2px * var(--dc));
  /* the preview pane: a card's inset, the organisation's tile and the name on it (proto 1139-1143) */
  --auth-preview-pad: calc(22px - 4px * var(--dc));
  --auth-preview-avatar: calc(62px - 8px * var(--dc));
  --auth-preview-title: calc(24px - 3px * var(--dc));
  /* sign-in is one card rather than a rail, so its sizes are its own */
  --auth-signin-card-w: calc(500px - 40px * var(--dc));
  --auth-signin-field-h: calc(48px - 4px * var(--dc));
  --auth-signin-title: calc(24px - 2px * var(--dc));
  /* sign-in's card inset and the mark above it (proto 1006/1012) */
  --auth-signin-gap: calc(24px - 4px * var(--dc));
  --auth-signin-pad-x: calc(32px - 4px * var(--dc));
  --auth-signin-brand: calc(56px - 4px * var(--dc));
  /* the hairline line a card ends on — sign-in's "New here?", the sign-up inbox's sign-in line, sign-out's way
     back: its block inset, which is also the card's bottom inset (rules review, "Sign-up by magic link", 2026-10-01) */
  --auth-signin-foot-pad: calc(12px - 2px * var(--dc));

  /* The auth surface's type ladder: the seven steps that move, smallest first. It stops at 12px — the
     compact end of --auth-text-xs — which is why every 12px label on these pages stays a literal. */
  --auth-text-xs: calc(12.5px - 0.5px * var(--dc));
  /* the quiet 13px step: the lines that say where a thing would live — the org's country, the preview's URL and
     type chip, a source chip — and the inbox page's Back row */
  --auth-text-quiet: calc(13px - 0.5px * var(--dc));
  --auth-text-sm: calc(13.5px - 0.5px * var(--dc));
  --auth-text: calc(14px - 0.5px * var(--dc));
  --auth-text-md: calc(14.5px - 0.5px * var(--dc));
  --auth-text-lg: calc(16px - 1px * var(--dc));
  --auth-preview-name: calc(20px - 2px * var(--dc));
  --auth-preview-initial: calc(34px - 4px * var(--dc));

  /* the rail's rhythm: the gap between a form's rows, the gap between tiles, and the paddings of the
     controls under them (proto 1007, 1065, 1124) */
  --auth-gap: calc(20px - 4px * var(--dc));
  /* the wider rhythm the two cards and the type list are set on (proto 1093, 1140, 1163); the strip's
     16px gap is another size, not this one, and stays where it is */
  --auth-gap-md: calc(18px - 2px * var(--dc));
  --auth-gap-sm: calc(14px - 2px * var(--dc));
  --auth-control-pad: calc(14px - 2px * var(--dc));
  --auth-ghost-pad-x: calc(24px - 4px * var(--dc));
  --auth-progress-gap: calc(30px - 6px * var(--dc));
  --auth-or-gap: calc(22px - 4px * var(--dc));
  /* the orb above the rail's title; sized here rather than in markup, so the density is the only thing that
     decides how big it is drawn */
  --auth-brand: calc(52px - 4px * var(--dc));

  /* the preview pane: how far it is inset, how wide the stack is, how far it sits above centre, and the
     workspace tile in its lower card (proto 1137, 1163) */
  --auth-preview-inset: calc(60px - 20px * var(--dc));
  --auth-preview-w: calc(530px - 50px * var(--dc));
  --auth-preview-lift: calc(120px - 40px * var(--dc));
  --auth-ws-tile: calc(56px - 6px * var(--dc));
  /* the workspace orbs: on a type card, in the preview's workspace tile, in the platform pill (proto 1201, 1351, 1372) */
  --auth-orb-card: calc(24px - 2px * var(--dc));
  --auth-orb-tile: calc(30px - 2px * var(--dc));
  --auth-orb-pill: calc(16px - 1px * var(--dc));

  /* The six-step sign-up's own sizes ("Six-step sign-up", 2026-10-07; proto 1051-1435). The three type steps under
     the 12px floor do not move — delta 0, as --text-note — and are tokens so each size is named once. */
  --auth-text-eyebrow: calc(10.5px - 0px * var(--dc));   /* "Single sign-on"; a team tile's initials */
  --auth-text-tiny: calc(11.5px - 0px * var(--dc));      /* the team card's role pill and "Pending" */
  --auth-text-help: calc(12px - 0px * var(--dc));        /* a rule line, a refused file, a role's description */
  --auth-text-picture: calc(15px - 1px * var(--dc));     /* "Profile picture", "Company logo" */
  --auth-or-gap-top: calc(26px - 4px * var(--dc));
  --auth-terms-top: calc(16px - 2px * var(--dc));        /* step 1: the field to the terms */
  --auth-terms-bottom: calc(22px - 4px * var(--dc));     /* the terms to Continue */
  --auth-continue-pad: calc(15px - 2px * var(--dc));     /* step 1's Continue */
  --auth-text-continue: calc(15px - 0.5px * var(--dc));
  --auth-invite-h: calc(44px - 4px * var(--dc));         /* an invite row's address, inside its box */
  --auth-or-gap-bottom: calc(16px - 2px * var(--dc));
  --auth-field-pad-x: calc(16px - 2px * var(--dc));      /* a field's inline inset */
  --auth-label-gap: calc(8px - 1px * var(--dc));         /* a glass card field's label to its input (.auth-field) */
  --auth-row-gap: calc(10px - 2px * var(--dc));          /* between invite rows; the label above them */
  --auth-invite-gap: calc(10px - 2px * var(--dc));       /* inside a row, a menu choice and a team row */
  --auth-role-gap: calc(6px - 1px * var(--dc));
  --auth-desc-gap: calc(2px - 0px * var(--dc));         /* a role's name to its description */
  --auth-check-nudge: calc(3px - 0px * var(--dc));      /* the check, down onto the name's line */
  --auth-picture: calc(76px - 8px * var(--dc));          /* the profile circle and the logo tile */
  --auth-picture-glyph: calc(26px - 2px * var(--dc));    /* the empty logo tile's picture glyph */
  --auth-picture-gap: calc(9px - 1px * var(--dc));       /* the title to its controls */
  --auth-picture-gap-sm: calc(8px - 1px * var(--dc));    /* between the controls; the rule line above */
  --auth-picture-error-gap: calc(5px - 1px * var(--dc)); /* a refused picture's sentence */
  --auth-logo-error-gap: calc(7px - 1px * var(--dc));    /* a refused logo's sentence */
  --auth-upload-pad-y: calc(8px - 1px * var(--dc));
  --auth-upload-pad-x: calc(13px - 2px * var(--dc));
  --auth-upload-bin: calc(36px - 4px * var(--dc));
  --auth-glyph: calc(16px - 1px * var(--dc));
  --auth-glyph-md: calc(15px - 1px * var(--dc));
  --auth-glyph-sm: calc(14px - 1px * var(--dc));
  --auth-menu-offset: calc(6px - 1px * var(--dc));
  --auth-menu-pad: calc(6px - 1px * var(--dc));
  --auth-role-menu-w: calc(286px - 20px * var(--dc));
  --auth-option-pad-y: calc(9px - 1px * var(--dc));      /* a role choice; a team card row */
  --auth-option-pad-x: calc(10px - 2px * var(--dc));
  --auth-add-pad-y: calc(7px - 1px * var(--dc));         /* Add another; a source chip */
  --auth-add-pad-x: calc(12px - 2px * var(--dc));
  --auth-team-help-gap: calc(16px - 2px * var(--dc));
  --auth-chip-gap: calc(9px - 1px * var(--dc));
  --auth-chip-icon-gap: calc(7px - 1px * var(--dc));
  --auth-chip-pad-x: calc(11px - 2px * var(--dc));
  --auth-nav-gap: calc(22px - 4px * var(--dc));          /* the bottom nav to what is under it */
  --auth-skip-lift: calc(6px - 1px * var(--dc));         /* Skip for now rides up into that space */
  --auth-skip-gap: calc(20px - 4px * var(--dc));
  --auth-strip-avatar: calc(32px - 2px * var(--dc));
  --auth-team-avatar: calc(28px - 2px * var(--dc));
  --auth-team-pad-top: calc(16px - 2px * var(--dc));
  --auth-team-pad-bottom: calc(10px - 2px * var(--dc));
  --auth-team-head-gap: calc(6px - 1px * var(--dc));
  --auth-team-pill-pad-y: calc(4px - 1px * var(--dc));
  --auth-team-pill-pad-x: calc(12px - 2px * var(--dc));
  --auth-team-more-pad-top: calc(8px - 1px * var(--dc));
  --auth-team-more-pad-bottom: calc(4px - 1px * var(--dc));
  /* the team card's waiting rows (proto 1410-1423): pure geometry standing in for text, so they do not move (delta 0) */
  --auth-skel-team-long: calc(170px - 0px * var(--dc));
  --auth-skel-team-short: calc(130px - 0px * var(--dc));
  --auth-skel-team-bar: calc(11px - 0px * var(--dc));
  --auth-skel-team-pill-w: calc(62px - 0px * var(--dc));
  --auth-skel-team-pill-h: calc(20px - 0px * var(--dc));

  /* The Team page ("Blinklink Team", 2026-09-25; proto 3282-3306). A member row's inset and the gap
     that runs through it — avatar to name, and between the items at its end — then the space a
     section takes and the space under its heading. */
  --team-row-pad-y: calc(12px - 2px * var(--dc));
  --team-row-pad-x: calc(16px - 2px * var(--dc));
  --team-row-gap: calc(13px - 2px * var(--dc));
  --team-section-gap: calc(24px - 4px * var(--dc));
  --team-head-gap: calc(10px - 2px * var(--dc));
  /* the head's rhythm: the head tile to the title (proto 3212), and the small step under a line —
     the title row under the breadcrumb (proto 3212) and the footer note under the sections (proto 3307) */
  --team-title-gap: calc(12px - 2px * var(--dc));
  --team-gap-xs: calc(4px - 1px * var(--dc));
  /* the two type steps a row moves on: the status text (proto 3299) and the action after it (proto
     3303). The 12px badge, chip and sub-line are already at this layer's floor and stay literal. */
  --team-status: calc(12.5px - 0.5px * var(--dc));
  --team-action: calc(13px - 0.5px * var(--dc));
  /* the monogram on the head tile (proto 3210) and on a member's avatar (proto 3294): the two boxes
     keep their size, because an icon box does not shrink — only the letter inside them moves */
  --team-tile-text: calc(15px - 1px * var(--dc));
  --team-avatar-text: calc(13px - 0.5px * var(--dc));
  /* the gap between the 2FA badge's shield and its word (proto 3300) and the role chip's inset
     (proto 3301); the chip's 12px type is at the floor above and stays literal */
  --team-badge-gap: calc(5px - 1px * var(--dc));
  --team-chip-pad-y: calc(4px - 1px * var(--dc));
  --team-chip-pad-x: calc(13px - 2px * var(--dc));
  /* the authority label after the role chip ("Team members list", 2026-10-05): the chip's height once its hairline
     border is counted, a narrower inset, and a type step half a pixel under the chip's so it reads as secondary */
  --team-authority-pad-y: calc(3px - 1px * var(--dc));
  --team-authority-pad-x: calc(9px - 2px * var(--dc));
  --team-authority-text: calc(11.5px - 0.5px * var(--dc));
  /* My Team in Account Settings (D205; prototype acctIsTeam, 3293-3331): the head's gap to the table (proto 20px), the
     actions' gap (16px), a cell's person cluster (10px), the Owner tag's inset (2px 8px) and its 10.5px type */
  --my-team-head-gap: calc(20px - 4px * var(--dc));
  --my-team-actions-gap: calc(16px - 4px * var(--dc));
  --my-team-person-gap: calc(10px - 2px * var(--dc));
  --my-team-owner-pad-y: calc(2px - 1px * var(--dc));
  --my-team-owner-pad-x: calc(8px - 1px * var(--dc));
  --my-team-owner-text: calc(10.5px - 0.5px * var(--dc));
  /* the count line's lift (2px), the role chip's own gap and inset (4px · 3px 4px), and the cells' small gaps (6-8px) */
  --my-team-count-gap: calc(2px - 1px * var(--dc));
  --my-team-chip-gap: calc(4px - 1px * var(--dc));
  --my-team-chip-pad-y: calc(3px - 1px * var(--dc));
  --my-team-chip-pad-x: calc(4px - 1px * var(--dc));
  --my-team-cell-gap: calc(6px - 1px * var(--dc));
  --my-team-button-gap: calc(8px - 2px * var(--dc));
  --my-team-avatar-text: calc(11.5px - 0.5px * var(--dc));

  /* A modal (proto 3613-3636 · 3757-3777): the dialog's column, its inset, and the scrim's inset
     around it, so the dialog still clears the viewport's edges on a short screen. */
  --modal-w: calc(440px - 40px * var(--dc));
  --modal-pad-y: calc(22px - 4px * var(--dc));
  --modal-pad-x: calc(24px - 4px * var(--dc));
  --modal-inset: calc(20px - 4px * var(--dc));
  /* its rhythm: under the title, above a field's label, under it, above the footer, between two chips
     or buttons, and the extra space that sets the destructive link apart from them (proto 3769) */
  --modal-sub-gap: calc(3px - 1px * var(--dc));
  --modal-field-gap: calc(16px - 4px * var(--dc));
  --modal-label-gap: calc(7px - 1px * var(--dc));
  --modal-foot-gap: calc(20px - 4px * var(--dc));
  --modal-gap: calc(10px - 1px * var(--dc));
  --modal-foot-split: calc(6px - 1px * var(--dc));
  /* the controls in it: the text field, a role chip, a footer button */
  --modal-input-pad-y: calc(11px - 2px * var(--dc));
  --modal-input-pad-x: calc(14px - 2px * var(--dc));
  --modal-chip-pad-y: calc(8px - 1px * var(--dc));
  --modal-chip-pad-x: calc(16px - 3px * var(--dc));
  --modal-button-pad: calc(11px - 2px * var(--dc));
  /* its three type steps: the title, a field label, and the body step the input and buttons share */
  --modal-title: calc(16px - 1px * var(--dc));
  --modal-label: calc(12.5px - 0.5px * var(--dc));
  --modal-text: calc(13px - 0.5px * var(--dc));

  /* The Workspaces directory ("Workspaces directory", 2026-09-25; proto 3480-3536). Its toolbar is the
     house toolbar at this pane's own two sizes: a tighter space under it (proto 3480) and a narrower
     search field (proto 3481). */
  --wsdir-toolbar-space: calc(14px - 2px * var(--dc));
  --wsdir-search-w: calc(280px - 28px * var(--dc));
  /* The nine-column row (proto 3495-3530): the header's and a data row's vertical inset — the horizontal
     one is the card's own --cell-pad-x — the gap between two columns, and the fixed column the two row
     actions stand in. */
  --wsdir-head-pad-y: calc(12px - 2px * var(--dc));
  --wsdir-row-pad-y: calc(10px - 2px * var(--dc));
  --wsdir-col-gap: calc(12px - 2px * var(--dc));
  --wsdir-actions-w: calc(230px - 20px * var(--dc));
  /* the Plan · Billing and Status tracks floor at their widest chip — Ecosystem, Suspended — so a pill never clips while
     the text columns, which ellipsise, give way first (W3b/W4 review, 2026-10-06); the pill's 12px type does not move */
  --wsdir-plan-min: calc(80px - 6px * var(--dc));
  --wsdir-status-min: calc(94px - 0px * var(--dc));
  /* the Last active track's floor: "3 months ago", the meter's longest literal, on one line (final UI pass, 2026-10-06) */
  --wsdir-last-min: calc(80px - 4px * var(--dc));
  --wsdir-actions-gap: calc(8px - 1px * var(--dc));
  /* inside a cell: the workspace tile to its handle (proto 24630), the org monogram to its name (24631) */
  --wsdir-cell-gap: calc(10px - 2px * var(--dc));
  --wsdir-org-gap: calc(8px - 1px * var(--dc));
  /* the row's own body step, the type pill's inset (proto 24632), and the billing-model chip's inset with
     the space that sets it under the plan (proto 24633) */
  --wsdir-text: calc(13px - 0.5px * var(--dc));
  --wsdir-type-pad-y: calc(3px - 1px * var(--dc));
  --wsdir-type-pad-x: calc(10px - 2px * var(--dc));
  --wsdir-model-pad-y: calc(2px - 0px * var(--dc));
  --wsdir-model-pad-x: calc(8px - 1px * var(--dc));
  --wsdir-model-gap: calc(3px - 1px * var(--dc));
  /* The two steps under this layer's 11.5px floor: the model chip's label and the line under the usage
     headline. Both have a delta of 0, for the reason --text-note above has one — the ladder stops there. */
  --wsdir-model-text: calc(10.5px - 0px * var(--dc));
  --wsdir-usage-sub: calc(11px - 0px * var(--dc));
  /* the two buttons at the end of a row (proto 3521-3522): the bordered Manage, and the accent pill that
     steps into the workspace */
  --wsdir-ghost-pad-y: calc(6px - 1px * var(--dc));
  --wsdir-ghost-pad-x: calc(11px - 2px * var(--dc));
  --wsdir-open-pad-y: calc(7px - 1px * var(--dc));
  --wsdir-open-pad-x: calc(12px - 2px * var(--dc));
  --wsdir-open-gap: calc(6px - 1px * var(--dc));
  /* the strip under the card (proto 3531): how far under it sits, the gap between the count and the
     legend, and the gap inside one legend item */
  --wsdir-foot-space: calc(10px - 2px * var(--dc));
  --wsdir-foot-gap-y: calc(8px - 1px * var(--dc));
  --wsdir-foot-gap-x: calc(16px - 3px * var(--dc));
  --wsdir-legend-gap: calc(8px - 1px * var(--dc));
  /* the gap between two fields paired on a dialog row (proto 3732) */
  --modal-col-gap: calc(12px - 2px * var(--dc));
  /* Create Org and New Partner (W3c, 2026-10-06): the prototype's 500px dialog (proto 3965), the rule and the
     uppercase label that open its "First workspace" part (4000-4001), and a field's hint line (4006). */
  --onboard-modal-w: calc(500px - 40px * var(--dc));
  --onboard-section-gap: calc(18px - 4px * var(--dc));
  --onboard-section-pad: calc(14px - 3px * var(--dc));
  --onboard-section-label: calc(12px - 0.5px * var(--dc));
  --onboard-hint-gap: calc(5px - 1px * var(--dc));
  --onboard-notice-gap: calc(14px - 3px * var(--dc));
  /* The usage meter (proto 24634): the bar, its longest run, and the space above and below it. The height
     does not move — a 4px bar is geometry, like a hairline or an icon box. */
  --meter-h: calc(4px - 0px * var(--dc));
  --meter-w: calc(120px - 12px * var(--dc));
  --meter-space-above: calc(4px - 1px * var(--dc));
  --meter-space-below: calc(3px - 1px * var(--dc));
  /* the gap between a cell's status pills (W3b, 2026-10-06): below this layer's floor at compact */
  --chip-group-gap: calc(4px - 1px * var(--dc));
  /* The Orgs directory's seven-column row (W3b, 2026-10-06; proto 3787-3814): the gap between columns, the fixed
     chevron column, the tile-to-text gap, the dots' own gap and the gap to the count beside them, the stack of
     usage lines and the dot-to-figure gap in each, the row's type step and the usage line's, and the space from
     the card down to the count under it. The 3px dot gap and the 40px chevron column are geometry and do not move. */
  --orgdir-col-gap: calc(12px - 2px * var(--dc));
  --orgdir-open-w: calc(40px - 0px * var(--dc));
  --orgdir-cell-gap: calc(11px - 2px * var(--dc));
  --orgdir-dots-gap: calc(3px - 0px * var(--dc));
  --orgdir-ws-gap: calc(8px - 1px * var(--dc));
  --orgdir-usage-gap: calc(3px - 1px * var(--dc));
  --orgdir-meter-gap: calc(6px - 1px * var(--dc));
  --orgdir-text: calc(13px - 0.5px * var(--dc));
  --orgdir-usage-text: calc(12px - 0px * var(--dc));
  --orgdir-foot-space: calc(10px - 2px * var(--dc));

  /* the way back out of a detail page (proto 3368): the space under the link. Its 12.5px label is the
     --text-xs step above, and the arrow beside it is an icon box. */
  --back-space: calc(12px - 2px * var(--dc));
  /* and the space above it: where the prototype's 16px line seats the link (measured 2026-10-03) */
  --back-lift: calc(2.5px - 0.5px * var(--dc));

  /* The organisation's page ("Org as a stop", 2026-09-28; proto 3367-3387 · 3537-3607). Its identity card:
     the card's inset, the gap that runs through it (tile to text, text to each action, action to action),
     the space under it, the gap between the name and the two chips beside it, and the step down to the
     meta line. */
  --org-head-pad-y: calc(18px - 3px * var(--dc));
  --org-head-pad-x: calc(20px - 4px * var(--dc));
  --org-head-gap: calc(16px - 3px * var(--dc));
  --org-head-space: calc(16px - 3px * var(--dc));
  --org-head-title-gap: calc(10px - 2px * var(--dc));
  --org-head-meta-gap: calc(4px - 1px * var(--dc));
  /* the handle pill beside the name (proto 3375); its 11.5px label is the --text-note step above */
  --org-chip-pad-y: calc(4px - 1px * var(--dc));
  --org-chip-pad-x: calc(11px - 2px * var(--dc));
  /* the org's name on the card (proto 3373); the 52px tile under it is an icon box and stays literal, as
     the Team page's head tile does — only the monogram in it moves */
  --org-name: calc(20px - 2px * var(--dc));
  --org-tile-text: calc(22px - 2px * var(--dc));
  /* the space under the tiles and each of the Overview's cards (proto 3547) — the sections' own rhythm, one
     step tighter than the Team page's, which is why it is a token of its own */
  --org-section-space: calc(22px - 4px * var(--dc));

  /* The Partners screens ("Partners click-through", 2026-10-03; proto 3351-3468 · 3791-3830 · 3985-4018). The
     generic pane's furniture is the Team page's and the house modal's; these are the sizes they add: the gap
     between the scope chip and the head's two buttons (proto 3376), and the two Partner dialogs — their column
     (460px, proto 3794 · 3988), the step above every label after the first (proto 3800: 14px, a step under the
     house modal's 16px), a select's inset (proto 3805: 10px 12px,
     a step inside a text field's), the logo row's gap and the monogram in its preview, and the gap between the
     Status chips (proto 4011). The 44px preview tile is geometry, written here with no delta as --meter-h is, so the
     page names no literal size; its 12px corner (proto 4007) is a radius, which density leaves alone, between the
     ladder's 10px and 14px steps. */
  --partner-logo-radius: 12px;
  --partner-head-gap: calc(10px - 2px * var(--dc));
  /* the primary head button's side inset: no delta because the pane's quiet button beside it is a constant 9px 16px
     (console.css, pane buttons), and the two must stay the same width step */
  --partner-head-button-pad-x: calc(16px - 0px * var(--dc));
  --partner-modal-w: calc(460px - 40px * var(--dc));
  --partner-field-gap: calc(14px - 3px * var(--dc));
  --partner-select-pad-y: calc(10px - 2px * var(--dc));
  --partner-select-pad-x: calc(12px - 2px * var(--dc));
  --partner-logo-gap: calc(12px - 2px * var(--dc));
  --partner-logo-box: calc(44px - 0px * var(--dc));
  --partner-logo-text: calc(16px - 1px * var(--dc));
  --partner-chip-gap: calc(7px - 1px * var(--dc));
  /* Edit Org's column ("Org archive and rename", 2026-10-14): the prototype's Edit organization is 480px, a step wider
     than the Partner dialogs' 460px; its fields keep their rhythm */
  --org-modal-w: calc(480px - 40px * var(--dc));

  /* The Feeds screens ("Feeds click-through", 2026-09-29; section note above). The spacing ladder: */
  /* one pixel of inset, the Live pill's (5625): the ladder's bottom step, which compact leaves as it is */
  --fd-space-1: calc(1px - 0px * var(--dc));
  --fd-space-2: calc(2px - 0px * var(--dc));
  --fd-space-2-5: calc(2.5px - 0.5px * var(--dc));
  --fd-space-3: calc(3px - 0.5px * var(--dc));
  --fd-space-4: calc(4px - 1px * var(--dc));
  --fd-space-5: calc(5px - 1px * var(--dc));
  --fd-space-6: calc(6px - 1px * var(--dc));
  --fd-space-7: calc(7px - 1px * var(--dc));
  --fd-space-8: calc(8px - 1px * var(--dc));
  --fd-space-9: calc(9px - 1px * var(--dc));
  --fd-space-10: calc(10px - 2px * var(--dc));
  --fd-space-11: calc(11px - 2px * var(--dc));
  --fd-space-12: calc(12px - 2px * var(--dc));
  --fd-space-13: calc(13px - 2px * var(--dc));
  --fd-space-14: calc(14px - 2px * var(--dc));
  --fd-space-15: calc(15px - 2px * var(--dc));
  --fd-space-16: calc(16px - 3px * var(--dc));
  --fd-space-18: calc(18px - 3px * var(--dc));
  --fd-space-20: calc(20px - 4px * var(--dc));
  --fd-space-22: calc(22px - 4px * var(--dc));
  --fd-space-24: calc(24px - 4px * var(--dc));
  --fd-space-26: calc(26px - 4px * var(--dc));
  --fd-space-28: calc(28px - 4px * var(--dc));
  --fd-space-30: calc(30px - 5px * var(--dc));
  --fd-space-32: calc(32px - 5px * var(--dc));
  --fd-space-36: calc(36px - 6px * var(--dc));
  /* the Conversions form's Add Conversion inset (2635) — the one step that screen adds to this ladder */
  --fd-space-40: calc(40px - 6px * var(--dc));
  --fd-space-42: calc(42px - 6px * var(--dc));
  --fd-space-44: calc(44px - 6px * var(--dc));
  /* Single Asset Upload's Add / Update inset (8267) — the Uploads screens' one step on this ladder */
  --fd-space-52: calc(52px - 8px * var(--dc));
  --fd-space-60: calc(60px - 10px * var(--dc));
  /* the type ladder, from the layer's 12.5px step up */
  --fd-text-12-5: calc(12.5px - 0.5px * var(--dc));
  --fd-text-13: calc(13px - 0.5px * var(--dc));
  --fd-text-13-5: calc(13.5px - 0.5px * var(--dc));
  --fd-text-14: calc(14px - 0.5px * var(--dc));
  --fd-text-14-5: calc(14.5px - 0.5px * var(--dc));
  --fd-text-15: calc(15px - 0.5px * var(--dc));
  --fd-text-15-5: calc(15.5px - 0.5px * var(--dc));
  --fd-text-16: calc(16px - 1px * var(--dc));
  --fd-text-16-5: calc(16.5px - 1px * var(--dc));
  --fd-text-17: calc(17px - 1px * var(--dc));
  /* the empty queue's heading (7433) — the Uploads screens' one step on this ladder */
  --fd-text-19: calc(19px - 2px * var(--dc));
  --fd-text-20: calc(20px - 2px * var(--dc));
  --fd-text-21: calc(21px - 2px * var(--dc));
  --fd-text-22: calc(22px - 2px * var(--dc));
  /* the company monogram's letter, in its 44px and 56px boxes (14576 · 15663) — the box stays, the letter moves */
  --fd-text-24: calc(24px - 2px * var(--dc));
  --fd-text-26: calc(26px - 2px * var(--dc));
  /* Widths the prototype fixes in px: the search pill (1771), a feed card (1872), the platform card (1816), a module
     tile and its picture (1828-1829), the form column (14574), the promo's placeholder (14635), the switcher and its
     menu and list (15045 · 15054 · 15059), the editor's rail and settings column (15100 · 15138), Feed Settings' rail
     (15643), the On | Off and Div | UI Trigger segments (15724 · 15788), a platform row's name (15734), and the
     room the snippet leaves for Copy (15795). The search's left inset is where its text starts after the glyph. */
  --fd-search-w: calc(270px - 30px * var(--dc));
  --fd-search-inset: calc(42px - 6px * var(--dc));
  /* Two boxes the prototype draws in its fallback font (Arial, its inputs name no font — 1773 · 14585) and the console in
     Poppins, whose line box is taller: the vertical insets that keep the prototype's 39px search pill and 46px Create
     Feed title field around Poppins' line. */
  --fd-search-pad-y: calc(8.5px - 1.5px * var(--dc));
  --fd-create-input-pad-y: calc(11.5px - 1.5px * var(--dc));
  --fd-card-w: calc(420px - 30px * var(--dc));
  --fd-platform-w: calc(660px - 40px * var(--dc));
  --fd-module-w: calc(146px - 10px * var(--dc));
  --fd-module-h: calc(96px - 6px * var(--dc));
  --fd-form-w: calc(620px - 40px * var(--dc));
  --fd-promo-art-h: calc(280px - 40px * var(--dc));
  --fd-switcher-w: calc(260px - 20px * var(--dc));
  --fd-switcher-menu-w: calc(320px - 20px * var(--dc));
  --fd-switcher-list-h: calc(280px - 40px * var(--dc));
  --fd-rail-w: calc(250px - 20px * var(--dc));
  --fd-settings-w: calc(300px - 20px * var(--dc));
  --fd-fs-rail-w: calc(290px - 30px * var(--dc));
  --fd-seg-mode-w: calc(320px - 20px * var(--dc));
  --fd-seg-tabs-w: calc(240px - 20px * var(--dc));
  --fd-platform-name-w: calc(70px - 6px * var(--dc));
  --fd-snippet-pad-end: calc(92px - 8px * var(--dc));
  /* Control boxes the prototype fixes in px (the rules review, 2026-09-29, "Feeds click-through"): the stepper's two
     buttons (15172-15173), the re-check button (15785) and the Platforms toggle with its knob (15736, 36 × 20 around a
     16px knob). Density moves them like any control; a glyph inside keeps its size. */
  --fd-control-28: calc(28px - 4px * var(--dc));
  --fd-control-26: calc(26px - 4px * var(--dc));
  --fd-switch-w: calc(36px - 4px * var(--dc));
  --fd-switch-h: calc(20px - 2px * var(--dc));
  --fd-switch-knob: calc(16px - 2px * var(--dc));
  /* Round 2 ("Feeds as the workspace's home", 2026-09-29): the module status toggle (2178: 38 × 21 around a 17px knob,
     which sits at 16px when on), What is it?'s dialog and its dark side (16560 · 16561), Manage Whitelist's dialog
     (15467: 660 wide, min(640px, 84vh) tall), its list's floor (15496: 120px) and its row menu (15522), and Configure
     Platform's placeholder (14563). */
  --fd-mswitch-w: calc(38px - 4px * var(--dc));
  --fd-mswitch-h: calc(21px - 2px * var(--dc));
  --fd-mswitch-knob: calc(17px - 2px * var(--dc));
  --fd-mswitch-on: calc(16px - 2px * var(--dc));
  --fd-about-w: calc(820px - 60px * var(--dc));
  --fd-about-art-w: calc(290px - 20px * var(--dc));
  --fd-wl-w: calc(660px - 40px * var(--dc));
  --fd-wl-h: calc(640px - 40px * var(--dc));
  --fd-wl-menu-w: calc(160px - 10px * var(--dc));
  --fd-wl-scroll-min: calc(120px - 20px * var(--dc));
  --fd-setup-art-h: calc(300px - 40px * var(--dc));
  /* The sizes the prototype writes against its --u (proto 899): the right panel (--panel-w, 902), Create Feed's two
     columns' insets (14573 · 14621), the editor's rail and canvas insets (15100 · 15355), and Feed Settings' rail
     and pane insets (15643 · 15658). Structural, like the sidebar's width: they follow the viewport, not --dc. */
  --fd-panel-w: calc(400 * var(--u));
  --fd-create-pad-x: calc(60 * var(--u));
  --fd-preview-pad-x: calc(36 * var(--u));
  --fd-rail-pad-x: calc(10 * var(--u));
  --fd-canvas-pad-x: calc(36 * var(--u));
  --fd-fs-rail-pad-x: calc(20 * var(--u));
  --fd-fs-pad-x: calc(40 * var(--u));

  /* The Conversions screens ("Conversions click-through", 2026-09-30). They are drawn to the same prototype as the Feeds
     screens, with sizes of the same kind, so they take the Feeds ladder above for every spacing and type step. What
     they add: the widths and control boxes the prototype fixes in px — the search pill (2423), the card's preview well
     (2441), the form column (2552), the Conversion Icon dialog (2673), the Select Icon popover and its tiles (2696 ·
     2698), a preset's bar (2684) and Show icon's knob (2740, in the Feeds screens' 38 × 21 module switch box); and
     the inset of the two fields the prototype draws in its fallback font (Arial: Title and the button's text name no
     font, 2567 · 2627), which keeps their 44px box around Poppins' taller line, as --fd-search-pad-y does the search's.
     The preview's phone and the dialog's placeholder phone are pictures at the prototype's geometry and stay literal. */
  --cv-search-w: calc(250px - 30px * var(--dc));
  --cv-well-h: calc(130px - 20px * var(--dc));
  --cv-form-w: calc(640px - 40px * var(--dc));
  --cv-system-pad-y: calc(10.5px - 1.5px * var(--dc));
  --cv-dialog-w: calc(880px - 60px * var(--dc));
  --cv-picker-w: calc(252px - 24px * var(--dc));
  --cv-picker-tile-h: calc(36px - 4px * var(--dc));
  --cv-preset-h: calc(34px - 4px * var(--dc));
  --cv-switch-knob: calc(15px - 2px * var(--dc));
  /* the sizes the prototype writes against its --u: the grid's column floor and gap (--cta-min, --gap-grid; 903-904) and
     the form's horizontal inset (2551). The right panel is --fd-panel-w and the preview's inset --fd-preview-pad-x, the
     same 400u and 36u. Structural: they follow the viewport, not --dc. */
  --cv-card-min: calc(225 * var(--u));
  --cv-grid-gap: calc(16 * var(--u));
  --cv-form-pad-x: calc(48 * var(--u));

  /* The Uploads screens ("Uploads click-through", 2026-09-30; section note above). The top bar's pile pill (1712-1714):
     its inset, the gap between its piles, the room after it, and a pile's inset and type — chrome, so --dc-chrome. */
  --upl-pill-inset: calc(3px - 0.5px * var(--dc-chrome));
  --upl-pill-gap: calc(2px - 0.5px * var(--dc-chrome));
  --upl-pill-end: calc(6px - 1px * var(--dc-chrome));
  --upl-tab-pad-y: calc(7px - 1px * var(--dc-chrome));
  --upl-tab-pad-x: calc(16px - 2px * var(--dc-chrome));
  --upl-tab-text: calc(13px - 0.5px * var(--dc-chrome));
  /* the widths and control boxes the prototype fixes in px: the empty queue's line (7434), the grid pager's buttons
     (7519), the review panel's icon bar (7597-7601) and Request revision (7769), the file's × (8101), a category's ⋯
     (8136) and its fade (8153), the CTA menu's name column (8242), Manage Category's × (8168), and the three dialogs
     (7784 · 7804 · 8165) */
  --upl-empty-w: calc(440px - 40px * var(--dc));
  /* the upload status screen's card ("Upload form on content-v5", 2026-10-08) */
  --upl-status-w: calc(560px - 40px * var(--dc));
  --upl-control-32: calc(32px - 4px * var(--dc));
  --upl-control-34: calc(34px - 4px * var(--dc));
  --upl-control-46: calc(46px - 6px * var(--dc));
  --upl-control-24: calc(24px - 2px * var(--dc));
  --upl-control-18: calc(18px - 2px * var(--dc));
  --upl-fade-w: calc(46px - 6px * var(--dc));
  --upl-cta-kind-w: calc(170px - 20px * var(--dc));
  /* the CTA menu's ceiling — console-authored: the prototype's menu holds four rows and names none */
  --upl-cta-menu-h: calc(420px - 40px * var(--dc));
  --upl-revise-w: calc(460px - 30px * var(--dc));
  --upl-confirm-w: calc(430px - 30px * var(--dc));
  /* Add to Feed's chooser (FeedChooser, 2026-10-20; console-authored): Manage Content's cards with an Add beside each */
  --as-chooser-w: calc(520px - 40px * var(--dc));
  --upl-mgr-w: calc(720px - 40px * var(--dc));
  --upl-mgr-h: calc(660px - 40px * var(--dc));
  /* the form preview's skeleton tag chips (uploadTagPlaceholders 23876): the six widths the nine of them take */
  --upl-skel-chip-44: calc(44px - 6px * var(--dc));
  --upl-skel-chip-46: calc(46px - 6px * var(--dc));
  --upl-skel-chip-50: calc(50px - 6px * var(--dc));
  --upl-skel-chip-52: calc(52px - 6px * var(--dc));
  --upl-skel-chip-58: calc(58px - 8px * var(--dc));
  --upl-skel-chip-64: calc(64px - 8px * var(--dc));
  /* the sizes the prototype writes against its --u: the grid's column floor and a tile's height (--tile-min, --tile-h;
     905 · 907). The grid's gap is --cv-grid-gap (--gap-grid), the panel --fd-panel-w, the form's insets --cv-form-pad-x
     and --fd-preview-pad-x — the same units. Structural: they follow the viewport, not --dc. */
  --upl-tile-min: calc(185 * var(--u));
  --upl-tile-h: calc(300 * var(--u));
  /* The Assets screens ("Assets click-through", 2026-09-30) take the Feeds ladder for every spacing and type step that
     moves, the Uploads boxes for the controls they share, and these widths of their own: the playlist editor's box and rail
     (7113 · 7165), its Icon menu (7131) and a row menu (7327). The rail's inset is written against the prototype's --u
     (7165), structural like the grid's column floor; the Asset Details clip box's 42vh (27638) is a share of the viewport,
     not a density step. */
  --as-editor-w: calc(960px - 60px * var(--dc));
  --as-editor-h: calc(660px - 40px * var(--dc));
  --as-rail-w: calc(340px - 30px * var(--dc));
  --as-icons-w: calc(232px - 20px * var(--dc));
  --as-menu-w: calc(160px - 10px * var(--dc));
  --as-rail-pad-x: calc(24 * var(--u));
  /* Email domains ("Email domains", 2026-10-14): the section's stack, a claim's row and the gaps inside it, the DNS
     table's cells (the prototype's Custom Domain table, 12px 16px · 13px 16px, decoded 17027-17029), its 13px text, and
     the Copy button's inset. The 12px copy glyph is an icon box and stays literal, as the directory's are. */
  --domains-gap: calc(14px - 3px * var(--dc));
  --domains-row-pad-y: calc(14px - 3px * var(--dc));
  --domains-row-gap: calc(10px - 2px * var(--dc));
  --domains-label-gap: calc(6px - 1px * var(--dc));
  --domains-cell-pad-y: calc(12px - 2px * var(--dc));
  --domains-cell-pad-x: calc(16px - 2px * var(--dc));
  --domains-text: calc(13px - 0.5px * var(--dc));
  --domains-copy-pad-y: calc(4px - 1px * var(--dc));
  --domains-copy-pad-x: calc(10px - 2px * var(--dc));
}

/* Workspace flavor accent. Haze and Wash take their paper hue from --flavor, so this also
 * decides what the light themes tint with. A workspace names its own section ink; a console level
 * uses the level colour itself, which is what the prototype does above a workspace
 * (proto 22317: sectionColor = levelColor). */
:root[data-workspace-flavor="skills"] { --flavor: var(--skills); --flavor-soft: var(--skills-soft); --flavor-section: var(--skills-section); }
:root[data-workspace-flavor="social"] { --flavor: var(--social); --flavor-soft: var(--social-soft); --flavor-section: var(--social-section); }
/* Ladder levels above a workspace: the Blinklink row is gold, an organisation violet */
:root[data-workspace-flavor="platform"] { --flavor: var(--platform); --flavor-soft: var(--platform-soft); --flavor-section: var(--platform); }
:root[data-workspace-flavor="org"] { --flavor: var(--org); --flavor-soft: var(--org-soft); --flavor-section: var(--org); }
:root[data-workspace-flavor="msp"] { --flavor: var(--msp); --flavor-soft: var(--msp-soft); --flavor-section: var(--msp); }
