/* 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)
 *   1. Legacy fixed greys + the old --color-* one-offs that V2 never replaced.
 *   2. V2 — the live system. Primitives, then semantic names. Start here.
 *   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.
 *
 * 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 Inter. GT Flexa Mono is font-library content only.
 */
: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 three steps are still used directly (700, 800
   * and 1000, all in library.css); the live ramp is --v2-neutral-* below.
   * Do not add uses. The hex comments were wrong for eight of these steps
   * (they described what the ramp was meant to be, not what it renders);
   * corrected Session 98 by measuring what the browser actually paints. */
  --neutral-0:    oklch(1 0 0);      /* #ffffff */
  --neutral-25:   oklch(0.985 0 0);  /* #fafafa */
  --neutral-50:   oklch(0.973 0 0);  /* #f6f6f6 */
  --neutral-100:  oklch(0.961 0 0);  /* #f2f2f2 — Figma Home canvas */
  --neutral-200:  oklch(0.922 0 0);  /* #e5e5e5 */
  --neutral-300:  oklch(0.87 0 0);   /* #d4d4d4 */
  --neutral-400:  oklch(0.715 0 0);  /* #a3a3a3 */
  --neutral-500:  oklch(0.596 0 0);  /* #7f7f7f */
  --neutral-600:  oklch(0.49 0 0);   /* #606060 */
  --neutral-700:  oklch(0.439 0 0);  /* #525252 — Figma nav label */
  --neutral-800:  oklch(0.28 0 0);   /* #292929 */
  --neutral-900:  oklch(0.19 0 0);   /* #141414 */
  --neutral-950:  oklch(0.13 0 0);   /* #070707 */
  --neutral-1000: oklch(0 0 0);      /* #000000 */

  /* The old destructive red. Kept so the name resolves; the red the app
   * paints is --v2-red-500 (Figma #dc1e28) via --color-destructive. */
  --red-500: oklch(0.577 0.215 27.325);  /* #dc2626 */
  --red-600: oklch(0.505 0.213 27.518);  /* #c10007 */

  --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: oklch(0.562 0 0);      /* #757575 */
  --shadow-nav-active: 0 0.5px 1px 0 oklch(0.766 0.0054 48.7 / 0.08), 0 0.5px 1px 0 oklch(0.672 0.0046 56.3 / 0.08);

  /* Update pill + download card (Figma 95:3314) */
  --color-update-bg: var(--neutral-800);          /* #292929 — the same step as the ramp */
  --color-update-pct: oklch(0.683 0 0);           /* #999999 */
  --color-update-track: oklch(1 0 0 / 0.2);       /* dim line under the white fill */

  /* Board colours. The one chromatic set besides the logo: a board picks
     one of these eight. Red, amber and purple are the original three from
     Figma (95:3213 / 99:7680) and keep their exact values; the other five
     were added in Session 81 to round the set out, in the same family and
     at the same weight. */
  --color-board-red: oklch(0.694 0.1964 26.4);      /* #ff5f57 */
  --color-board-orange: oklch(0.782 0.1711 67.2);   /* #ff9f09 */
  --color-board-amber: oklch(0.835 0.1612 80.9);    /* #febc2e */
  --color-board-green: oklch(0.728 0.2173 144.7);   /* #28c840 */
  --color-board-teal: oklch(0.751 0.1266 181.8);    /* #2bc8b4 */
  --color-board-blue: oklch(0.688 0.1693 251.4);    /* #3b9eff */
  --color-board-purple: oklch(0.598 0.2541 298.0);  /* #9747ff */
  --color-board-pink: oklch(0.711 0.203 357.7);     /* #ff5fa2 */
  /* 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);
  /* Marketing site only — the Figma Website frame (95:5741) is warm on purpose.
     The app itself stays monochrome; nothing below is used inside the product. */
  --color-site-bg: oklch(0.9461 0 0);                    /* #ededed page ground */
  --color-site-ink: oklch(0.235 0 0);                    /* #1e1e1e headline + button fill */
  --color-site-ink-fill: oklch(0.9491 0 0);              /* #eeeeee label on the black button */
  --color-site-body: oklch(0.2005 0.0042 84.59 / 0.55);  /* subheading */
  --color-site-faint: oklch(0.235 0 0 / 0.4);            /* the beta line */
  --color-site-card: oklch(1 0 0);                       /* pricing cards */
  --color-site-hairline: oklch(0.235 0 0 / 0.1);         /* card edge on the site */
  --color-site-shadow: oklch(0.235 0 0 / 0.07);          /* the one card shadow */
  --color-site-code: oklch(0.235 0 0 / 0.06);            /* inline code chip */
  --color-site-foot: oklch(0.235 0 0 / 0.6);             /* footer wordmark + copyright */
  --color-site-shot-shadow: oklch(0.7663 0.0054 48.66 / 0.12); /* the app shot's own soft shadow */
  --color-hero-from: oklch(0.631 0.197 40.25);           /* #e65100 deep orange */
  --color-hero-via: oklch(0.8622 0.1681 88.31 / 0.6);    /* warm yellow at 60% — paints #ffdf7e */
  --color-hero-to: oklch(0.9461 0 0 / 0);                /* #ededed, fully transparent */

  /* Alpha variants — their own tokens, never color-mix() */
  --color-overlay-strong: oklch(0.961 0 0 / 0.85);
  --color-scrim: oklch(0.13 0 0 / 0.25);       /* behind modals */
  --color-tint: oklch(0.13 0 0 / 0.05);        /* hover wash on light */
  --color-tint-strong: oklch(0.13 0 0 / 0.09); /* active wash on light */
  --color-focus-ring: oklch(0.13 0 0 / 0.28);  /* keyboard focus outline */
  --color-hairline: oklch(0.13 0 0 / 0.06);    /* inset 0.5px edge */
  --color-hairline-strong: oklch(0.13 0 0 / 0.12); /* swatch ring, outline button edge */
  /* The wash under a hovered / pressed destructive button. These are the OLD
   * red (--red-500), not --color-destructive — which now points at Figma's
   * #dc1e28. So the wash sits a shade warmer than the label on top of it.
   * Left alone on purpose: changing it would move a colour. */
  --color-destructive-wash: oklch(0.577 0.215 27.325 / 0.08);
  --color-destructive-wash-strong: oklch(0.577 0.215 27.325 / 0.15);

  /* Font family.
     UI is a neutral grotesque. GT Flexa Mono appears in the Figma as library
     *content* (a font being previewed), not as the interface face — see
     docs/figma-notes.md before promoting it to the UI. */
  --font-sans: "Inter", system-ui, sans-serif;
  /* Parry is the brand serif. Marketing headline + wordmark only. */
  --font-display: "Parry", Georgia, "Times New Roman", serif;

  /* Type scale — sizes are what you see on screen (Session 99).
     Was written larger then shrunk with zoom:0.9; that broke menus.
     These numbers ARE the old on-screen sizes, no zoom. */
  --text-h3: 16px;        --leading-h3: 24px;
  --text-body: 14px;      --leading-body: 20px;
  --text-label: 13px;     --leading-label: 18px;
  --text-caption: 12px;   --leading-caption: 16px;
  --text-overline: 11px;  --leading-overline: 14px;  --tracking-overline: 0.07em;
  /* HeroUI relaxed leading */
  --leading-label-relaxed: 20px;
  --leading-overline-relaxed: 18px;
  --leading-body-relaxed: 24px;

  --font-weight-regular: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;

  /* 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 */
  --spacing-xl: 20px;   /* 5 */
  --spacing-2xl: 24px;  /* 6 */
  --spacing-3xl: 32px;  /* 8 */
  --spacing-4xl: 40px;  /* 10 */

  /* Layout */
  --layout-sidebar-width: 200px;
  --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;
  /* Shared hit target for chrome toggle, tools, collapsed nav squares. */
  --control-size: 28px;
  --control-icon: 16px;

  /* ---------- 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-menu: 300;     /* a menu — it must clear the dialog that opened it */
  --layer-shelf: 500;    /* the shake shelf, dropped on from another app */
  --layer-toast: 1000;   /* the last word; nothing covers a toast */

  /* ---------- Motion — three durations, two easings (Phase 4) ----------
   * Canonical names: --duration-fast/base/slow and --ease-enter/leave.
   * Every older name aliases onto one of these so call sites keep working.
   * JS reads these via ui/src/lib/motion.ts — no hardcoded seconds there. */
  --duration-fast: 120ms;   /* hover, colour, opacity under the cursor; dismiss */
  --duration-base: 180ms;   /* appear, move, resize */
  --duration-slow: 260ms;   /* panel, menu, modal */

  --ease-enter: cubic-bezier(0.22, 1, 0.36, 1); /* arrive, settle soft */
  --ease-leave: cubic-bezier(0.4, 0, 1, 1);     /* straight out, 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);

  /* Legacy duration aliases → the three */
  --spring-fast-enter:     var(--duration-fast);
  --spring-fast-exit:      var(--duration-fast);
  --spring-moderate-enter: var(--duration-base);
  --spring-moderate-exit:  var(--duration-fast);
  --spring-slow-enter:     var(--duration-slow);
  --spring-slow-exit:      var(--duration-base);

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

  /* ---------- 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: six 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. */
  --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;   /* the largest 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 */

  /* 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-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, inspector, a resting control. Barely there.
   *   card     a library card, a settings sheet — the everyday lift.
   *   float    menus, popovers, toasts. Carries a hairline ring.
   *   modal    dialogs. The deepest thing on screen.
   *
   * Exactly one shadow token per rung, plus the hairline edge. Nothing may
   * wear a shadow that is not on this ladder. There used to be 15 tokens
   * for these 5 rungs; the extra names all survive below as aliases so no
   * call site broke, but they hold no numbers of their own.
   *
   * The ink is neutral-900 (#212121) at low alpha — one colour, six
   * weights (--v2-shadow-ink-*, declared in the V2 block).
   *
   * 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-hairline: inset 0 0 0 0.5px var(--color-hairline);
  --shadow-page:  none;
  --shadow-panel: 0 1px 2px var(--v2-shadow-ink-6);
  --shadow-card:
    0 1px 2px var(--v2-shadow-ink-4),
    0 2px 8px var(--v2-shadow-ink-5);
  --shadow-float:
    0 0 0 1px var(--v2-ring),
    0 1px 2px var(--v2-shadow-ink-4),
    0 8px 24px var(--v2-shadow-ink-8);
  /* Menus — a step deeper than float so white cards clear the toolbar. */
  --shadow-menu:
    0 0 0 1px var(--v2-ring),
    0 4px 12px var(--v2-shadow-ink-8),
    0 16px 40px var(--v2-shadow-ink-12);
  /* Figma shadow/overlay (frame 143:49 dialog) — deeper than card. Written
   * for dialogs and used by nothing until now, which is why a dialog did
   * not read as further forward than the panel behind it. */
  --shadow-modal:
    0 1px 3px var(--v2-shadow-ink-8),
    0 8px 24px var(--v2-shadow-ink-12);

  /* Off the ladder on purpose — art, not depth. The membership card is a
   * physical object lying on the page, so it throws a real object's shadow;
   * the crown wears a 1px light along its top edge, which is a highlight,
   * not a shadow. Nothing else may use these three. */
  --shadow-account-card:
    0 6px 14px var(--v2-shadow-ink-8),
    0 24px 40px oklch(0 0 0 / 0.16);       /* #000 16% */
  --shadow-account-card-hover:
    0 10px 20px var(--v2-shadow-ink-10),
    0 32px 56px oklch(0 0 0 / 0.2);        /* #000 20% */
  --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 */

  /* 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: oklch(0.52 0.2 265);
  --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;

  /* Borders */
  --border-destructive: 1px solid var(--color-destructive-outline);
}

/* 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 {
  /* ---------- Primitives — neutral ramp ----------
   * Chroma 0, every step. This is the ramp that follows the theme: each
   * step is re-declared in the dark set, so a component names a step and
   * gets the right grey in both. WHAT EACH BAND IS FOR — written from how
   * the app actually paints today, not from an ideal:
   *
   *   0        the raised sheet. Cards, modals, the inspector — anything
   *            that should read as sitting on top. (--v2-bg-elevated)
   *   50       a quiet well sunk into a sheet. Placeholder tiles, the
   *            outline button's fill. (--v2-bg-subtle)
   *   75       chips and quiet pills: tag chips, the slider track, a small
   *            inset field.
   *   100      the everyday quiet fill: secondary button, hover wash on a
   *            plain row, thin dividers. (--color-secondary-fill)
   *   150      the app canvas, and the resting fill of a filled-but-quiet
   *            control. One step stronger than 100, so hover reads.
   *            (--v2-bg-base)
   *   200      that same control pressed, and a filled progress bar.
   *   300      the hairline. Borders, the outline button's edge, a pressed
   *            filter pill. (--v2-border-subtle)
   *   400      a stronger edge, and the quietest text or icon you may use
   *            — disabled labels, decorative marks.
   *            (--v2-border-strong / --v2-icon-muted / --color-text-muted)
   *   500      quiet supporting text: notes, meta, timestamps.
   *   600      secondary text with a job to do — an inspector value, a
   *            chip's label.
   *   700-900  unused today. Do not reach for them without a reason; the
   *            gap between 600 and 950 is deliberate.
   *   950      primary text, and the fill of an inverted surface such as a
   *            toast. (--v2-text-primary / --v2-bg-inverse)
   *   1000     true black. One use, in the window chrome. Text should be
   *            950, not this.
   *
   * Rule of thumb: surfaces come from the light end (0-300), words from
   * the dark end (400-950). If you want emphasis, move two steps, not one. */
  --v2-neutral-0:    oklch(1 0 0);         /* #ffffff */
  --v2-neutral-50:   oklch(0.97315 0 0);   /* #f6f6f6 — background/subtle (Figma) */
  --v2-neutral-75:   oklch(0.95514 0 0);   /* #f0f0f0 — Figma surface4 */
  --v2-neutral-100:  oklch(0.94309 0 0);   /* #ececec */
  --v2-neutral-150:  oklch(0.931 0 0);     /* #e8e8e8 — background/base (Figma) */
  --v2-neutral-200:  oklch(0.90365 0 0);   /* #dfdfdf */
  --v2-neutral-300:  oklch(0.88531 0 0);   /* #d9d9d9 — border/subtle (Figma) */
  --v2-neutral-400:  oklch(0.7731 0 0);    /* #b5b5b5 */
  --v2-neutral-500:  oklch(0.63343 0 0);   /* #8a8a8a */
  --v2-neutral-600:  oklch(0.5278 0 0);    /* #6b6b6b */
  --v2-neutral-700:  oklch(0.40912 0 0);   /* #4a4a4a */
  --v2-neutral-800:  oklch(0.29313 0 0);   /* #2c2c2c */
  --v2-neutral-900:  oklch(0.24776 0 0);   /* #212121 — neutral/900 (Figma) */
  --v2-neutral-950:  oklch(0.23929 0 0);   /* #1f1f1f — text/primary (Figma) */
  --v2-neutral-1000: oklch(0 0 0);         /* #000000 */

  /* ---------- Primitives — brand blue (Figma default #3d6aff) ---------- */
  --v2-blue-50:  oklch(0.96191 0.01793 272.31);  /* #eef2ff */
  --v2-blue-100: oklch(0.91298 0.04187 273.72);  /* #d9e1ff */
  --v2-blue-200: oklch(0.82819 0.08528 271.98);  /* #b3c4ff */
  --v2-blue-300: oklch(0.74345 0.13141 269.61);  /* #8ba7ff */
  --v2-blue-400: oklch(0.66084 0.17932 268.13);  /* #6489ff */
  --v2-blue-500: oklch(0.58347 0.2268 266.37);   /* #3d6aff — accent/brand-blue */
  --v2-blue-600: oklch(0.51778 0.21275 266.43);  /* #3057e0 */
  --v2-blue-700: oklch(0.44249 0.18644 266.46);  /* #2444b8 */
  --v2-blue-800: oklch(0.3629 0.14789 266.42);   /* #1a338a */
  --v2-blue-900: oklch(0.27692 0.10349 266.11);  /* #10225a */

  /* ---------- Primitives — destructive red (Figma #dc1e28) ---------- */
  --v2-red-50:  oklch(0.95656 0.01849 17.48);   /* #fdecec */
  --v2-red-500: oklch(0.57293 0.21913 25.99);   /* #dc1e28 — accent/destructive-red */
  --v2-red-600: oklch(0.49994 0.19301 26.39);   /* #b8151d */
  --v2-red-700: oklch(0.41607 0.15953 25.98);   /* #8f0f16 */

  /* ---------- Primitives — success green (Figma 89:461, Session 69) ----------
   * Used for the "Access Granted" state on the Permissions onboarding step
   * and Settings → Permissions. 500 is Figma's own `text4` swatch from the
   * Onboarding-Permission frame — do not drift it toward a generic green.
   * Only extra colour in V2 outside the neutral / blue / red families. */
  --v2-green-50:  oklch(0.96282 0.02386 159.15);  /* #e6f8ed */
  --v2-green-500: oklch(0.68139 0.20546 146.43);  /* #01b83f — Figma text4 */
  --v2-green-600: oklch(0.58612 0.17652 146.46);  /* #019632 */
  --v2-green-700: oklch(0.48986 0.14673 146.61);  /* #017526 */

  /* ---------- Semantic aliases — surface & text (Figma pulled 2026-09-02) ---------- */
  --v2-bg-base:      var(--v2-neutral-150);   /* app canvas / secondary btn */
  --v2-bg-subtle:    var(--v2-neutral-50);    /* placeholder tiles, outline btn */
  --v2-bg-elevated:  var(--v2-neutral-0);     /* modals, cards, elevated btn */
  --v2-bg-surface:   oklch(0.96115 0 0);      /* #f2f2f2 — Figma background/surface, sidebar */
  --v2-bg-inverse:   var(--v2-neutral-950);   /* toasts on dark */

  --v2-text-primary:   var(--v2-neutral-950);      /* #1f1f1f — Figma text/primary */
  --v2-text-secondary: oklch(0.41283 0 0);         /* #4b4b4b — Figma text/secondary, nav labels */
  --v2-text-tertiary:  oklch(0.61671 0 0);         /* #858585 — Figma text/tertiary, nav icons */
  --v2-text-inverse:   var(--v2-neutral-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(--v2-blue-500);
  --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 — for decorative marks that should
   * recede behind the text they sit above. Its own value: it sits between
   * tertiary (#858585) and --color-text-muted (#b5b5b5), matching neither. */
  --v2-icon-muted:     oklch(0.71547 0 0);        /* #a3a3a3 — Figma dialog close 143:49 */

  --v2-border-subtle:   var(--v2-neutral-300);
  --v2-border-strong:   var(--v2-neutral-400);
  --v2-border-hairline: oklch(0.94611 0 0);       /* #ededed — Figma stroke/border, dividers */
  /* Card edge — primary black at 14%. Keeps a white image from melting
   * into the canvas without drawing a visible frame. */
  --v2-card-edge: oklch(0 0 0 / 0.14);
  --v2-canvas-dot: oklch(0 0 0 / 0.08);       /* full-view dot grid */
  /* 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);
  --v2-warning: oklch(0.7225 0.14883 69.64);  /* #e0921f — nearly-full meters, calmer than destructive */

  /* Actions */
  --v2-brand-blue:         var(--v2-blue-500);
  --v2-brand-blue-hover:   var(--v2-blue-600);
  --v2-brand-blue-active:  var(--v2-blue-700);
  --v2-destructive:        var(--v2-red-500);
  --v2-destructive-hover:  var(--v2-red-600);
  --v2-destructive-active: var(--v2-red-700);
  --v2-success:            var(--v2-green-500);
  --v2-button-text:        oklch(1 0 0);            /* label on an accent fill — never flips with the theme */

  /* ---------- Type — Inter Variable via Google Fonts range 100..900 ---------- */
  --v2-font-family: "Inter", ui-sans-serif, system-ui, sans-serif;

  /* One scale, 7 stops. Session 99: these ARE on-screen sizes (no zoom).
     Old written 14 @ zoom 0.9 ≈ 13 on screen — now written 13. */
  --v2-text-display:   700 36px/44px var(--v2-font-family);   /* hero, empty-state title */
  --v2-text-heading:   600 24px/32px var(--v2-font-family);   /* section titles */
  --v2-text-title:     600 18px/24px var(--v2-font-family);   /* card / modal titles */
  --v2-text-body-lg:   400 14px/20px var(--v2-font-family);   /* long-form reading */
  --v2-text-body-md:   500 14px/20px var(--v2-font-family);   /* body md */
  --v2-text-body:      400 13px/18px var(--v2-font-family);   /* default UI copy */
  --v2-text-label:     500 13px/18px var(--v2-font-family);   /* small non-button label */
  --v2-text-caption:   400 11px/14px var(--v2-font-family);   /* meta, timestamps */
  --v2-text-overline:  500 10px/14px var(--v2-font-family);   /* uppercase section labels */

  /* Button / section typography */
  --v2-text-section:    600 14px/20px var(--v2-font-family);

  /* Tight-leading labels — line-box hugs the glyph. */
  --v2-text-body-bold:    700 13px/13px var(--v2-font-family);
  --v2-text-body-relaxed: 400 13px/20px var(--v2-font-family);
  --v2-text-small-bold:   700 12px/14px var(--v2-font-family);
  --v2-text-label-bold:   700 14px/14px var(--v2-font-family);

  --v2-tracking-tight:    -0.01em;
  --v2-tracking-overline: 0.06em;

  /* ---------- 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 */

  /* ---------- Sidebar ----------
   * Session 99: baked from the old 0.9 zoom look (was 220 / 36). */
  --v2-sidebar-width:            200px;
  --v2-sidebar-inner-padding:    12px;

  --v2-nav-row-height:      32px;
  --v2-nav-row-radius:      8px;
  --v2-nav-row-padding-x:   12px;
  --v2-nav-row-padding-y:   4px;
  --v2-nav-row-gap:         4px;
  --v2-nav-icon-gap:        8px;
  /* ---- 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-slow);  /* was 250ms */
  --tr-modal-close: var(--duration-fast);  /* was 150ms — dismiss stays quick */
  --tr-morph-open:  var(--duration-slow);  /* was 350ms */

  --tr-modal-scale: 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 six weights the depth ladder is built from. One colour —
   * neutral-900 (#212121) — at six alphas. The ladder itself lives in the
   * first block of this file, under "Shadows — THE DEPTH LADDER". */
  --v2-shadow-ink-4:  oklch(0.24776 0 0 / 0.04);
  --v2-shadow-ink-5:  oklch(0.24776 0 0 / 0.05);
  --v2-shadow-ink-6:  oklch(0.24776 0 0 / 0.06);
  --v2-shadow-ink-8:  oklch(0.24776 0 0 / 0.08);
  --v2-shadow-ink-10: oklch(0.24776 0 0 / 0.1);
  --v2-shadow-ink-12: oklch(0.24776 0 0 / 0.12);

  /* 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 surfaces behind that blur. Both point at the one tint. */
  --v2-menu-surface:  var(--v2-bg-elevated); /* solid card — menus, not frost */
  --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);
  --v2-menu-divider:  var(--v2-border-hairline);
  /* The sidebar's right edge — a fold, not a stroke. In light that is a
   * hairline with a whisper of shade beside it; in dark the shade does the
   * work and the light line all but disappears (Session 78: it used to be a
   * hard 25% white line in both themes, which looked wrong on dark). */
  --v2-fold-edge:
    1px 0 0 0 oklch(1 0 0 / 0.25),
    2px 0 4px -1px oklch(0 0 0 / 0.05);
  /* 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);

  /* ---------- 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.20019 0 0);   /* #161616 */
  --v2-preview-dark-panel:   oklch(0.20463 0 0);   /* #171717 */

  /* ---------- Membership card foil (Session 72) ----------
   * The base sheet under the iridescent layers. Cool silver-blue: the
   * owner asked for a bluish card. Four stops, 135deg, light → deep → light. */
  --v2-card-foil-1: oklch(0.93557 0.01913 263.01);  /* #e3eaf7 */
  --v2-card-foil-2: oklch(0.86953 0.03832 260.69);  /* #c6d5ee */
  --v2-card-foil-3: oklch(0.78808 0.06126 260.95);  /* #a4bbe2 */
  --v2-card-foil-4: oklch(0.91683 0.02386 262.09);  /* #dbe4f4 */
  --v2-card-foil-ring: oklch(1 0 0 / 0.45);
}

/* =============================================================
 * 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. --v2-blue-500 is safe to
   * point at here because it is the same in both themes. */
  --overlay-shelf-accent:      color-mix(in oklch, var(--v2-blue-500) 95%, transparent);
  --overlay-shelf-accent-ink:  var(--v2-button-text);
  /* The ring while a drag is over the card. This is Apple's own system
   * blue (#0a84ff), NOT --v2-blue-500 — deliberately the OS colour for an
   * OS-level drop target, and it does not match the pill beside it. */
  --overlay-shelf-ring:        oklch(0.62425 0.20558 255.49 / 0.95);
  --overlay-shelf-spinner-track: oklch(1 0 0 / 0.35);
  --overlay-shelf-lift:        0 6px 16px oklch(0 0 0 / 0.3);   /* under a thumbnail */
  --overlay-shelf-lift-active: 0 6px 16px oklch(0 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);
  --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 0 0 / 0.32),
    0 4px 12px oklch(0 0 0 / 0.2);
  /* The pill's warm accent. Declared, but nothing paints with it today. */
  --overlay-notch-accent:      oklch(0.71 0.2 41);        /* #ff6b28 */
}

/* The Mac in light appearance. Only the shelf changes — see above. */
@media (prefers-color-scheme: light) {
  :root {
    /* These repeat the numbers from --v2-neutral-50 / text-primary / secondary
     * on purpose. Do NOT swap them for var(--v2-...): those tokens 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.97315 0 0 / 0.55);  /* the neutral-50 grey, 55% */
    --overlay-shelf-ink:      oklch(0.23929 0 0 / 0.95);  /* the text/primary grey, 95% */
    --overlay-shelf-ink-dim:  oklch(0.41283 0 0 / 0.75);  /* the text/secondary grey, 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.23929 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"] {
  /* Neutral ramp — pure greys, canvas darkest, raised cards lighter.
   *
   * Session 77 lifted the whole ramp. The first cut sat on near-black
   * (#0f0f0f canvas, #171717 cards) and the owner was right that it read
   * badly: a black canvas makes every card look like a hole, and a #262626
   * hairline on a #171717 card is invisible. The canvas is a grey now, the
   * cards are three steps above it, and the strokes are light enough to
   * actually draw an edge. OKLCH lightness is the first number. */
  --v2-neutral-0:    oklch(0.26032 0 0);   /* #242424 — raised cards, inspector, modals */
  --v2-neutral-50:   oklch(0.27685 0 0);   /* #282828 — subtle wells */
  --v2-neutral-75:   oklch(0.30118 0 0);   /* #2e2e2e — chips, quiet pills */
  --v2-neutral-100:  oklch(0.32109 0 0);   /* #333333 — fields */
  --v2-neutral-150:  oklch(0.34846 0 0);   /* #3a3a3a — strong fills, "on" pills */
  --v2-neutral-200:  oklch(0.3753 0 0);    /* #414141 */
  --v2-neutral-300:  oklch(0.40912 0 0);   /* #4a4a4a — border/subtle */
  --v2-neutral-400:  oklch(0.48193 0 0);   /* #5e5e5e */
  --v2-neutral-500:  oklch(0.56241 0 0);   /* #757575 */
  --v2-neutral-600:  oklch(0.64009 0 0);   /* #8c8c8c */
  --v2-neutral-700:  oklch(0.73159 0 0);   /* #a8a8a8 */
  --v2-neutral-800:  oklch(0.85451 0 0);   /* #cfcfcf */
  --v2-neutral-900:  oklch(0.91887 0 0);   /* #e4e4e4 */
  --v2-neutral-950:  oklch(0.96115 0 0);   /* #f2f2f2 — text/primary */
  --v2-neutral-1000: oklch(1 0 0);         /* #ffffff */

  --v2-blue-50:  oklch(0.29226 0.06051 268.19);  /* #1f2a4a */
  --v2-blue-100: oklch(0.34947 0.08424 268.48);  /* #283766 */

  --v2-red-50:   oklch(0.25394 0.05872 17.28);   /* #3a1518 */
  --v2-green-50: oklch(0.27865 0.05304 153.66);  /* #10301c */

  --v2-bg-base:      var(--v2-neutral-150);
  --v2-bg-subtle:    var(--v2-neutral-50);
  --v2-bg-elevated:  var(--v2-neutral-0);
  --v2-bg-surface:   oklch(0.22645 0 0);   /* #1c1c1c — window canvas, sidebar */
  --v2-bg-inverse:   var(--v2-neutral-950);

  --v2-text-primary:   oklch(0.94611 0 0);   /* #ededed */
  --v2-text-secondary: oklch(0.73159 0 0);   /* #a8a8a8 — = neutral-700 here */
  --v2-text-tertiary:  oklch(0.57951 0 0);   /* #7a7a7a */
  --v2-text-inverse:   var(--v2-bg-surface); /* #1c1c1c */
  /* Comment bubbles stay brand blue + white in dark too. */
  --v2-comment-bg:     var(--v2-blue-500);
  --v2-comment-text:   var(--color-white);

  /* Icons follow text, same as in light. */
  --v2-icon-muted:     var(--v2-neutral-400);

  --v2-border-subtle:   var(--v2-neutral-300);
  --v2-border-strong:   var(--v2-neutral-400);
  --v2-border-hairline: var(--v2-neutral-75);   /* #2e2e2e */
  /* A black pill on a dark card reads as a hole; lift both scrims. */
  --color-scrim-badge: oklch(1 0 0 / 0.14);
  --color-scrim: oklch(0 0 0 / 0.55);

  /* ---- 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.10);
  --v2-canvas-dot: oklch(1 0 0 / 0.06);
  --v2-warning: oklch(0.77828 0.14202 76.22);   /* #eaa93c */

  /* Their dark blue is lighter than their light one — #0071e2 becomes
   * #3b9bff — because a saturated mid blue goes muddy on a dark ground. */
  --v2-brand-blue:        oklch(0.6261 0.20037 265.63);   /* #4d7dff */
  --v2-brand-blue-hover:  var(--v2-blue-400);
  --v2-brand-blue-active: var(--v2-blue-300);

  /* The same five-rung ladder, re-inked for dark. Only the rungs are
   * declared here — every --v2-shadow-* / --shadow-* alias follows them,
   * so this is the one place dark depth is set. On a dark ground a raised
   * surface reads as a ring plus a deeper drop, not a lighter grey. */
  --shadow-panel: 0 1px 2px oklch(0 0 0 / 0.25);
  --shadow-card:
    0 0 0 1px var(--v2-ring),
    0 1px 2px oklch(0 0 0 / 0.35),
    0 4px 16px oklch(0 0 0 / 0.4);
  --shadow-float:
    0 0 0 1px var(--v2-ring),
    0 1px 2px oklch(0 0 0 / 0.35),
    0 8px 24px oklch(0 0 0 / 0.42);
  --shadow-menu:
    0 0 0 1px var(--v2-ring),
    0 4px 12px oklch(0 0 0 / 0.45),
    0 16px 40px oklch(0 0 0 / 0.55);
  --shadow-modal:
    0 1px 3px oklch(0 0 0 / 0.4),
    0 8px 24px 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),
    3px 0 8px -2px oklch(0 0 0 / 0.45);
  --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-card-foil-1: oklch(0.3258 0.03782 265.61);   /* #2b3448 */
  --v2-card-foil-2: oklch(0.27593 0.03245 261.68);  /* #1f2838 */
  --v2-card-foil-3: oklch(0.38897 0.04857 261.17);  /* #36455f */
  --v2-card-foil-4: oklch(0.31717 0.03854 263.79);  /* #283246 */
  --v2-card-foil-ring: oklch(1 0 0 / 0.1);

  /* Carried over from the retired V1 dark block. The two --shadow-* lines
   * that used to sit here are gone: they are rungs of the ladder above now,
   * and a rung is set in exactly one place. */
  --color-tint: oklch(1 0 0 / 0.06);
  --color-tint-strong: oklch(1 0 0 / 0.1);
}

/* =============================================================
 * 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 */
  --color-bg-base:        var(--v2-bg-subtle);      /* the app canvas */
  --color-bg-surface:     var(--v2-bg-elevated);    /* panels, cards, sidebar rows */
  --color-bg-elevated:    var(--v2-bg-elevated);    /* modals — lifted by shadow */
  --color-bg-subtle:      var(--v2-bg-base);        /* placeholder tiles, hover fills */
  --color-secondary-fill: var(--v2-neutral-100);    /* soft secondary button */

  /* 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(--v2-neutral-400);

  /* Emphasis / actions */
  --color-emphasis-foreground: var(--v2-button-text);
  --color-destructive:         var(--v2-destructive);
  --color-destructive-outline: color-mix(in oklch, var(--v2-destructive) 40%, transparent);

  /* Brand blue */
  --color-brand-blue:         var(--v2-brand-blue);
  --color-brand-blue-hover:   var(--v2-brand-blue-hover);
  --color-primary:            var(--v2-brand-blue);
  --color-primary-foreground: var(--v2-button-text);
  /* shadcn accent role — blue highlights (toggles on, tint buttons, hovers) */
  --color-accent:             var(--v2-brand-blue);
  /* App primary button fill is blue. The marketing site keeps --color-site-ink. */
  --color-button-fill:        var(--v2-brand-blue);
  --color-button-fill-hover:  var(--v2-brand-blue-hover);
  --color-button-fill-active: var(--v2-brand-blue-active);
  /* Tile hover / select ring — the same blue as a primary action. */
  --color-selection:          var(--v2-brand-blue);

  /* Borders. Both point at the same step: the V1 pair drew two weights,
   * V2 has one hairline, and nobody has asked for the second back. */
  --color-border:        var(--v2-border-subtle);
  --color-border-strong: var(--v2-border-subtle);

  /* Sidebar / nav (Figma frame 37:94) */
  --layout-sidebar-width:    var(--v2-sidebar-width);
  --color-nav-label:         var(--v2-text-secondary);  /* default row label */
  --color-nav-label-active:  var(--v2-text-primary);
  --color-nav-icon:          var(--v2-icon-tertiary);   /* inactive icon */
  --color-nav-icon-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);
  --color-nav-section:       var(--v2-text-tertiary);

  /* Overlays / dim */
  --color-bg-base-90: color-mix(in oklch, var(--v2-bg-subtle) 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. */
}
