/* Mise Design System — source of truth: Figma "Mise — Inso" (RqAfmeFH8J7aK07fkLzxzz)
 * Design system page 92:1190 + Home screens. Token direction: Figma → code.
 *
 * HOW THIS FILE IS LAID OUT (Session 98, ramp added 2026-09-28)
 *   0. The ramp — the only raw colours. Everything else points here.
 *   1. Legacy fixed greys + the old --color-* one-offs that V2 never replaced.
 *   2. V2 — the live names. Semantic names, built on the ramp.
 *   3. Overlay windows — the shake shelf and the notch pill.
 *   4. The dark set.
 *   5. Legacy V1 names → V2. Every old --color-* name resolves from here.
 *
 * THE RAMP, IN PLAIN WORDS (design audit 2026-09-28, sections 1 and 2)
 *   Greys run --gray-0 to --gray-12. Each step has one job:
 *     0 white: cards, menus, dialogs      7  strong border
 *     1 app background                    8  disabled text
 *     2 window and sidebar                9  quiet icon
 *     3 grey fill, hairline               10 hint text
 *     4 hover                             11 second-line text
 *     5 pressed, focus fill               12 main text
 *     6 subtle border, field edge
 *   The dark set re-declares every step, so a name picks the right grey in
 *   both themes. Colours (blue, red, green, amber, purple) have four steps:
 *     3 a soft wash behind something
 *     4, 5 that wash under the pointer, and pressed (blue and red only)
 *     9 a solid fill with a white label
 *     10 that fill under the pointer
 *     11 the colour used as text on white
 *   New code names a ramp step or a semantic name built on one. The older
 *   --v2-* and --color-* names still work: they point at the ramp.
 *
 * Three rules for this file:
 *   - One notation: OKLCH. No hex, no rgb(), anywhere, ever. The hex written
 *     in a comment is a reading aid only — the OKLCH value is the truth.
 *   - One number in one place. If two names mean the same colour, the second
 *     one is `var(--the-first)`.
 *   - VALUES ONLY. No selectors, no component rules. The .btn / .type-* /
 *     .v2-* blocks that used to live here moved to ui/src/styles/controls.css
 *     in Session 98. If you are about to write a `{`, you are in the wrong file.
 *
 * Monochrome UI. Exceptions: --color-destructive, folder/board colours,
 * --v2-brand-blue (primary actions), --v2-success, the prism shimmer.
 * UI font is SF Pro (system). GT Flexa Mono is font-library content only.
 */

/* ---------- 0. The ramp — light values. Dark values are in the dark set. ---------- */
:root {
  /* Greys. Chroma 0. Even 0.02 steps for grounds and fills, wider for text. */
  --gray-0:  oklch(1 0 0);
  --gray-1:  oklch(0.98 0 0);
  --gray-2:  oklch(0.96 0 0);
  --gray-3:  oklch(0.94 0 0);
  --gray-4:  oklch(0.92 0 0);
  --gray-5:  oklch(0.90 0 0);
  --gray-6:  oklch(0.88 0 0);
  --gray-7:  oklch(0.84 0 0);
  --gray-8:  oklch(0.78 0 0);
  --gray-9:  oklch(0.66 0 0);   /* 3:1 on the window, so a quiet icon still reads */
  --gray-10: oklch(0.525 0 0);  /* 4.5:1 on the window grey, for hint text */
  --gray-11: oklch(0.42 0 0);
  --gray-12: oklch(0.24 0 0);

  /* Colours. One lightness band per job; the hue stays where it was. */
  --blue-3:  oklch(0.96 0.018 266);
  --blue-4:  oklch(0.93 0.0234 266);  /* the blue wash under the pointer */
  --blue-5:  oklch(0.90 0.0288 266);  /* the blue wash while pressed */
  --blue-9:  oklch(0.55 0.20 266);
  --blue-10: oklch(0.515 0.20 266);
  --blue-11: oklch(0.50 0.19 266);

  --red-3:  oklch(0.96 0.018 27);
  --red-4:  oklch(0.93 0.0234 27);   /* the red wash under the pointer */
  --red-5:  oklch(0.90 0.0288 27);   /* the red wash while pressed */
  --red-9:  oklch(0.555 0.20 27);
  --red-10: oklch(0.52 0.20 27);
  --red-11: oklch(0.51 0.19 27);

  --green-3:  oklch(0.96 0.024 150);
  --green-9:  oklch(0.55 0.15 150);
  --green-10: oklch(0.515 0.15 150);
  --green-11: oklch(0.50 0.13 150);

  --amber-3:  oklch(0.96 0.028 70);
  --amber-9:  oklch(0.55 0.115 70);
  --amber-10: oklch(0.515 0.115 70);
  --amber-11: oklch(0.50 0.105 70);

  --purple-3:  oklch(0.96 0.02 305);
  --purple-9:  oklch(0.55 0.18 305);
  --purple-10: oklch(0.515 0.18 305);
  --purple-11: oklch(0.50 0.17 305);

  /* The storage meter when it is nearly full: brighter than amber-9 so it
   * reads as a warning on a bar, calmer than red. */
  --warning-meter: oklch(0.64 0.14 70);

  /* Fixed colours. These never change with Light / Dark: the dark set does
   * not re-declare them, on purpose. */
  /* The HUD: a small dark panel floating over anything — tooltip, selection
   * bar, toast. It stays dark in both themes, so its words stay white. */
  --hud-bg:             oklch(0.24 0 0 / 0.94);
  --hud-text:           oklch(1 0 0);         /* words on the HUD */
  --hud-text-secondary: oklch(1 0 0 / 0.72);  /* second-line words, counts */
  --hud-divider:        oklch(1 0 0 / 0.16);  /* the thin line between HUD groups */
  --hud-key-bg:         oklch(1 0 0 / 0.16);  /* a key cap inside a tooltip */
  /* Text or a thumb sitting on a coloured fill (a blue button, a red
   * button, a switch track). Always white. */
  --on-fill:            oklch(1 0 0);
  /* A mark drawn on something that is light whatever the theme — a tick on
   * a pale colour swatch, a glyph on a photo. Always dark grey. */
  --on-light-fixed:     oklch(0.24 0 0);
}

:root {
  /* Legacy fixed greys (V1). Chroma 0. These do NOT follow the theme — they
   * are the same grey in Light and Dark, which is why almost nothing paints
   * with them any more. Only these five steps are still read; the live
   * ramp is --gray-* at the top of the file. Do not add uses. The nine
   * unused steps were deleted 2026-09-28. */
  --neutral-0:    oklch(1 0 0);      /* #ffffff */
  --neutral-300:  oklch(0.87 0 0);   /* #d4d4d4 */
  --neutral-700:  oklch(0.439 0 0);  /* #525252 — Figma nav label */
  --neutral-800:  oklch(0.28 0 0);   /* #292929 */
  --neutral-1000: oklch(0 0 0);      /* #000000 */

  --color-white: var(--neutral-0);
  /* The Mise crown. Black in light, white in dark — it follows the theme,
   * not the text around it, so the mark can be tinted in one place without
   * dragging every label with it. Wired up Session 98; before that the
   * crown quietly inherited the text colour and this token painted
   * nothing. Only the mark may use it. */
  --color-logo: var(--v2-neutral-1000);

  /* Sidebar leftovers — the rest of the nav colours now come from V2 (see
     the alias block at the foot of this file). */
  --color-nav-editing: var(--neutral-300);        /* #d4d4d4 creating row */
  --color-nav-placeholder: var(--gray-10);        /* hint text */

  /* Board colours. The one chromatic set besides the logo: a board picks
     one of these ten. Owner's hues, 2026-09-19; one lightness band (L 0.60)
     since 2026-09-28 so no board shouts over another, and every one reaches
     3:1 on white. Gold and orange sit a touch higher; graphite and stone
     are the two near-greys. Same values in both themes, except graphite,
     which is too dark to see on the dark sidebar and gets its own.
     Raw values live under --board-*; --color-board-* are aliases. */
  --board-blue: oklch(0.60 0.10 233);
  --board-green: oklch(0.60 0.10 158);
  --board-graphite: oklch(0.46 0.012 107);  /* dark value in the dark set */
  --board-purple: oklch(0.60 0.13 309);
  --board-brown: oklch(0.60 0.085 48);
  --board-stone: oklch(0.62 0.012 88);
  --board-magenta: oklch(0.60 0.15 351);
  --board-gold: oklch(0.62 0.12 76);
  --board-red: oklch(0.60 0.15 27);
  --board-orange: oklch(0.62 0.14 53);
  /* The older --color-board-* names. The Tailwind theme reads --board-*
   * (text-board-green, bg-board-blue); inline styles still build these. */
  --color-board-blue: var(--board-blue);
  --color-board-green: var(--board-green);
  --color-board-graphite: var(--board-graphite);
  --color-board-purple: var(--board-purple);
  --color-board-brown: var(--board-brown);
  --color-board-stone: var(--board-stone);
  --color-board-magenta: var(--board-magenta);
  --color-board-gold: var(--board-gold);
  --color-board-red: var(--board-red);
  --color-board-orange: var(--board-orange);
  /* Inspector preview badges (Figma 330:2705 / 330:2711). */
  /* Prism shimmer while an image loads (glimm "prism": cyan→indigo→magenta). */
  --shine-prism-cyan: oklch(0.75 0.13 220 / 0.16);
  --shine-prism-indigo: oklch(0.58 0.21 280 / 0.16);
  --shine-prism-magenta: oklch(0.62 0.24 330 / 0.14);
  /* "PNG chip" (Figma): dark translucent pill over media, both themes. */
  --color-scrim-badge: oklch(0 0 0 / 0.40);
  --color-badge-fg: oklch(1 0 0);
  /* Card select circle over a picture: a soft light ring and a white veil
   * behind it, never a hard white stroke (session 128 look). */
  --color-pick-ring: color-mix(in oklch, var(--color-text-secondary) 42%, var(--color-white));
  --color-pick-veil: oklch(1 0 0 / 0.55);

  /* Alpha variants — their own tokens, never color-mix() */
  --color-overlay-strong: oklch(0.961 0 0 / 0.85);
  --scrim: oklch(0.13 0 0 / 0.25);             /* behind modals */
  --color-scrim: var(--scrim);
  --color-tint: var(--v2-wash-2);              /* hover wash — the same wash, one name */
  --color-tint-strong: var(--v2-menu-selected); /* active wash — the same wash, one name */
  --focus-ring: oklch(0.13 0 0 / 0.28);        /* keyboard focus outline */
  --color-focus-ring: var(--focus-ring);
  --color-focus-fill: var(--gray-5); /* pressed / focused fill; one step past hover (gray-4) so focus no longer looks like hover. Neutral grey, no hue: a tint read as blue on the search bar. */
  --hairline: oklch(0.24 0 0 / 0.06);          /* inset 0.5px edge — the shadow ink */
  --color-hairline: var(--hairline);
  --color-hairline-strong: oklch(0.24 0 0 / 0.12); /* swatch ring, outline button edge */
  /* The one line colour for a divider between groups, rows or panes.
   * See-through, so it reads on any ground; white in the dark set. Kept
   * near the old #ededed hairline: the owner found 10% too harsh. */
  --divider: oklch(0.24 0 0 / 0.06);

  /* Font family.
     UI is SF Pro via the Mac system stack. Do not load Inter or any other
     webfont for chrome. GT Flexa Mono appears in Figma as library *content*
     (a font being previewed), not as the interface face. */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", sans-serif;
  /* Parry is the brand serif. Marketing headline + wordmark only. */
  --font-display: "Parry", Georgia, "Times New Roman", serif;

  /* Code face: file paths, key names, code. */
  --font-mono: ui-monospace, "SF Mono", Menlo, monospace;

  /* Type scale — the one scale, modelled on macOS text styles.
     Each token is a full `font:` shorthand (weight size/line-height family),
     so one line sets the whole look: `font: var(--type-body);`.
     Sizes are what you see on screen, no zoom.

       display        hero, empty-screen title
       title-1        section and page titles
       title-2        dialog and card titles
       headline       group headings, emphasised rows
       body-large     long reading: notes, chat answers
       body           default UI text (macOS body)
       body-emphasis  labels, menu rows, buttons
       callout        secondary lines, meta, chips, keys
       callout-emphasis  section labels, key caps, chips (medium weight)
         section-label   = callout-emphasis, for a group's label
         key             = callout-emphasis, for a key cap
       dialog-title   = title-2, the title at the top of a dialog
       caption        timestamps, counts, fine print
       overline       uppercase section labels; pair with --tracking-overline
       mono           file paths, key names, code

     Numbers that change or line up in columns use --numeric-tabular
     (the `.tabular` class in the app base stylesheet, index.css). */
  /* Each stop is written once as three parts (size, leading, weight) and
   * the shorthand is built from them, so the Tailwind theme (text-body,
   * text-caption...) and `font: var(--type-body)` read the same numbers. */
  --type-display-size: 36px;
  --type-display-leading: 44px;
  --type-display-weight: 600;
  --type-display: var(--type-display-weight) var(--type-display-size)/var(--type-display-leading) var(--font-sans);  /* hero, empty-screen title */
  --type-title-1-size: 24px;
  --type-title-1-leading: 32px;
  --type-title-1-weight: 600;
  --type-title-1: var(--type-title-1-weight) var(--type-title-1-size)/var(--type-title-1-leading) var(--font-sans);  /* section and page titles */
  --type-title-2-size: 18px;
  --type-title-2-leading: 24px;
  --type-title-2-weight: 600;
  --type-title-2: var(--type-title-2-weight) var(--type-title-2-size)/var(--type-title-2-leading) var(--font-sans);  /* dialog and card titles */
  --type-headline-size: 14px;
  --type-headline-leading: 20px;
  --type-headline-weight: 600;
  --type-headline: var(--type-headline-weight) var(--type-headline-size)/var(--type-headline-leading) var(--font-sans);  /* group headings, emphasised rows */
  --type-body-large-size: 14px;
  --type-body-large-leading: 20px;
  --type-body-large-weight: 400;
  --type-body-large: var(--type-body-large-weight) var(--type-body-large-size)/var(--type-body-large-leading) var(--font-sans);  /* long reading: notes, chat answers */
  --type-body-size: 13px;
  --type-body-leading: 18px;
  --type-body-weight: 400;
  --type-body: var(--type-body-weight) var(--type-body-size)/var(--type-body-leading) var(--font-sans);  /* default UI text (macOS body) */
  --type-body-emphasis-size: 13px;
  --type-body-emphasis-leading: 18px;
  --type-body-emphasis-weight: 500;
  --type-body-emphasis: var(--type-body-emphasis-weight) var(--type-body-emphasis-size)/var(--type-body-emphasis-leading) var(--font-sans);  /* labels, menu rows, buttons */
  --type-callout-size: 12px;
  --type-callout-leading: 16px;
  --type-callout-weight: 400;
  --type-callout: var(--type-callout-weight) var(--type-callout-size)/var(--type-callout-leading) var(--font-sans);  /* secondary lines, meta, chips, keys */
  --type-callout-emphasis-size: 12px;
  --type-callout-emphasis-leading: 16px;
  --type-callout-emphasis-weight: 500;
  --type-callout-emphasis: var(--type-callout-emphasis-weight) var(--type-callout-emphasis-size)/var(--type-callout-emphasis-leading) var(--font-sans);  /* section labels, key caps, chips */
  --type-caption-size: 11px;
  --type-caption-leading: 14px;
  --type-caption-weight: 400;
  --type-caption: var(--type-caption-weight) var(--type-caption-size)/var(--type-caption-leading) var(--font-sans);  /* timestamps, counts, fine print */
  --type-overline-size: 10px;
  --type-overline-leading: 14px;
  --type-overline-weight: 600;
  --type-overline: var(--type-overline-weight) var(--type-overline-size)/var(--type-overline-leading) var(--font-sans);  /* uppercase section labels; pair with --tracking-overline */
  --type-mono-size: 12px;
  --type-mono-leading: 16px;
  --type-mono-weight: 400;
  --type-mono: var(--type-mono-weight) var(--type-mono-size)/var(--type-mono-leading) var(--font-mono);  /* file paths, key names, code */
  /* Role names. Each points at a stop above; use the role, so a later
   * change to one role does not drag the others with it. */
  --type-section-label: var(--type-callout-emphasis);  /* a group's label */
  --type-key:           var(--type-callout-emphasis);  /* a key cap in a menu or tooltip */
  --type-dialog-title:  var(--type-title-2);           /* the title at the top of a dialog */
  --tracking-overline: 0.06em;
  /* Tight tracking: display and title-1 only (owner call, 2026-09-28). */
  --tracking-tight: -0.01em;
  --numeric-tabular: tabular-nums;

  /* Three weights only. Mac uses semibold, not bold, for emphasis. */
  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;

  /* Old size names; new code uses --type-* (or the text-* classes).
   * Renamed --legacy-* on 2026-09-28: --text-* and --leading-* are Tailwind's
   * own namespaces now, and --text-body / --text-caption / --text-overline
   * mean the type scale there. Kept only while screens convert. */
  --legacy-text-h3: 16px;        --legacy-leading-h3: 24px;
  --legacy-text-body: 14px;      --legacy-leading-body: 20px;
  --legacy-text-label: 13px;     --legacy-leading-label: 18px;
  --legacy-text-caption: 12px;   --legacy-leading-caption: 16px;
  --legacy-text-overline: 11px;  --legacy-leading-overline: 14px;
  --legacy-leading-label-relaxed: 20px;
  --legacy-leading-overline-relaxed: 18px;
  --legacy-leading-body-relaxed: 24px;

  /* Spacing — HeroUI / Tailwind scale (base unit 4px = 0.25rem).
     Layout prefers 4 / 8 / 12 / 16. 2 and 6 are micro only (icon clusters).
     unit 0.5=2 · 1=4 · 1.5=6 · 2=8 · 3=12 · 4=16 · 5=20 · 6=24 · 8=32 … */
  --spacing-2xs: 2px;   /* 0.5 */
  --spacing-xs: 4px;    /* 1 */
  --spacing-sm: 6px;    /* 1.5 — micro */
  --spacing-md: 8px;    /* 2 — default layout gap */
  --spacing-base: 12px; /* 3 */
  --spacing-lg: 16px;   /* 4 — section / panel pad */
  /* A card's own inset, for the chips that sit on top of a thumbnail. Fixed
   * 6px was right on a laptop and looked pinned to the very corner on a large
   * display, where the same card is drawn much bigger (Session 107). It grows
   * with the window and stops at both ends so it never disappears or floats.
   * Falls back to the fixed value where clamp is unavailable. */
  --card-chip-inset: 6px;
  --card-chip-inset: clamp(6px, 0.45vw, 12px);
  --spacing-xl: 20px;   /* 5 */
  --spacing-2xl: 24px;  /* 6 */
  --spacing-3xl: 32px;  /* 8 */
  --spacing-4xl: 40px;  /* 10 */

  /* Spacing roles. Use these on the thing they name, so every button of a
   * size shares one side pad, every field one inner pad. */
  --button-pad-sm: 12px;     /* side pad of a small (28) button */
  --button-pad-md: 16px;     /* side pad of a medium (36) button */
  --button-pad-lg: 20px;     /* side pad of a large (40) button */
  --field-pad-sm: 8px;       /* inner side pad of a small field */
  --field-pad-md: 12px;      /* inner side pad of a medium field */
  --gap-icon-row: 8px;       /* icon to its word in a row or menu */
  --gap-icon-control: 6px;   /* icon to its word inside a button or chip */
  --badge-h-sm: 16px;        /* a small count or status badge */
  --badge-h-md: 20px;        /* a medium badge */

  /* Optical trims. The maths says centred, the eye says off; these put it
   * right. Each fixes one shape, so use it only for that shape.
   *   chevron  a 16px chevron box is mostly empty space on its open side,
   *            so a row ending in one looks padded too much. Pull it in.
   *   close    an × is drawn inset in its box and looks further from the
   *            corner than it is. Pull it toward the corner.
   *   play     a play triangle's weight sits left of its box centre. Nudge
   *            it right so it looks centred in its disc.
   *   title    a title's line-height adds air above the letters. Take this
   *            off the top padding of a surface that starts with a title,
   *            so the top gap looks the same as the side gap. */
  --optical-chevron-trim: -6px;
  --optical-close-trim: -2px;
  --optical-play-shift: 1px;
  --optical-title-trim: 4px;

  /* One opacity for anything disabled — buttons, fields, switches, rows. */
  --disabled-opacity: 0.45;

  /* Layout. --layout-sidebar-width lives in the V1 block at the foot of the
   * file (220, from --v2-sidebar-width); a 200 written here was always
   * overridden by it, and was deleted 2026-09-28. */
  --layout-inspector-width: 252px;
  /* One gap: window ↔ panels, and panel ↔ panel. */
  --layout-shell-gap: 8px;
  --layout-chrome-height: 40px;
  /* Traffic lights + air before collapse. */
  --layout-traffic-width: 70px;
  /* Two header heights: the window's top bar, and a panel's own header. */
  --header-window: 52px;
  --header-panel: 48px;
  /* Three control heights. Same idea as a button next to a select next to a
   * tab: they share a height, and text / icons / pad move together.
   * Small 28 — chrome squares, section headers, tight menus (Sort).
   * Medium 36 — toolbar, search, sidebar rows, ordinary menus.
   * Large 40 — the Large button (D091) and the library pill. */
  --control-sm: 28px;
  --control-md: 36px;
  --control-lg: 40px;
  /* Older names → the three heights. */
  --control-size: var(--control-sm);
  --control-size-toolbar: var(--control-md);
  --control-size-row: var(--control-size-toolbar);
  --control-size-switcher: var(--control-lg);
  /* 20 is switches and dots. */
  --control-size-xs: 20px;
  /* Filter, tag and starter chips. */
  --chip-h: 24px;
  /* A sidebar nav row (read by .sidebar in shell.css). */
  --sidebar-row-h: 32px;
  /* One number in one place: the icon size is named once, in the V2 block
   * below (--v2-icon-md). This older name answers from there. */
  --control-icon: var(--v2-icon-md);

  /* ---------- Stacking — the layer ladder (Session 98, Phase 3) ----------
   * Who covers whom, written down once, so nobody has to guess a number.
   * Read it top to bottom: each step is genuinely in front of the one
   * above it. Use a token; never write a bare z-index.
   *
   * A menu sits ABOVE a modal on purpose: a dropdown opened inside a
   * dialog has to be visible. That is also why a menu left open when a
   * dialog appears will cover it — the fix for that is to close the menu,
   * not to move the number. */
  --layer-content: 1;    /* the grid, the panels, the page */
  --layer-sticky: 20;    /* headers and rails pinned while you scroll */
  --layer-float: 40;     /* the manage bar, popovers, item-view controls */
  --layer-modal: 100;    /* dialogs and their dimming backdrop */
  --layer-drop: 150;     /* the drag-and-drop overlay — over a dialog, under a menu */
  --layer-menu: 300;     /* a menu — it must clear the dialog that opened it */
  --layer-tooltip: 400;  /* a tooltip — it must clear the menu it explains */
  --layer-shelf: 500;    /* the shake shelf, dropped on from another app */
  --layer-toast: 1000;   /* the last word; nothing covers a toast */

  /* ---------- Motion — three springs, faster exits ----------
   * JS springs in ui/src/lib/springs.ts read these. Enter is a spring;
   * leave is a plain tween one step quicker (no bounce). CSS transitions
   * still use --ease-enter / --ease-leave.
   *   fast      hover, fades, small toggles
   *   moderate  dropdowns, tabs, panels that must land exactly
   *   slow      dialogs, drawers — only this one may bounce */
  --duration-fast: 80ms;
  --duration-base: 160ms;
  --duration-slow: 240ms;

  --spring-fast-exit:     60ms;
  --spring-moderate-exit: 120ms;
  --spring-slow-exit:     160ms;

  --spring-fast-bounce:     0;
  --spring-moderate-bounce: 0;
  --spring-slow-bounce:     0.12;

  --ease-enter: cubic-bezier(0.22, 1, 0.36, 1); /* CSS arrive, settle soft */
  --ease-leave: cubic-bezier(0.4, 0, 1, 1);     /* CSS leave, no settle */

  /* One overshoot kept for tick / save / menu pop in CSS (Agent B owns those files). */
  --ease-pop: cubic-bezier(0.34, 1.36, 0.64, 1);

  --spring-fast-enter:     var(--duration-fast);
  --spring-moderate-enter: var(--duration-base);
  --spring-slow-enter:     var(--duration-slow);

  /* Legacy easing aliases → enter / leave / pop */
  --ease-out-soft:  var(--ease-enter);
  --ease-out-quart: var(--ease-enter);

  /* Opening scale — where a surface starts before it springs to full size.
   * Menus and toasts one value, dialogs one value. */
  --scale-enter-menu: 0.96;
  --scale-enter-dialog: 0.97;

  /* Keyboard focus outline — one width, one gap, everywhere. */
  --focus-outline-width: 2px;
  --focus-outline-offset: 2px;

  /* ---------- Radius — ONE corner scale (merged Session 98, Phase 3) ----------
   * There used to be two scales that disagreed at three rungs (8/12/16
   * against 10/16/24) and both were live, so two panels meant to match
   * sat 2px apart. They are now one scale: seven rungs plus the pill.
   *
   * Merged by counting real call sites and keeping the dominant value per
   * rung, which means almost nothing moved. Every old name still answers,
   * as an alias below — no call site had to change. The single rendered
   * change is --v2-radius-md, whose 10px was not a rung on either scale.
   *
   * Nested boxes: outer radius = inner radius + the padding between them.
   *
   * New code uses --radius-*. The --v2-radius-* names below are aliases
   * only, kept so old call sites keep working. */
  --radius-xs:   4px;   /* favicons, small thumbnails */
  --radius-sm:   6px;   /* sidebar nav buttons, tag pills, library cards */
  --radius-md:   8px;   /* action buttons, link cards, icon containers */
  --radius-lg:  12px;   /* inner cards, rows, bars */
  --radius-xl:  16px;   /* mid panels, dialogs, overlay panels */
  --radius-2xl: 24px;   /* sheets — the largest corner */
  --radius-sheet: var(--radius-2xl); /* welcome and import cards — was 20, now the 24 sheet */
  /* The pill. One shape, one spelling — 9999px and 999px were the same
   * thing twice, and 999px is already past any real control height. */
  --radius-pill: 999px; /* status pills, badges, circular */
  /* Chip inside the search field. Field corner is 8, chip sits 4 in, so 4.
     A pill fights the field. Floor is 4 so a bigger inset cannot pinch it. */
  --radius-search-chip: max(var(--radius-xs), calc(var(--radius-md) - var(--spacing-xs))); /* search chip: field corner minus the 4px inset */

  /* Old names → the scale. No number lives here. */
  --radius-full:       var(--radius-pill);  /* was 9999px — same shape */
  --v2-radius-pill:    var(--radius-pill);
  --v2-radius-sm:      var(--radius-sm);    /*  6 — unchanged */
  --v2-radius-control: var(--radius-md);    /*  8 — unchanged */
  --v2-radius-md:      var(--radius-md);    /* MOVES 10 → 8 */
  --v2-radius-card:    var(--radius-lg);    /* 12 — unchanged */
  --v2-radius-sheet:    var(--radius-sheet);
  --v2-radius-lg:      var(--radius-xl);    /* 16 — unchanged */
  --v2-radius-xl:      var(--radius-2xl);   /* 24 — unchanged */

  /* ---------- Shadows — THE DEPTH LADDER (Session 98, Phase 3) ----------
   * Five rungs, and a thing may not skip one:
   *
   *   page     the canvas. No shadow at all.
   *   panel    sidebar, library, item panel, cards at rest. Barely there.
   *   card     a hovered card, the welcome card — the everyday lift.
   *   float    selection bar, toast.
   *   menu     menus, popovers, tooltips.
   *   modal    dialogs, Quick Look. The deepest thing on screen.
   *
   * Each rung is deeper than the one before on every measure: edge, contact
   * shadow and lift (audit 2026-09-28, §2.2). Each carries its own 0.5px
   * edge as the first layer, so no surface needs a separate border.
   *
   * Exactly one shadow token per rung, plus the hairline edge. Nothing may
   * wear a shadow that is not on this ladder. The extra old names survive
   * below as aliases so no call site broke, but hold no numbers of their own.
   *
   * Each rung is written once, from two sets of colours that flip with the
   * theme: --shadow-edge-N (the 0.5px edge) and --shadow-drop-N (the drop).
   * Light: both are the gray-12 ink at N% (--v2-shadow-ink-*). Dark: the
   * edge is white and the drop black (the dark set re-declares them). So
   * one --shadow-* value, and the Tailwind shadow-* class copied from it,
   * is right in both themes.
   *
   * NOT on the ladder, and not depth: --shadow-hairline, --v2-fold-edge
   * and --v2-btn-inset draw edges with box-shadow. Leave them be. */
  --shadow-edge-6:  var(--v2-shadow-ink-6);
  --shadow-edge-8:  var(--v2-shadow-ink-8);
  --shadow-edge-10: var(--v2-shadow-ink-10);
  --shadow-edge-12: var(--v2-shadow-ink-12);
  --shadow-drop-4:  var(--v2-shadow-ink-4);
  --shadow-drop-5:  var(--v2-shadow-ink-5);
  --shadow-drop-6:  var(--v2-shadow-ink-6);
  --shadow-drop-8:  var(--v2-shadow-ink-8);
  --shadow-drop-10: var(--v2-shadow-ink-10);
  --shadow-drop-12: var(--v2-shadow-ink-12);
  --shadow-drop-18: var(--v2-shadow-ink-18);

  --shadow-hairline: inset 0 0 0 0.5px var(--color-hairline);
  --shadow-page:  none;
  --shadow-panel:
    0 0 0 0.5px var(--shadow-edge-6),
    0 1px 2px var(--shadow-drop-4);
  --shadow-card:
    0 0 0 0.5px var(--shadow-edge-8),
    0 1px 2px var(--shadow-drop-5),
    0 2px 6px var(--shadow-drop-5);
  --shadow-float:
    0 0 0 0.5px var(--shadow-edge-10),
    0 2px 4px var(--shadow-drop-6),
    0 6px 16px var(--shadow-drop-8);
  /* Menus — the D079 card: --menu-ring is the edge, --menu-shadow the
   * contact and lift (both set below). */
  --shadow-menu: var(--menu-ring), var(--menu-shadow);
  --shadow-pressed: inset 0 1px 3px var(--color-scrim); /* a filled button while held down */
  --shadow-modal:
    0 0 0 0.5px var(--shadow-edge-12),
    0 4px 12px var(--shadow-drop-10),
    0 24px 60px var(--shadow-drop-18);

  /* The membership card is a physical object lying on the page, so it throws
   * a slightly richer shadow than a panel. It is off the five-rung ladder: its own two tokens, used by nothing else.
   * It used to end in a 40px blur of 16% black at 24px down, which pooled
   * under the card and met the next section as a smudge rather than a
   * shadow (2026-09-17). Ink tokens only now; the dark set has its own pair.
   * Nothing else may use these two. */
  --shadow-account-card:
    0 2px 6px var(--v2-shadow-ink-8),
    0 10px 24px var(--v2-shadow-ink-12);
  --shadow-account-card-hover:
    0 4px 10px var(--v2-shadow-ink-10),
    0 16px 36px var(--v2-shadow-ink-12);
  --highlight-emboss: 0 1px 0 oklch(1 0 0 / 0.35); /* #fff 35% — top-light */

  /* Old shadow names → the ladder. Marked where a rendered value moves. */
  --shadow-surface:      var(--shadow-card);   /* MOVES: gains the second layer */
  --shadow-card-hover:   var(--shadow-card);   /* MOVES: softer, and drops its own ring */
  --shadow-overlay:      var(--shadow-float);  /* MOVES: 0.5px ring → 1px, deeper spread */
  --shadow-nav-active:   var(--shadow-panel);  /* MOVES: also drops a stray warm tint */

  /* ---- Menus (session 122) ----
   * One card for toolbar, right-click and flyouts. Pad is 8 and the corner
   * 16, so a row's corner is 8 (D079). */
  --menu-bg: var(--v2-bg-elevated);
  --menu-ring: 0 0 0 0.5px var(--shadow-edge-12);  /* the menu rung's edge */
  /* The menu rung (§2.2): a contact shadow and a lift, one step deeper
   * than float and one step lighter than a dialog. */
  --menu-shadow:
    0 2px 6px var(--shadow-drop-8),
    0 10px 28px var(--shadow-drop-12);
  --menu-radius: var(--radius-xl);            /* 16 — pad 8 + row radius 8 */
  --menu-pad: var(--spacing-md);              /* 8 — the sides */
  --menu-pad-y: var(--spacing-xs);            /* 4 — top and bottom (audit 3 §3, replaces D079's 8) */
  --menu-min-w: 216px;
  --menu-max-w: 300px;
  --menu-row-h: 32px;                         /* a step under the 36 toolbar */
  --menu-row-pad-x: var(--spacing-md);        /* 8 */
  --menu-row-gap: var(--spacing-md);          /* icon → word */
  --menu-row-radius: var(--radius-md);        /* 8 hover pill */
  --menu-hover: var(--v2-menu-hover);
  --menu-divider: var(--color-hairline);
  --menu-divider-gap: var(--spacing-xs);      /* air above and below */
  --menu-header-pad: var(--spacing-sm) var(--spacing-md) var(--spacing-xs);
  --menu-submenu-overlap: 6px;                /* flyout tucks under its parent edge */
  --menu-submenu-offset-y: calc(-1 * var(--menu-pad-y));  /* flyout's first row lines up with the parent row */
  --menu-pop-duration: 160ms;
  --menu-pop-ease: var(--ease-enter);
  --menu-pop-scale: var(--scale-enter-menu);  /* was 0.94 */
  --menu-pop-shift: 4px;
  --menu-leave-duration: var(--spring-moderate-exit);  /* 120 — was 100 */
  --menu-leave-ease: var(--ease-leave);
  --menu-swatch: 22px;
  --menu-swatch-gap: var(--spacing-md);
  --menu-tile: 32px;
  --menu-tile-gap: var(--spacing-2xs);

  /* Selection manage bar (Figma 361:2329) — dark frosted pill over the grid */

  /* Soft progressive blur band when a list overflows (library, sidebar). */
  --scroll-blur-size: 36px;
  --scroll-blur-strength: 10px;

  /* Skeleton — HeroUI-inspired shimmer, Mise tokens only */
  --skeleton-duration: 2s;
  --skeleton-bg: var(--color-secondary-fill);
  --skeleton-shine: oklch(1 0 0 / 0.55);

  /* Colour filter slider — functional hue track (filter UI only) */
  --color-filter-cyan: oklch(0.78 0.14 220);
  --color-filter-blue: var(--blue-9);
  --color-filter-purple: oklch(0.48 0.22 295);
  --color-filter-pink: oklch(0.62 0.22 340);
  --color-filter-red: oklch(0.55 0.22 25);
  --color-filter-orange: oklch(0.68 0.18 55);
  --color-filter-yellow: oklch(0.84 0.16 95);
  --color-filter-green: oklch(0.62 0.17 145);
  /* The rest of the families, so a colour chip can show a real dot. */
  --color-filter-brown: oklch(0.45 0.09 55);
  --color-filter-grey: oklch(0.65 0 0);
  --color-filter-black: oklch(0.2 0 0);
  --color-filter-white: oklch(0.97 0 0);
  --color-filter-track: linear-gradient(
    90deg,
    var(--color-filter-cyan) 0%,
    var(--color-filter-blue) 14%,
    var(--color-filter-purple) 28%,
    var(--color-filter-pink) 42%,
    var(--color-filter-red) 56%,
    var(--color-filter-orange) 70%,
    var(--color-filter-yellow) 84%,
    var(--color-filter-green) 100%
  );
  --color-filter-dot: oklch(1 0 0 / 0.35);

  /* Blurs */
  --blur-backdrop: 8px;
}

/* Dark theme: V1 aliases follow the V2 dark set below through the bridge;
 * the old V1 block was dead code (out-specified) and was removed in Session 73. */

/* =============================================================
 * V2 — Mise design system (Figma "Mise V2", file JlQcPTFvtbaPjICu8jpsrX).
 * Session 66, 2026-09-02. A small opinionated system: primitives +
 * semantic aliases + type scale + radii + shadows + motion.
 *
 * This is the live system — the front door. New work uses --v2-* names.
 * Every old --color-* name is an alias pointing back here (foot of file).
 * Session 98 rewrote these from hex into OKLCH; the values did not move.
 * ============================================================= */
:root {
  /* ---------- Old neutral steps → the grey ramp ----------
   * These names predate --gray-*. Each one now points at the ramp step
   * whose job it did, so several old steps that were nearly the same grey
   * land on one step. Both themes follow, because the ramp is re-declared
   * in the dark set. New code names --gray-* or a semantic name.
   *
   *   0     raised sheet                    → gray-0
   *   50    quiet well in a sheet           → gray-1
   *   75    chips, slider track             → gray-3
   *   100   everyday quiet fill             → gray-3
   *   150   canvas fill, hover              → gray-4
   *   200   pressed, filled progress        → gray-5
   *   300   hairline border                 → gray-6
   *   400   quietest text or mark           → gray-8
   *   500   quiet supporting text           → gray-10
   *   600   secondary text                  → gray-11
   *   800-950 main text, inverted fill      → gray-12
   *   1000  true black (white in dark). Not on the ramp. */
  --v2-neutral-0:    var(--gray-0);
  --v2-neutral-50:   var(--gray-1);
  --v2-neutral-75:   var(--gray-3);
  --v2-neutral-100:  var(--gray-3);
  --v2-neutral-150:  var(--gray-4);
  --v2-neutral-200:  var(--gray-5);
  --v2-neutral-300:  var(--gray-6);
  --v2-neutral-400:  var(--gray-8);
  --v2-neutral-500:  var(--gray-10);
  --v2-neutral-600:  var(--gray-11);
  --v2-neutral-800:  var(--gray-12);
  --v2-neutral-900:  var(--gray-12);
  --v2-neutral-950:  var(--gray-12);
  --v2-neutral-1000: oklch(0 0 0);         /* #000000 */

  /* ---------- Old colour steps → the colour ramp ---------- */
  --v2-blue-50:  var(--blue-3);
  /* Light blue, one reader: the confetti (confetti.tsx reads it by name). */
  --v2-blue-300: oklch(0.74345 0.13141 269.61);  /* #8ba7ff */
  --v2-blue-500: var(--blue-9);
  --v2-blue-600: var(--blue-10);
  --v2-red-500:  var(--red-9);
  --v2-green-500: var(--green-9);
  --v2-green-600: var(--green-11);

  /* ---------- Semantic aliases — surface & text ---------- */
  /* Misnamed: this is the hover grey, not a base. It is kept so old call
   * sites work; controls use the four --fill-* names below instead. */
  --v2-bg-base:      var(--gray-4);    /* a quiet control's resting fill, row hover */
  --v2-bg-subtle:    var(--gray-1);    /* placeholder tiles, outline btn — a well in a sheet */
  --v2-bg-elevated:  var(--gray-0);    /* modals, cards, elevated btn */
  --v2-bg-surface:   var(--gray-2);    /* the window and the sidebar */
  --v2-bg-inverse:   var(--gray-12);   /* toasts on dark */

  /* A grey control's fill — a grey button, a field, a chip, a segmented
   * control. Every grey control uses these four, in this order, so rest,
   * hover and pressed always step the same way in both themes. */
  --fill-rest:     var(--gray-3);
  --fill-hover:    var(--gray-4);
  --fill-pressed:  var(--gray-5);
  --fill-selected: var(--gray-5);   /* chosen and staying chosen */

  --v2-text-primary:   var(--gray-12);   /* main text */
  --v2-text-secondary: var(--gray-11);   /* second-line text, nav labels */
  --v2-text-tertiary:  var(--gray-10);   /* hint text, nav icons */
  --v2-text-inverse:   var(--gray-0);
  /* Comments — someone's words, not metadata. The one blue *fill* in the
   * UI besides primary actions; owner-approved exception to monochrome. */
  /* Comment bubbles — iMessage-sent language: solid blue, white words. */
  --v2-comment-bg:     var(--blue-9);
  --v2-comment-text:   var(--color-white);

  /* Icons carry the same three weights as text, and the same values — an
   * icon beside a label should not be a different grey from it. */
  --v2-icon-primary:   var(--v2-text-primary);
  --v2-icon-secondary: var(--v2-text-secondary);
  --v2-icon-tertiary:  var(--v2-text-tertiary);   /* Figma Icon/tertiary — inactive nav icon */
  /* One step quieter than tertiary — decorative marks that should recede
   * behind the text they sit above. */
  --v2-icon-muted:     var(--gray-9);    /* quiet icon */

  --v2-border-subtle:   var(--gray-6);   /* subtle border, field edge */
  --v2-border-strong:   var(--gray-7);   /* strong border */
  --v2-border-hairline: var(--gray-3);   /* dividers */
  /* Card edge — the shadow ink at 8%, the same edge the card rung draws.
   * Keeps a white image from melting into the canvas without a frame. */
  --v2-card-edge: oklch(0.24 0 0 / 0.08);
  /* Softer edge for cards that stack — a settings page shows six or eight
   * in one column, and at 14% the column reads as a stack of harsh strokes
   * rather than raised paper (Session 107). Grid cards keep the full 14%:
   * there the edge stops a white image melting into the canvas. */
  --v2-card-edge-soft: oklch(0 0 0 / 0.07);
  --v2-canvas-dot: oklch(0 0 0 / 0.045);       /* full-view dot grid */
  --v2-canvas-frame: var(--v2-ring);           /* hairline around the full-view picture */
  /* Washes — in light these are black at low alpha; the names are the same
   * in both themes so no component has to know which one it is in. */
  --v2-wash-2: oklch(0 0 0 / 0.05);
  --v2-ring:   oklch(0 0 0 / 0.06);
  /* Nearly-full meters, calmer than destructive. Confetti reads it by name. */
  --v2-warning: var(--warning-meter);

  /* Actions. A solid fill is step 9 (white label on top), its hover step 10.
   * Where a colour is the words themselves, use the -text names (step 11):
   * they pass 4.5:1 on white and on the window grey. */
  --v2-brand-blue:         var(--blue-9);
  --v2-brand-blue-hover:   var(--blue-10);
  --v2-brand-blue-text:    var(--blue-11);
  --v2-destructive:        var(--red-9);
  --v2-destructive-text:   var(--red-11);
  --v2-success:            var(--green-11);   /* only ever words and ticks */
  --v2-button-text:        var(--on-fill);          /* label on an accent fill — never flips with the theme */

  /* ---------- Type — SF Pro via the Mac system stack ---------- */
  --v2-font-family: var(--font-sans);

  /* Old names; new code uses --type-*. Each points at the --type-* stop
     it matches. The four written out in full have no exact new stop. */
  --v2-text-display:      var(--type-display);        /* old name */
  --v2-text-heading:      var(--type-title-1);        /* old name */
  --v2-text-title:        var(--type-title-2);        /* old name */
  --v2-text-section:      var(--type-headline);       /* old name */
  --v2-text-label-bold:   var(--type-headline);       /* old name */
  --v2-text-body-lg:      var(--type-body-large);     /* old name */
  --v2-text-body-md:      500 14px/20px var(--font-sans);   /* old name: body-large at medium weight */
  --v2-text-body:         var(--type-body);           /* old name */
  --v2-text-body-relaxed: 400 13px/20px var(--font-sans);   /* old name: body with looser leading */
  --v2-text-label:        var(--type-body-emphasis);  /* old name */
  --v2-text-body-bold:    var(--type-body-emphasis);  /* old name */
  --v2-text-meta:         500 12px/16px var(--font-sans);   /* old name: callout at medium weight */
  --v2-text-small-bold:   600 12px/14px var(--font-sans);   /* old name */
  --v2-text-caption:      var(--type-caption);        /* old name */
  --v2-text-overline:     var(--type-overline);       /* old name */

  --v2-tracking-tight:    var(--tracking-tight);
  --v2-tracking-overline: var(--tracking-overline);   /* old name */

  /* ---------- Icon sizes (Nucleo UI fill-18 art) ----------
   * Always 16 for the default draw size (AGENTS.md). Do not shrink with type. */
  --v2-icon-sm: 12px;   /* inline badges, chips */
  --v2-icon-md: 16px;   /* default — toolbar, most buttons */
  --v2-size-swatch: 22px; /* colour chips */

  /* ---------- Sidebar ----------
   * Figma node 145:50: 220-wide square sheet with asymmetric body insets.
   * This is the live sidebar width: --layout-sidebar-width points here. */
  --v2-sidebar-width:            220px;
  --v2-sidebar-inner-padding:    12px;
  --v2-sidebar-inset-top:        16px;
  --v2-sidebar-inset-right:      13px;
  --v2-sidebar-inset-bottom:     20px;

  --v2-nav-row-height:      var(--control-size-toolbar);  /* Figma 37:94 is 36 */
  --v2-nav-row-radius:      var(--radius-md);
  --v2-nav-row-padding-x:   12px;
  --v2-nav-row-padding-y:   4px;
  --v2-nav-row-gap:         4px;
  --v2-nav-icon-gap:        4px;
  /* ---- Motion vocabulary aliases (Session 77 names → Phase 4 three+two) */
  --tr-ease-out:   var(--ease-enter);
  --tr-ease-in:    var(--ease-leave);
  --tr-ease-pop:   var(--ease-pop);
  --tr-ease-bob:   var(--ease-pop);   /* was a near-identical overshoot */
  --tr-ease-morph: var(--ease-pop);

  --tr-menu-open:   var(--duration-base);  /* 160 — menus open at 160 (D073) */
  --tr-modal-close: var(--duration-fast);  /* was 150ms — dismiss stays quick */
  --tr-morph-open:  var(--duration-slow);  /* was 350ms */

  --tr-modal-scale: var(--scale-enter-dialog);  /* 0.97 — was 0.96 */
  --tr-blur:        2px;    /* the haze on a morph or an icon swap */

  --v2-nav-icon-size:       var(--v2-icon-md);  /* 16 — one size for every rail row */
  /* Label — 13/18 so descenders clear inside overflow-hidden wrappers. */
  --v2-nav-label:           600 13px/18px var(--v2-font-family);

  --v2-sidebar-divider-block:   14px;
  --v2-sidebar-divider-line:    1px;
  --v2-sidebar-section-height:  28px;
  --v2-sidebar-section-inset-y: 4px;

  /* ---------- Radii ----------
   * Moved. There is one corner scale now and it lives in the first block
   * of this file, under "Radius". The --v2-radius-* names still work —
   * they are aliases into that scale. Do not re-declare them here.
   * (--v2-radius-xs was deleted: it was 4px, used nowhere, and --radius-xs
   * already says the same thing.) */

  /* ---------- Shadow ink ----------
   * The weights the depth ladder is built from. One colour — gray-12 in
   * light (L 0.24) — at seven alphas. The ladder itself lives in the
   * first block of this file, under "Shadows — THE DEPTH LADDER". */
  --v2-shadow-ink-4:  oklch(0.24 0 0 / 0.04);
  --v2-shadow-ink-5:  oklch(0.24 0 0 / 0.05);
  --v2-shadow-ink-6:  oklch(0.24 0 0 / 0.06);
  --v2-shadow-ink-8:  oklch(0.24 0 0 / 0.08);
  --v2-shadow-ink-10: oklch(0.24 0 0 / 0.1);
  --v2-shadow-ink-12: oklch(0.24 0 0 / 0.12);
  --v2-shadow-ink-18: oklch(0.24 0 0 / 0.18);

  /* V2 shadow names → the ladder. No numbers here either.
   * (--v2-shadow-lg was deleted: "the absolute max", used nowhere, and
   * --shadow-modal is the max now.) */
  --v2-shadow-sm:      var(--shadow-panel);  /* unchanged value */
  --v2-shadow-surface: var(--shadow-card);   /* unchanged value */
  --v2-shadow-float:   var(--shadow-float);  /* unchanged value */
  --v2-shadow-menu:    var(--shadow-menu);
  --v2-shadow-overlay: var(--shadow-modal);  /* unchanged value */
  --v2-shadow-md:      var(--shadow-card);   /* MOVES: was its own 0 4px 12px */
  --v2-shadow-chatbox: var(--shadow-float);  /* MOVES: gains the ring */

  /* ---------- Frost — the one recipe for floating chrome ----------
   * Menus, the manage bar and the item-view controls used to each blur 8px
   * and tint differently; two scroll fades blurred 10px. Owner kept frost
   * (2026-09-07) but it has to be ONE frost. This is it: same blur, same
   * tint, same hairline, everywhere something floats.
   * The shelf and the notch are NOT this — their translucency is the Mac's
   * own vibrancy, a different thing (--overlay-shelf-* / --overlay-notch-*).
   * The scroll fade is NOT this either: there the blur is the hint. */
  --frost-blur: 8px;
  --frost-surface: oklch(1 0 0 / 0.9);
  --frost-border: var(--v2-ring);

  /* Translucent surface behind that blur. */
  --v2-toast-surface: var(--frost-surface);
  --v2-menu-hover:    var(--v2-wash-2);
  /* Selected radio row — a step above hover so the choice reads as chosen. */
  --v2-menu-selected: oklch(0 0 0 / 0.08);
  /* Figma node 145:50: a single edge highlight makes the sidebar read like
   * one cut sheet. The structural hairline remains the real boundary. */
  --v2-fold-edge: 1px 0 0 0 oklch(1 0 0 / 0.25);
  /* Button inset stroke + top-light + bottom-shadow (Figma spec on filled btns) */
  --v2-btn-inset:
    inset 0 0 0 1px oklch(0 0 0 / 0.15),
    inset 0 1px 0 0 oklch(1 0 0 / 0.2),
    inset 0 -1.5px 0 0 oklch(0 0 0 / 0.12);

  /* ---------- App-wide UI scale ----------
   * Session 99: zoom is GONE. Was 0.9 to fake Figma parity; that made
   * getBoundingClientRect lie, so menus opened in the wrong place.
   * On-screen sizes now live in the type/layout tokens above. Always 1. */
  --v2-ui-scale: 1;

  /* ---------- Motion (V2 names → Phase 4 three + two) ---------- */
  --v2-duration-fast: var(--duration-fast);
  --v2-duration:      var(--duration-base);
  --v2-duration-slow: var(--duration-slow);
  --v2-ease:          var(--ease-enter);
  --v2-ease-out:      var(--ease-enter);
  --v2-ease-in:       var(--ease-leave);

  /* ---------- Scrollbar thumb (Session 73, Fluid Functionalism ramp) ----------
   * Overlay black on light, white on dark: rest 8 %, hover 12 %, drag 16 %. */
  --v2-scrollbar-thumb:        oklch(0 0 0 / 0.28);
  --v2-scrollbar-thumb-hover:  oklch(0 0 0 / 0.40);
  --v2-scrollbar-thumb-active: oklch(0 0 0 / 0.52);
  --v2-inspector-scrollbar-thumb: oklch(0 0 0 / 0.25); /* #00000040 */

  /* ---------- Appearance thumbnails (Session 73) ----------
   * Fixed: the Light / Dark / System pickers draw both themes at once, so
   * these cannot follow the theme — they are literal on purpose. The three
   * light ones match the light ramp; the dark three predate the Session 77
   * lift and are darker than the real dark theme now is. */
  --v2-preview-light-canvas: oklch(0.931 0 0);     /* #e8e8e8 — = neutral-150 */
  --v2-preview-light-side:   oklch(0.96115 0 0);   /* #f2f2f2 — = bg-surface */
  --v2-preview-light-panel:  oklch(1 0 0);         /* #ffffff — = neutral-0 */
  --v2-preview-dark-canvas:  oklch(0.16842 0 0);   /* #0f0f0f */
  --v2-preview-dark-side:    oklch(0.29 0 0);       /* #313131 — was #161616, invisible on #0f0f0f */
  --v2-preview-dark-panel:   oklch(0.34 0 0);       /* #3b3b3b — the drawing has to be visible */

  /* ---------- Membership card foil (Session 72) ----------
   * Neutral brushed silver, owner reference 2026-09-19. Four stops,
   * graphite edge → bright band → shaded band → soft highlight. */
  --v2-card-foil-1: oklch(0.52 0.006 250);
  --v2-card-foil-2: oklch(0.93 0.004 250);
  --v2-card-foil-3: oklch(0.66 0.006 250);
  --v2-card-foil-4: oklch(0.88 0.004 250);
  --v2-card-foil-ring: oklch(1 0 0 / 0.55);
  --v2-card-foil-grain: oklch(0 0 0 / 0.035);
  --v2-card-foil-base: oklch(0.76 0.005 250); /* the sheet under the foil */
  --v2-card-engrave-ink: oklch(0.30 0 0);
  --v2-card-engrave: 0 1px 0 oklch(1 0 0 / 0.55), 0 -1px 0 oklch(0 0 0 / 0.25); /* engraved lettering: light below, shadow above */
  --v2-card-engrave-filter: drop-shadow(0 1px 0 oklch(1 0 0 / 0.55)) drop-shadow(0 -1px 0 oklch(0 0 0 / 0.25));

  /* Pro card gold foil — matte champagne gold, owner reference 2026-09-19.
   * Membership card only — nothing else may bind these. Not Amex. */
  --v2-card-gold-1: oklch(0.90 0.055 92);   /* pale champagne */
  --v2-card-gold-2: oklch(0.83 0.075 88);   /* the body */
  --v2-card-gold-3: oklch(0.74 0.085 82);   /* shaded edge */
  --v2-card-gold-4: oklch(0.87 0.065 90);   /* soft highlight */
  --v2-card-gold-ring: oklch(1 0 0 / 0.45);
  --v2-card-gold-base: oklch(0.82 0.075 87); /* the sheet under the foil */
  --v2-card-gold-grain: oklch(0 0 0 / 0.035); /* the brushed grain */
  --v2-card-gold-ink: oklch(0.36 0.05 68); /* dark bronze lettering */
  --v2-card-gold-engrave: 0 1px 0 oklch(1 0 0 / 0.35); /* light edge under the lettering */
}

/* =============================================================
 * Overlay windows — the shake shelf and the notch pill.
 *
 * Two small always-on-top windows that float over whatever is on screen.
 * macOS blurs the desktop behind them itself (NSVisualEffectView), so this
 * is the one place a Mise surface is translucent on purpose: what shows
 * through is the operating system, not a glass effect we drew.
 *
 * They follow the MAC's appearance, not the app's Light / Dark setting —
 * a separate window, a separate rule. The shelf has both appearances (it
 * sits on the wallpaper); the notch pill is always dark because it hangs
 * off the black bezel. Light values are in the prefers-color-scheme block
 * below. Session 98: these were raw rgba() inside shelf.css and notch.css.
 * ============================================================= */
:root {
  /* --- The shelf (Figma 144:156). Dark appearance is the default. --- */
  --overlay-shelf-surface:     oklch(0.18309 0.00404 285.99 / 0.52); /* the card's own tint over the Mac's blur */
  --overlay-shelf-ink:         oklch(1 0 0 / 0.95);   /* the status words */
  --overlay-shelf-ink-dim:     oklch(1 0 0 / 0.6);    /* the drop-target arrow */
  --overlay-shelf-edge:        oklch(1 0 0 / 0.14);   /* the rim that keeps the card off the desktop */
  --overlay-shelf-well:        oklch(1 0 0 / 0.1);    /* the recessed bed you drop onto */
  --overlay-shelf-chip:        oklch(1 0 0 / 0.14);   /* the resting status pill */
  --overlay-shelf-control:     oklch(0.27763 0.00363 286.16 / 0.85); /* the close button */
  --overlay-shelf-warn:        oklch(1 0 0 / 0.16);   /* "couldn't save" — quiet, the words carry it */
  --overlay-shelf-warn-ink:    oklch(1 0 0 / 0.92);
  /* Sending / Sent. The one shelf colour that IS a system colour: brand blue,
   * held back 5% so the glass still reads through. blue-9 is 0.02 lighter
   * in the dark set; too small to matter on glass. */
  --overlay-shelf-accent:      color-mix(in oklch, var(--blue-9) 95%, transparent);
  --overlay-shelf-accent-ink:  var(--v2-button-text);
  /* The ring while a drag is over the card. Was Apple's system blue
   * (#0a84ff); now the brand blue, so the ring matches the pill beside it. */
  --overlay-shelf-ring:        color-mix(in oklch, var(--blue-9) 95%, transparent);
  --overlay-shelf-spinner-track: oklch(1 0 0 / 0.35);
  --overlay-shelf-lift:        0 6px 16px oklch(0.24 0 0 / 0.3);   /* under a thumbnail — the shadow ink */
  --overlay-shelf-lift-active: 0 6px 16px oklch(0.24 0 0 / 0.28);
  /* The shimmer that sweeps the card when a drop lands. Same three-hue
   * idea as --shine-prism-* (the loading shimmer on a library card) but
   * far stronger — this one crosses glass in screen blend, not a white
   * card. Not interchangeable; do not merge the two sets. */
  --overlay-shelf-shimmer-cyan:    oklch(0.74715 0.13599 219.96 / 0.5);
  --overlay-shelf-shimmer-indigo:  oklch(0.55949 0.22955 279.31 / 0.45);
  --overlay-shelf-shimmer-magenta: oklch(0.62157 0.26294 322.51 / 0.4);

  /* --- The notch pill. Always dark: it hangs off the black bezel. --- */
  --overlay-notch-surface:     oklch(0.19125 0 0 / 0.96); /* near-opaque, so nothing blurs behind it */
  --overlay-notch-ink:         oklch(1 0 0 / 0.92);
  --overlay-notch-ink-dim:     oklch(1 0 0 / 0.6);
  --overlay-notch-edge:        oklch(1 0 0 / 0.08);
  /* Corner of the squared-off notch shape — deep enough to read as a
   * cutout in the bezel rather than a rounded card (Session 107). */
  --overlay-notch-shape-radius: 18px;
  /* The concave corner where the notch meets the screen edge. Small: it is a
   * fillet joining two edges, not a corner of its own. */
  --overlay-notch-fillet: 12px;
  --overlay-notch-well:        oklch(0.27 0 0);           /* #262626 bed under a thumbnail */
  --overlay-notch-well-edge:   oklch(1 0 0 / 0.06);
  --overlay-notch-swatch-edge: oklch(1 0 0 / 0.18);       /* stronger — a colour sample must read as one */
  --overlay-notch-control:     oklch(1 0 0 / 0.1);        /* the Undo button */
  --overlay-notch-control-hover: oklch(1 0 0 / 0.16);
  --overlay-notch-lift:
    0 20px 40px oklch(0.24 0 0 / 0.32),
    0 4px 12px oklch(0.24 0 0 / 0.2);
}

/* The Mac in light appearance. Only the shelf changes — see above. */
@media (prefers-color-scheme: light) {
  :root {
    /* These repeat the light numbers of --gray-1 / gray-12 / gray-11 on
     * purpose. Do NOT swap them for var(--gray-...): those flip with the
     * app's Light / Dark setting, and this block follows the MAC. A dark
     * app on a light Mac would turn the shelf inside out. */
    --overlay-shelf-surface:  oklch(0.98 0 0 / 0.55);  /* gray-1, 55% */
    --overlay-shelf-ink:      oklch(0.24 0 0 / 0.95);  /* gray-12, 95% */
    --overlay-shelf-ink-dim:  oklch(0.42 0 0 / 0.75);  /* gray-11, 75% */
    --overlay-shelf-edge:     oklch(0 0 0 / 0.12);
    --overlay-shelf-well:     oklch(0 0 0 / 0.06);
    --overlay-shelf-chip:     oklch(0 0 0 / 0.08);
    --overlay-shelf-control:  oklch(0 0 0 / 0.08);
    --overlay-shelf-warn:     oklch(0 0 0 / 0.1);
    --overlay-shelf-warn-ink: oklch(0.24 0 0 / 0.95);
  }
}

/* ============================================================
 * V2 dark set (Session 72, 2026-09-05) — derived first pass.
 * Every V2 colour token gets a dark value here so Light / Dark / System
 * actually changes the app. Neutrals are re-ramped for dark (canvas
 * darkest, raised cards lighter); text and icons swap ends. The
 * V1→V2 bridge below re-declares V1 aliases from these, so the whole
 * app follows. Owner tunes from Figma later; keep the names, change
 * the values.
 * ============================================================ */
:root[data-theme="dark"] {
  /* The ramp, dark. Same jobs as light: canvas darkest, raised cards
   * lighter, text at the far end. Every --gray-* name and every name built
   * on one follows from here, so this is where dark greys are set.
   *
   * gray-0 has no audit value in dark; it is the raised card, kept at the
   * card grey the app already shows (0.26). */
  --gray-0:  oklch(0.26 0 0);
  --gray-1:  oklch(0.23 0 0);
  --gray-2:  oklch(0.255 0 0);
  --gray-3:  oklch(0.28 0 0);
  --gray-4:  oklch(0.305 0 0);
  --gray-5:  oklch(0.33 0 0);
  --gray-6:  oklch(0.355 0 0);
  --gray-7:  oklch(0.385 0 0);
  --gray-8:  oklch(0.42 0 0);
  --gray-9:  oklch(0.54 0 0);
  --gray-10: oklch(0.66 0 0);
  --gray-11: oklch(0.78 0 0);
  --gray-12: oklch(0.95 0 0);

  /* Colours, dark. A mid colour goes muddy on a dark ground, so fills and
   * text sit lighter. Hover goes lighter here (+0.035), the way a lit
   * surface brightens in dark; washes are a deep tint, not a pale one.
   * Blue and red solid/text are the audit's values; the rest follow the
   * same bands. */
  --blue-3:  oklch(0.29 0.06 266);
  --blue-4:  oklch(0.32 0.06 266);
  --blue-5:  oklch(0.35 0.06 266);
  --blue-9:  oklch(0.57 0.20 266);
  --blue-10: oklch(0.585 0.20 266);  /* held under 0.59 so white words keep their contrast */
  --blue-11: oklch(0.66 0.17 266);

  --red-3:  oklch(0.29 0.06 27);   /* level with the other washes; 0.26 matched the card */
  --red-4:  oklch(0.32 0.06 27);
  --red-5:  oklch(0.35 0.06 27);
  --red-9:  oklch(0.57 0.20 27);
  --red-10: oklch(0.605 0.20 27);
  --red-11: oklch(0.68 0.17 27);

  --green-3:  oklch(0.28 0.05 150);
  --green-9:  oklch(0.57 0.15 150);
  --green-10: oklch(0.605 0.15 150);
  --green-11: oklch(0.72 0.17 150);

  --amber-3:  oklch(0.28 0.05 70);
  --amber-9:  oklch(0.57 0.115 70);
  --amber-10: oklch(0.605 0.115 70);
  --amber-11: oklch(0.78 0.14 70);

  --purple-3:  oklch(0.28 0.06 305);
  --purple-9:  oklch(0.57 0.18 305);
  --purple-10: oklch(0.605 0.18 305);
  --purple-11: oklch(0.72 0.15 305);

  --warning-meter: oklch(0.76 0.14 72);

  /* Graphite is near-black; on the dark sidebar it vanished. Same hue and
   * strength, lifted to the other boards' lightness. */
  --board-graphite: oklch(0.60 0.012 107);
  --divider: oklch(1 0 0 / 0.07);

  --v2-neutral-1000: oklch(1 0 0);         /* #ffffff — true black flips to white */

  /* Two grounds whose order flips in dark. In light the window (gray-2)
   * sits darker than a well in a card (gray-1); in dark the window is the
   * darkest thing and a well sits a step above the card. */
  --v2-bg-surface:   var(--gray-1);   /* window canvas, sidebar */
  --v2-bg-subtle:    var(--gray-3);   /* a well inside a card */
  --v2-text-inverse: var(--v2-bg-surface);

  /* The badge scrim has no dark value: it sits on a photo, and the photo
   * is the same in both themes. */
  --scrim: oklch(0 0 0 / 0.55);
  /* Play disc over card media — the ground is a photo either way, so this
   * stays a white disc, eased a touch for dark surroundings. */
  --color-overlay-strong: oklch(0.961 0 0 / 0.8);

  /* ---- Washes (Session 77) -------------------------------------------
   * The idea taken from the transitions.dev demo: in dark, a raised
   * surface is not a lighter grey, it is a *wash of white* over whatever
   * is beneath. Depth then reads the same on any ground, and the edge is
   * a white hairline rather than a darker one — which is why their panels
   * look lit instead of painted. */
  --v2-wash-2: oklch(1 0 0 / 0.06);   /* chips, hover */
  --v2-ring:   oklch(1 0 0 / 0.06);   /* the white hairline on a card */
  --v2-card-edge: oklch(1 0 0 / 0.08); /* the card rung's edge, dark */
  --v2-card-edge-soft: oklch(1 0 0 / 0.05);
  --v2-canvas-dot: oklch(1 0 0 / 0.035);
  --v2-canvas-frame: oklch(1 0 0 / 0.08);      /* hairline around the full-view picture */

  /* The ladder's colours, re-inked for dark: a white edge and a black
   * drop. The rungs themselves are written once, in the first block; these
   * reproduce the dark values they had before (edge 6/8/10/12%, drop
   * 30–60%). This is the one place dark depth is set. */
  --shadow-edge-6:  oklch(1 0 0 / 0.06);
  --shadow-edge-8:  oklch(1 0 0 / 0.08);
  --shadow-edge-10: oklch(1 0 0 / 0.1);
  --shadow-edge-12: oklch(1 0 0 / 0.12);
  --shadow-drop-4:  oklch(0 0 0 / 0.3);
  --shadow-drop-5:  oklch(0 0 0 / 0.35);
  --shadow-drop-6:  oklch(0 0 0 / 0.4);
  --shadow-drop-8:  oklch(0 0 0 / 0.45);
  --shadow-drop-10: oklch(0 0 0 / 0.5);
  --shadow-drop-12: oklch(0 0 0 / 0.5);
  --shadow-drop-18: oklch(0 0 0 / 0.6);
  /* The membership card, dark: the same white edge as the rungs and a
   * deeper black drop, so the card still lifts off a dark page. */
  --shadow-account-card:
    0 0 0 0.5px oklch(1 0 0 / 0.08),
    0 2px 6px oklch(0 0 0 / 0.35),
    0 10px 24px oklch(0 0 0 / 0.45);
  --shadow-account-card-hover:
    0 0 0 0.5px oklch(1 0 0 / 0.1),
    0 4px 10px oklch(0 0 0 / 0.4),
    0 16px 36px oklch(0 0 0 / 0.5);
  /* One frost, dark side. */
  --frost-surface: oklch(0.30 0 0 / 0.94);
  /* --frost-border needs no dark value: --v2-ring is already white here. */
  --v2-menu-selected: oklch(1 0 0 / 0.10);
  --v2-fold-edge: 1px 0 0 0 oklch(1 0 0 / 0.04);
  --v2-btn-inset:
    inset 0 0 0 1px oklch(1 0 0 / 0.08),
    inset 0 1px 0 0 oklch(1 0 0 / 0.1),
    inset 0 -1.5px 0 0 oklch(0 0 0 / 0.3);

  --v2-scrollbar-thumb:        oklch(1 0 0 / 0.28);
  --v2-scrollbar-thumb-hover:  oklch(1 0 0 / 0.40);
  --v2-scrollbar-thumb-active: oklch(1 0 0 / 0.52);
  --v2-inspector-scrollbar-thumb: oklch(1 0 0 / 0.25); /* #ffffff40 */

  --v2-card-foil-1: oklch(0.26 0.006 250);
  --v2-card-foil-2: oklch(0.60 0.006 250);
  --v2-card-foil-3: oklch(0.36 0.006 250);
  --v2-card-foil-4: oklch(0.54 0.006 250);
  --v2-card-foil-ring: oklch(1 0 0 / 0.16);
  --v2-card-foil-grain: oklch(1 0 0 / 0.04);
  --v2-card-foil-base: oklch(0.40 0.006 250);
  --v2-card-engrave-ink: oklch(0.92 0 0);
  --v2-card-engrave: 0 1px 0 oklch(1 0 0 / 0.18), 0 -1px 0 oklch(0 0 0 / 0.5);
  --v2-card-engrave-filter: drop-shadow(0 1px 0 oklch(1 0 0 / 0.18)) drop-shadow(0 -1px 0 oklch(0 0 0 / 0.5));

  /* Pro card gold foil — dark theme. Membership card only. */
  --v2-card-gold-1: oklch(0.62 0.07 88);
  --v2-card-gold-2: oklch(0.54 0.075 84);
  --v2-card-gold-3: oklch(0.46 0.075 80);
  --v2-card-gold-4: oklch(0.58 0.07 86);
  --v2-card-gold-ring: oklch(1 0 0 / 0.14);
  --v2-card-gold-base: oklch(0.52 0.072 84);
  --v2-card-gold-grain: oklch(0 0 0 / 0.06);
  --v2-card-gold-ink: oklch(0.93 0.04 90);
  --v2-card-gold-engrave: 0 1px 0 oklch(0 0 0 / 0.35);

  /* Three near-black alphas that had no dark answer, so on a dark surface
   * they painted black on black: the keyboard focus ring vanished, and so
   * did every edge drawn with a hairline — the chat box among them. Same
   * job, flipped to white (Session 115). --color-tint, --color-tint-strong
   * and --color-focus-fill need no dark line: they point at names that
   * already flip. */
  --focus-ring: oklch(1 0 0 / 0.32);
  --hairline: oklch(1 0 0 / 0.08);
  --color-hairline-strong: oklch(1 0 0 / 0.16);
}

/* =============================================================
 * Legacy V1 names → V2 (Session 66; sole home since Session 98).
 *
 * Components all over ui/ still ask for --color-* names. Every one of them
 * is answered here, and ONLY here: this is the single place to look up what
 * an old name resolves to. Session 98 deleted the duplicate definitions
 * that used to sit at the top of the file — they were dead, out-specified
 * by this block, and they were the reason the same colour appeared to have
 * two values.
 *
 * Order matters: this must stay AFTER the V2 block above so it wins.
 * No number lives here. If a value needs changing, change the V2 token.
 * ============================================================= */
:root {
  /* Surfaces */
  /* The names disagree with their --v2-* twins (bg-base, bg-surface mean
   * different greys in the two sets). Kept as they are — renaming would move
   * call sites — but each now names its ramp step so the value is plain. */
  --color-bg-base:        var(--gray-1);            /* the page ground behind the app; = shadcn --background */
  --color-bg-surface:     var(--v2-bg-elevated);    /* gray-0 — panels, cards, sidebar rows */
  --color-bg-elevated:    var(--v2-bg-elevated);    /* gray-0 — modals, lifted by shadow */
  --color-bg-subtle:      var(--v2-bg-base);        /* gray-4 — placeholder tiles, hover fills */
  --color-secondary-fill: var(--gray-3);            /* soft secondary button */
  /* A filled field answers with its fill, never a ring: one step under the
   * pointer, one more while you type. The ramp runs darker in light mode and
   * lighter in dark, so both read as "more" either way. */
  --color-field-hover: var(--gray-4);
  --color-field-focus: var(--gray-5);   /* the same step as --color-focus-fill */

  /* Text */
  --color-text-primary:   var(--v2-text-primary);
  --color-text-secondary: var(--v2-text-secondary);
  --color-text-tertiary:  var(--v2-text-tertiary);
  --color-text-muted:     var(--gray-8);   /* disabled text */

  /* Emphasis / actions.
   * --color-primary, --color-primary-foreground, --color-border and
   * --color-destructive are also Tailwind theme names (bg-primary,
   * border-border...), which point at the shadcn roles. These old copies
   * carry the SAME step as those roles, so the two never disagree; the
   * website and the extension, which have no Tailwind, still read them. */
  --color-destructive:         var(--red-9);         /* = shadcn --destructive */

  /* Brand blue */
  --color-brand-blue:         var(--v2-brand-blue);
  --color-brand-blue-hover:   var(--v2-brand-blue-hover);
  --color-primary:            var(--blue-9);        /* = shadcn --primary */
  --color-primary-foreground: var(--v2-button-text);
  /* Blue highlights (toggles on, tint buttons). Was --color-accent until
   * 2026-09-28; that name is the Tailwind theme's now, and there it means
   * shadcn's grey hover (--accent), not blue. */
  --color-brand-accent:       var(--v2-brand-blue);
  /* Tile hover / select ring — the same blue as a primary action. */
  --color-selection:          var(--v2-brand-blue);

  /* Borders. Subtle (gray-4, lighter on purpose: gray-6 read harsh) and strong. */
  --color-border:        var(--gray-4);   /* = shadcn --border */
  --color-border-strong: var(--v2-border-strong);

  /* Sidebar / nav (Figma frame 37:94) */
  --layout-sidebar-width:    var(--v2-sidebar-width);
  --layout-content-min:      480px;  /* the library column never shrinks below this */
  --settings-rail-width:     176px;  /* Settings tab rail; its own width, not tied to the sidebar */
  --color-nav-label:         var(--v2-text-secondary);  /* default row label */
  --color-nav-label-active:  var(--v2-text-primary);
  --color-nav-count:         var(--v2-text-tertiary);
  --color-nav-active-bg:     var(--v2-bg-elevated);     /* white pill on grey */
  --color-nav-active-border: var(--v2-border-hairline);

  /* Overlays / dim */
  --color-bg-base-90: color-mix(in oklch, var(--color-bg-base) 90%, transparent);
  --color-overlay:    color-mix(in oklch, var(--v2-neutral-0) 70%, transparent);

  /* The notch pill's two old names. The values live in the overlay block. */
}
