/* Design system tokens — `--ds-*` namespace.
 *
 * The `--ds-*` set is the opt-in design system introduced by the
 * /home redesign: green/navy palette, system font stack, light/dark
 * surface pair, blue-info + amber-warn callout vocabularies.
 *
 * Pages opt into the design system by adding a scope class
 * (`.home-mock`, `.advanced-mock`) and referencing `var(--ds-*)`.
 * Tokens live globally so any future page (or shared component) can
 * pick them up without re-declaring values.
 *
 * The legacy `--primary` family in style-custom.css remains the
 * default app brand (blue) used by login, dashboard, catalog,
 * marketplace, admin, etc. The two systems coexist — pages that
 * haven't been redesigned keep reading `var(--primary)` and stay
 * blue; redesigned pages reference `var(--ds-*)` and get the green
 * surface.
 */

:root {
    /* Native form controls (inputs/selects/textareas) + scrollbars render in
       the light UA palette; `[data-theme="dark"]` below flips this to `dark`
       so a default-styled field with no explicit background doesn't stay
       white on a dark surface. */
    color-scheme: light;

    /* Brand surface — green/navy palette. Opted into via the
       `.home-mock` / `.advanced-mock` scopes. */
    --ds-primary: #2ea877;          /* brand-dark green */
    --ds-primary-dark: #1f8a5e;     /* hover/active */
    --ds-primary-light: #e6f9f0;    /* mint tint */
    --ds-brand-accent: #54d3a0;     /* brand (lighter) */

    /* Hero surface — deep navy used by setup hero + first-session
       terminal-frame backgrounds. Reads as the visual ground for any
       "this is what your terminal will look like" mock-up. */
    --ds-hero-bg: #0f1b3a;
    --ds-hero-bg-deep: #0a1430;
    --ds-hero-ink: #f3f6ff;

    /* Code-panel surface — near-black bg with cool-blue ink + warm
       yellow command accent. Used by `.code-block` (copyable install
       command), `.terminal-body`, expected-output blocks. */
    --ds-code-bg: #0c1224;
    --ds-code-ink: #d7e4ff;
    --ds-code-yellow: #ffd866;

    /* Syntax-token palette for highlighted code painted on
       --ds-code-bg. The vendored highlight.js sheet ships GitHub's
       LIGHT theme (near-black / navy / dark-blue tokens meant for a
       white page), which is unreadable on our dark code surface —
       chat.css remaps every hljs token family onto these instead.
       Every value clears 5.5:1 against --ds-code-bg in BOTH themes
       (blue #0c1224 and paper #1c1b1a), so the set is declared once
       here and inherited by the paper override below. */
    --ds-code-keyword: #ff7b72;   /* keyword, type, doctag */
    --ds-code-title: #d2a8ff;     /* function / class names */
    --ds-code-literal: #79c0ff;   /* number, literal, attr, operator */
    --ds-code-string: #a5d6ff;    /* string, regexp */
    --ds-code-builtin: #ffa657;   /* built_in, symbol */
    --ds-code-comment: #8b949e;   /* comment, formula */
    --ds-code-tag: #7ee787;       /* tag/selector name, quote */
    --ds-code-bullet: #f2cc60;    /* list bullets in md blocks */
    --ds-code-addition-ink: #7ee787;
    --ds-code-addition-bg: rgba(46, 160, 67, 0.15);
    --ds-code-deletion-ink: #ffa198;
    --ds-code-deletion-bg: rgba(248, 81, 73, 0.15);

    /* Light surface — page background, card surface, dim variant
       for inset panels. */
    --ds-bg: #f6f7fa;
    --ds-surface: #ffffff;
    --ds-surface-dim: #f0f2f6;
    /* Sunken — inset panels that must read a shade DARKER than the page
       canvas (grouping trays), unlike --ds-surface-dim which is a near-bg
       wash. */
    --ds-surface-sunken: #eaeef2;
    --ds-border: #e4e7ee;
    --ds-border-light: #f0f2f6;

    /* Text — primary / secondary / muted on light surfaces. Primary
       is near-black for body copy; muted is for chrome (timestamps,
       hints, captions). */
    --ds-text-primary: #0e1525;
    --ds-text-secondary: #4a5168;
    --ds-text-muted: #788098;

    /* Accent — orange used for terminal `[3]`-style prompts and the
       Cowork surface card warning chip. */
    --ds-orange: #C2410C;
    --ds-orange-light: #FED7AA;

    /* Callout vocabularies — `.callout-hint` (blue info) and
       `.callout-rec` (amber recommendation). Background +
       left-border + ink so the box reads at a glance. */
    --ds-info-bg: #eef3ff;
    --ds-info-ink: #1c3994;
    --ds-info-line: #4f7cf2;
    --ds-warn-bg: #fff8e6;
    --ds-warn-ink: #6e4d00;
    --ds-warn-line: #f5c84b;

    /* Elevation — navy-tinted shadow stack. Matches the deep-navy
       hero so the depth perception reads consistently across the
       page. */
    --ds-shadow-sm: 0 1px 2px rgba(15, 27, 58, .05), 0 1px 3px rgba(15, 27, 58, .06);
    --ds-shadow-md: 0 4px 16px rgba(15, 27, 58, .08);
    --ds-shadow-lg: 0 8px 24px rgba(15, 27, 58, .14);

    /* Hero box-shadow tint — used by `.page-header--hero`,
       `.stack-hero`, `.env-setup-cta`. Flipped per theme so the
       drop-shadow colour follows the gradient. */
    --ds-hero-shadow: rgba(15, 27, 58, 0.22);

    /* Hero eyebrow colour — green accent on top of the navy
       gradient by default. The "blue" theme aliases this to a
       translucent white because mint-green on blue reads poorly. */
    --ds-hero-eyebrow: var(--ds-brand-accent);

    /* Hero CTA pill — `<a class="btn-intro-primary">` on /home's
       intro hero. Mint-green-on-navy by default; the "blue" theme
       flips it to white-on-blue because mint-on-blue has poor
       contrast. */
    --ds-hero-cta-bg: var(--ds-brand-accent);
    --ds-hero-cta-fg: var(--ds-hero-bg);
    --ds-hero-cta-bg-hover: var(--ds-primary);
    /* On hover the bg darkens to --ds-primary; switch text to white
       so contrast stays high (dark navy on medium-dark green ≈ 5.6:1,
       white on --ds-primary ≈ 8.5:1). */
    --ds-hero-cta-fg-hover: #ffffff;

    /* Typography — system stack so weight + letterforms render
       identically on macOS (San Francisco) and Windows (Segoe UI).
       Inter remains a graceful fallback in the cascade. */
    --ds-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", sans-serif;
    --ds-font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* ─── Theme: blue (pre-redesign palette) ──────────────────────────
   Activated by `<html data-theme="blue">`. Overrides only the
   tokens that diverge from the default navy theme:
     - brand fill          → blue (legacy `--primary`)
     - hero gradient       → blue → blue-dark
     - eyebrow accent      → translucent white (mint-green on blue
                              reads poorly)
     - drop-shadow tint    → blue
   Everything else (surfaces, callouts, code panels, fonts)
   stays the same. Page markup and component classes don't change
   between themes. */
:root[data-theme="blue"] {
    --ds-primary: var(--primary);
    --ds-primary-dark: var(--primary-dark);
    --ds-primary-light: var(--primary-light);
    --ds-brand-accent: var(--brand-accent);

    --ds-hero-bg: var(--primary);
    --ds-hero-bg-deep: var(--primary-dark);

    --ds-hero-shadow: rgba(0, 115, 209, 0.20);
    --ds-hero-eyebrow: rgba(255, 255, 255, 0.92);

    /* Blue theme — hero CTA pill flips to white-on-blue. Mint-green
       on blue reads badly; white on the brand-blue gradient has
       full contrast. Hover state darkens to a translucent white. */
    --ds-hero-cta-bg: #ffffff;
    --ds-hero-cta-fg: var(--primary-dark);
    --ds-hero-cta-bg-hover: rgba(255, 255, 255, 0.88);
    /* Blue theme: bg on hover stays near-white, keep dark text for contrast. */
    --ds-hero-cta-fg-hover: var(--primary-dark);

    /* `.callout-hint` info-bg vocabulary — default is a cool-blue
       indigo (#eef3ff / #4f7cf2 / #1c3994) that reads as a
       distinct "info" hue on the navy theme. Under the brand-blue
       theme the indigo clashes with the hero gradient; re-tint to
       brand-blue so all the blue surfaces share a hue family. */
    --ds-info-bg: rgba(0, 115, 209, 0.08);
    --ds-info-line: var(--primary);
    --ds-info-ink: var(--primary-dark);
}

/* ─── Design-system additions driven by .interface-design/system.md ────
   Tokens consumed by the .ds-card family, the .badge--* modifiers, and
   the canonical focus-ring contract. Append-only; nothing above this
   block changed. */
:root {
    /* Cross-pattern accent vocabulary — one set of {bg,ink,line} per
       status that feeds .flash-*, .badge--*, .ds-card--*, and the
       legacy .card-error/.card-highlight/.card-ai re-skins. Info +
       warn alias the pre-existing tokens above; success + danger are
       net-new. Per system.md: "One status vocabulary, five surfaces."
       Re-tinting any status is a one-token edit. */
    --ds-accent-info-bg:    var(--ds-info-bg);
    --ds-accent-info-ink:   var(--ds-info-ink);
    --ds-accent-info-line:  var(--ds-info-line);

    --ds-accent-warn-bg:    var(--ds-warn-bg);
    --ds-accent-warn-ink:   var(--ds-warn-ink);
    --ds-accent-warn-line:  var(--ds-warn-line);

    --ds-accent-success-bg:    #dcfce7;
    --ds-accent-success-ink:   #166534;
    --ds-accent-success-line:  #16a34a;

    --ds-accent-danger-bg:    #fee2e2;
    --ds-accent-danger-ink:   #991b1b;
    --ds-accent-danger-line:  #dc2626;

    /* Read-only sharing state — "Shared with you", where the caller can
       SEE who has access but cannot change it (they can't re-share
       something that isn't theirs). Deliberately its own hue rather than
       a tint of --ds-primary: primary marks the sharing badges that ARE
       controls, and a badge wearing the action colour while doing
       nothing on click is the worse failure. Violet is unrelated to
       every primary the themes ship (green by default, sky blue under
       blue/paper) and stays clear of the neutral "Private" chip. */
    --ds-readonly-bg:   #f4eefe;
    --ds-readonly-ink:  #6b21a8;
    --ds-readonly-line: #a855f7;

    /* Canonical focus-ring — one outline + offset reused on every
       interactive element (button, link, tab, table row, input). Per
       system.md: "Focus ring is non-negotiable. No outline: none
       carve-outs." */
    --ds-focus-outline:        2px solid var(--ds-primary);
    --ds-focus-outline-offset: 2px;

    /* Extended text hierarchy used by .ds-card and form-control rules. */
    --ds-text-disabled: #d1d5db;
    --ds-text-inverse:  #ffffff;
    --ds-text-link:     var(--ds-primary);
}

/* ─── Categorical "kind" vocabulary + assistant accent ─────────────
   Shared across all themes (append-only). Introduced by the paper
   redesign but declared globally so any theme can consume them:

   - --ds-kind-*: categorical colors for entity kinds (data package,
     plugin, memory, library, recipe). Drawn from a decorative sticker
     palette, deepened where needed to clear 4.5:1 text contrast on
     their -soft tints. NEVER use the brand primary for category tags —
     categories must not be mistakable for the one brand action color.
   - --ds-assistant-*: the assistant Agnes's identity accent (sky blue) — the
     ONE accent for "Agnes said / suggests this / is showing you around"
     surfaces (the guided tour, "Ask Agnes" affordances, the "Ask Agnes"
     card, assistant voice cards, the "Agnes is using…" pill).
     Deliberately distinct from the green brand primary and from
     --ds-agnes so the assistant voice reads as its own accent.
   - --ds-agnes-*: the platform/brand green accent retained for chat
     surfaces that are the user's own (e.g. the user's message bubble)
     and legacy assistant-voice callouts not yet migrated to --ds-assistant.
     Never reused for structural UI.
   - --ds-motion-* / --ds-ease-*: shared motion vocabulary so page and
     panel transitions feel identical everywhere. Honor
     prefers-reduced-motion at the consumer site.
   - --ds-radius-btn: the ONE radius every labelled button wears —
     primary CTA, secondary, ghost, on a detail header or in a
     toolbar. Matched to the toolbar control radius (search field,
     filter/sort buttons) so a primary action standing next to an
     input is the same shape as the input.
   - --ds-radius-pill: fully-round radius for BADGES — category tags,
     status chips, counters, avatars, dots, and circular icon-only
     buttons. Never on a labelled button (that is --ds-radius-btn),
     never on inputs. */
:root {
    --ds-kind-data: #185a57;
    --ds-kind-data-soft: #e1f3f1;
    --ds-kind-plugin: #391c57;
    --ds-kind-plugin-soft: #f2e9fb;
    --ds-kind-memory: #523410;
    --ds-kind-memory-soft: #f3e7dc;
    --ds-kind-library: #0a5aa8;
    --ds-kind-library-soft: #e9eff6;
    /* `file` is a kind name the resource vocabulary introduced (paper
       gives it amber). Aliased to `library` here so a `kind='file'`
       caller resolves to something on every OTHER theme — which is the
       pre-existing behaviour: a lone file used to borrow the colour of
       the collection holding it. */
    --ds-kind-file: var(--ds-kind-library);
    --ds-kind-file-soft: var(--ds-kind-library-soft);
    --ds-kind-recipe: #9c1264;
    --ds-kind-recipe-soft: #fbe6f1;
    /* Marketplace entity kinds — skill (green) / agent (violet). Same
       vocabulary as data/plugin/etc.; deepened to clear 4.5:1 on their
       -soft tints. Replaces the per-page hex that marketplace_item_detail
       previously inlined so skill/agent heroes resolve through tokens. */
    --ds-kind-skill: #0e7c57;
    --ds-kind-skill-soft: #e6f6f0;
    --ds-kind-agent: #6d28d9;
    --ds-kind-agent-soft: #f0e9fb;

    --ds-agnes: #047857;
    --ds-agnes-soft: #ecfdf5;
    --ds-agnes-line: #a7f3d0;

    /* Assistant identity — sky blue. Solid value (sky-600) doubles as button
       background (white text, AA) and emphasis text on the -soft tint,
       mirroring the --ds-agnes emerald-700/50/200 structure. */
    --ds-assistant: #0284c7;
    --ds-assistant-dark: #0369a1;
    --ds-assistant-soft: #e0f2fe;
    --ds-assistant-line: #bae6fd;

    --ds-motion-fast: .16s;
    --ds-motion-med: .24s;
    --ds-motion-slow: .32s;
    --ds-ease-standard: cubic-bezier(.2, .7, .2, 1);
    --ds-ease-enter: cubic-bezier(.22, .9, .22, 1);

    --ds-radius-btn: 9px;
    --ds-radius-pill: 9999px;
}

/* ─── Resource colour system ───────────────────────────────────────
   ONE semantic accent per resource type, for the whole product — the
   Library table and grid, detail pages, icons, type badges, section
   glyphs, search results, related lists, activity timelines, the Stack,
   empty states, builders, hover/selected states, context menus. A reader
   should recognise "this is a Skill" from the colour before reading the
   badge.

   Three roles per resource, and no fourth:
     -ink   the accent itself — glyphs, badge text, active indicators,
            left borders, small decorative marks. Every value clears
            4.5:1 on --ds-surface AND on its own -soft tint, so it is
            safe as text, not just as a fill.
     -soft  the tint — icon containers, badge fills, subtle gradients,
            highlights. Only ever backs -ink (or the resource glyph).
     -line  the hairline — 1px rims on tinted containers, separators
            that need to carry the resource identity. Decorative: it is
            never the only thing distinguishing two states.

   Hard rule, and the reason the family stops at three roles: a resource
   colour is NEVER a large filled background. No hero slabs, no
   full-width bands, no filled buttons. It is an accent, so a category
   can never be mistaken for the one brand action colour — the same rule
   the --ds-kind-* vocabulary above was introduced for.

   Declared globally (append-only, consumed by nothing yet at :root) so
   any theme can pick the family up; the paper theme remaps its
   --ds-kind-* aliases onto these values, which is what carries the
   palette to every existing consumer without touching their markup. */
:root {
    /* Data — deep teal. Already the --ds-kind-data hue: data is the
       oldest kind in the product and the one users have learned. */
    --ds-resource-data-ink:  #0f5f5c;
    --ds-resource-data-soft: #e2f2f0;
    --ds-resource-data-line: #a9d8d3;

    /* Skill — violet. */
    --ds-resource-skill-ink:  #6d28d9;
    --ds-resource-skill-soft: #f1eafe;
    --ds-resource-skill-line: #cfb8f8;

    /* Plugin — azure blue. The one hue in this family that shares a
       family with a brand primary (paper's sky #0284c7), so it is
       deliberately pulled DEEPER and cooler than any --ds-primary the
       themes ship. What ultimately keeps the two apart is the hard rule
       above: an azure fill is never a button, so azure never appears
       where the reader is deciding what to click. */
    --ds-resource-plugin-ink:  #1857b8;
    --ds-resource-plugin-soft: #e7eefc;
    --ds-resource-plugin-line: #b6cbf4;

    /* File / Upload — amber. Deepened well past the warn vocabulary's
       ink so a file's accent never reads as a warning about the file. */
    --ds-resource-file-ink:  #92590a;
    --ds-resource-file-soft: #fdf1dc;
    --ds-resource-file-line: #efd09b;

    /* Collection — coral. A collection is a container of files, so it
       sits one hue-step from the file amber: related at a glance,
       distinguishable side by side in the same list. */
    --ds-resource-collection-ink:  #b83b32;
    --ds-resource-collection-soft: #fdece9;
    --ds-resource-collection-line: #f5c2ba;

    /* Agent — indigo. */
    --ds-resource-agent-ink:  #4338ca;
    --ds-resource-agent-soft: #eaeafb;
    --ds-resource-agent-line: #c1c1f1;

    /* Memory — rose. */
    --ds-resource-memory-ink:  #b0246a;
    --ds-resource-memory-soft: #fce8f0;
    --ds-resource-memory-line: #f3bdd3;

    /* Recipe — plum. Not one of the seven named resource types, but a
       real kind in the product, so it needs a slot here rather than
       being the one thing still reading a legacy token. Kept on the
       purple side of the memory rose: the two are the closest pair in
       the family and never appear in the same list. */
    --ds-resource-recipe-ink:  #86216f;
    --ds-resource-recipe-soft: #fae8f5;
    --ds-resource-recipe-line: #e6b9dc;
}

/* Dark mode — the tints cannot survive as near-white fills (see the
   light-only-tint guard in tests/test_design_system_contract.py), so both
   halves of each pair flip: the ink lightens to clear AA on the dark
   surface, and the tint becomes a translucent wash of that lightened ink
   over whatever surface it lands on. Declaring -ink first lets -soft and
   -line derive from it, so a re-tint stays a one-value edit per resource. */
:root[data-theme="dark"] {
    --ds-resource-data-ink:  #5ccdc2;
    --ds-resource-data-soft: color-mix(in srgb, var(--ds-resource-data-ink) 16%, var(--ds-surface));
    --ds-resource-data-line: color-mix(in srgb, var(--ds-resource-data-ink) 38%, var(--ds-surface));

    --ds-resource-skill-ink:  #b794f6;
    --ds-resource-skill-soft: color-mix(in srgb, var(--ds-resource-skill-ink) 16%, var(--ds-surface));
    --ds-resource-skill-line: color-mix(in srgb, var(--ds-resource-skill-ink) 38%, var(--ds-surface));

    --ds-resource-plugin-ink:  #7fb0f4;
    --ds-resource-plugin-soft: color-mix(in srgb, var(--ds-resource-plugin-ink) 16%, var(--ds-surface));
    --ds-resource-plugin-line: color-mix(in srgb, var(--ds-resource-plugin-ink) 38%, var(--ds-surface));

    --ds-resource-file-ink:  #e0b055;
    --ds-resource-file-soft: color-mix(in srgb, var(--ds-resource-file-ink) 16%, var(--ds-surface));
    --ds-resource-file-line: color-mix(in srgb, var(--ds-resource-file-ink) 38%, var(--ds-surface));

    --ds-resource-collection-ink:  #f0897d;
    --ds-resource-collection-soft: color-mix(in srgb, var(--ds-resource-collection-ink) 16%, var(--ds-surface));
    --ds-resource-collection-line: color-mix(in srgb, var(--ds-resource-collection-ink) 38%, var(--ds-surface));

    --ds-resource-agent-ink:  #9b93f5;
    --ds-resource-agent-soft: color-mix(in srgb, var(--ds-resource-agent-ink) 16%, var(--ds-surface));
    --ds-resource-agent-line: color-mix(in srgb, var(--ds-resource-agent-ink) 38%, var(--ds-surface));

    --ds-resource-memory-ink:  #f191b8;
    --ds-resource-memory-soft: color-mix(in srgb, var(--ds-resource-memory-ink) 16%, var(--ds-surface));
    --ds-resource-memory-line: color-mix(in srgb, var(--ds-resource-memory-ink) 38%, var(--ds-surface));

    --ds-resource-recipe-ink:  #dfa0d0;
    --ds-resource-recipe-soft: color-mix(in srgb, var(--ds-resource-recipe-ink) 16%, var(--ds-surface));
    --ds-resource-recipe-line: color-mix(in srgb, var(--ds-resource-recipe-ink) 38%, var(--ds-surface));
}

/* ─── Theme: paper ─────────────────────────────────────────────────
   Activated by `<html data-theme="paper">`. The prototype-derived
   look (issue #896): warm paper canvas, white panels, one confident
   emerald accent, Inter-first type with tight negative tracking on
   headlines, pill CTAs, hairline slate borders, calm shadows.

   Like the dark theme below, this overrides BOTH token families —
   the `--ds-*` set and the legacy `--primary`/`--background` family
   in style-custom.css — so legacy pages and DS pages flip together.
   Instances that don't opt in (default `blue`) are untouched; the
   whole look is one `AGNES_INSTANCE_THEME=paper` switch.

   Contrast notes (WCAG AA on #ffffff / #f3f6fa):
     --ds-text-primary  #0f172a → 15.5:1 ✓
     --ds-text-secondary #475569 → 7.4:1 ✓
     --ds-text-muted    #64748b → 4.8:1 ✓
     --ds-primary-dark  #059669 → 3.2:1 (large text / fills only;
                                  body-copy accents use --ds-agnes) */
:root[data-theme="paper"] {
    /* Brand — sky blue. Sky is the app's primary color under paper;
       hover darkens (see .btn skin in paper-skin.css), soft tint + hairline
       for selected states. Kept in lockstep with --ds-assistant so the whole app
       and the assistant read as one sky-blue identity. */
    --ds-primary: #0284c7;
    --ds-primary-dark: #0369a1;
    --ds-primary-light: #e0f2fe;
    --ds-brand-accent: #7dd3fc;
    /* NB: --ds-agnes stays emerald (defined globally) — it's the Agnes
       *platform* green kept for the "connect to Agnes" banners + AI
       Connector page. Assistant/chat surfaces use --ds-assistant (sky) explicitly. */

    /* Resource colours — the --ds-kind-* aliases are re-pointed at the
       --ds-resource-* family declared above. Every existing consumer
       (catalog + library cards, the library table, detail heroes, the
       activity centre, file previews, skills/agents/workspace pages,
       admin surfaces) reads --ds-kind-*, so ONE remapping here carries
       the resource palette to all of them with zero markup churn — and
       leaves the default blue instance on its original hues, which is
       what keeps this redesign opt-in.

       Only the aliases move; nothing consumes --ds-resource-* directly
       except the detail-page sheet, whose own rules are paper-scoped too.

       `library` is the COLLECTION resource (the scaffold's kind name for
       it predates the resource vocabulary), and `file` is net-new here:
       a lone file used to borrow the collection's colour, which made a
       file and the folder holding it indistinguishable in a list. */
    --ds-kind-data: var(--ds-resource-data-ink);
    --ds-kind-data-soft: var(--ds-resource-data-soft);
    --ds-kind-skill: var(--ds-resource-skill-ink);
    --ds-kind-skill-soft: var(--ds-resource-skill-soft);
    --ds-kind-plugin: var(--ds-resource-plugin-ink);
    --ds-kind-plugin-soft: var(--ds-resource-plugin-soft);
    --ds-kind-file: var(--ds-resource-file-ink);
    --ds-kind-file-soft: var(--ds-resource-file-soft);
    --ds-kind-library: var(--ds-resource-collection-ink);
    --ds-kind-library-soft: var(--ds-resource-collection-soft);
    --ds-kind-agent: var(--ds-resource-agent-ink);
    --ds-kind-agent-soft: var(--ds-resource-agent-soft);
    --ds-kind-memory: var(--ds-resource-memory-ink);
    --ds-kind-memory-soft: var(--ds-resource-memory-soft);
    --ds-kind-recipe: var(--ds-resource-recipe-ink);
    --ds-kind-recipe-soft: var(--ds-resource-recipe-soft);

    /* Surfaces — page canvas is a cool paper grey; panels are white.
       The dim variant is the inset/wash surface (table headers,
       segmented controls, code chips). */
    --ds-bg: #f3f6fa;
    --ds-surface: #ffffff;
    --ds-surface-dim: #f5f7fb;
    --ds-surface-sunken: #eaeef2;
    --ds-border: #e2e8f0;
    --ds-border-light: #edf2f8;

    /* Text — slate ink hierarchy. */
    --ds-text-primary: #0f172a;
    --ds-text-secondary: #475569;
    --ds-text-muted: #64748b;
    --ds-text-disabled: #cbd5e1;

    /* Hero — the `--ds-hero-*` family stays DARK under paper: /home's
       install hero and /dashboard's setup CTA embed terminal mockups
       and dozens of white-ink rules, and the prototype language keeps
       exactly one dark "night" moment + dark terminal chrome anyway.
       Paper re-tints it from navy to the warm near-black of the
       terminal chrome. Content-page heroes (.page-header--hero,
       .stack-hero) get their LIGHT paper-card treatment explicitly in
       paper-skin.css instead of through these tokens. */
    --ds-hero-bg: #1f1e1c;
    --ds-hero-bg-deep: #141312;
    --ds-hero-ink: #f4f3f1;
    --ds-hero-shadow: rgba(0, 0, 0, 0.18);
    --ds-hero-eyebrow: #7dd3fc;
    --ds-hero-cta-bg: #0ea5e9;
    --ds-hero-cta-fg: #ffffff;
    --ds-hero-cta-bg-hover: #0284c7;
    --ds-hero-cta-fg-hover: #ffffff;

    /* Code/terminal chrome — warm near-black, deliberately NOT a
       brand color, so instructional code blocks stay quiet. */
    --ds-code-bg: #1c1b1a;
    --ds-code-ink: #e8e6e3;
    --ds-code-yellow: #ffd866;

    /* Status vocabularies — teal-leaning success, amber warn,
       red danger; info keeps the cool indigo family. */
    --ds-info-bg: #eef3ff;
    --ds-info-ink: #1c3994;
    --ds-info-line: #4f7cf2;
    --ds-warn-bg: #fff7e8;
    --ds-warn-ink: #a16207;
    --ds-warn-line: #f6dfb4;
    --ds-accent-warn-bg: #fff7e8;
    --ds-accent-warn-ink: #a16207;
    --ds-accent-warn-line: #f6dfb4;
    --ds-accent-success-bg: #e6f6f4;
    --ds-accent-success-ink: #0f766e;
    --ds-accent-success-line: #b7e3de;
    --ds-accent-danger-bg: #feecec;
    --ds-accent-danger-ink: #dc2626;
    --ds-accent-danger-line: #fca5a5;

    /* Shadows — calm, cool-tinted; cards lift on hover instead of
       resting heavy. */
    --ds-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.05);
    --ds-shadow-md: 0 8px 20px rgba(0, 0, 0, 0.06);
    --ds-shadow-lg: 0 12px 34px rgba(37, 99, 235, 0.08);

    /* Typography — Inter-first. Falls back to the system stack when
       Inter isn't installed; operators can serve it via the theme
       `font_url` override. */
    --ds-font: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    /* Legacy compat shims — flip the style-custom.css family so the
       header, footer, and not-yet-migrated pages re-skin together
       (same pattern as the dark theme). */
    --primary: #0284c7;
    --primary-dark: #0369a1;
    --primary-light: rgba(2, 132, 199, 0.1);
    --brand-accent: #7dd3fc;
    --hero-bg: #ffffff;
    --hero-ink: #111827;
    --background: var(--ds-bg);
    --surface: var(--ds-surface);
    --surface-dim: var(--ds-surface-dim);
    --border: var(--ds-border);
    --border-light: var(--ds-border-light);
    --text-primary: var(--ds-text-primary);
    --text-secondary: var(--ds-text-secondary);
    --text-muted: var(--ds-text-muted);
    --text-disabled: var(--ds-text-disabled);
    --font-primary: var(--ds-font);
    --info-bg: var(--ds-info-bg);
    --info-ink: var(--ds-info-ink);
    --info-line: var(--ds-info-line);
    --warn-bg: var(--ds-warn-bg);
    --warn-ink: var(--ds-warn-ink);
    --warn-line: var(--ds-warn-line);
    --shadow-sm: var(--ds-shadow-sm);
    --shadow-md: var(--ds-shadow-md);
    --shadow-card: 0 1px 3px 0 rgba(15, 23, 42, 0.05), 0 1px 2px -1px rgba(15, 23, 42, 0.04);
    --shadow-elevated: var(--ds-shadow-lg);
}

/* ─── Theme: dark + blue variant ──────────────────────────────────
   Activated by `<html data-theme="dark" data-theme-variant="blue">`.
   Stamped by _theme_resolve.html when the user's light-mode brand is
   "blue" and they switch to dark.  Overrides only the brand tokens so
   the blue palette persists in dark mode instead of falling back to
   the default green.

   Colour selection rationale (WCAG AA contrast on --ds-surface #141a30):
     --ds-primary      #4f9deb  → 6.1:1  ✓ (AA ≥ 4.5:1)
     --ds-primary-dark #3a87d4  → 4.8:1  ✓ (AA ≥ 4.5:1)
     --ds-brand-accent #7ab8f2  → 8.1:1  ✓ (lighter, used for hero)
   Light tint is a translucent fill, not body text, so 3:1 is sufficient.
   Hero tokens mirror the light-blue theme's white-on-blue convention. */
:root[data-theme="dark"][data-theme-variant="blue"] {
    --ds-primary:       #4f9deb;
    --ds-primary-dark:  #3a87d4;
    --ds-primary-light: rgba(79, 157, 235, 0.18);
    --ds-brand-accent:  #7ab8f2;

    /* Hero surface — stays blue even in dark mode. */
    --ds-hero-bg:      #0a2a5e;
    --ds-hero-bg-deep: #061a45;

    /* Hero eyebrow + CTA: translucent-white convention from the blue
       light theme — mint-on-blue has poor contrast. */
    --ds-hero-shadow:     rgba(0, 80, 180, 0.35);
    --ds-hero-eyebrow:    rgba(255, 255, 255, 0.92);
    --ds-hero-cta-bg:     #ffffff;
    --ds-hero-cta-fg:     #0a2a5e;
    --ds-hero-cta-bg-hover: rgba(255, 255, 255, 0.88);
    --ds-hero-cta-fg-hover: #0a2a5e;

    /* Info callout vocabulary re-tinted to brand-blue family (same
       reasoning as the light blue theme). */
    --ds-info-bg:         rgba(79, 157, 235, 0.18);
    --ds-info-line:       #4f9deb;
    --ds-info-ink:        #a8c8f5;
    --ds-accent-info-bg:  rgba(79, 157, 235, 0.18);
    --ds-accent-info-line: #4f9deb;
    --ds-accent-info-ink:  #a8c8f5;
}

/* ─── Theme: dark ──────────────────────────────────────────────────
   Activated by ``<html data-theme="dark">``. Overrides the surface,
   text, border, and accent tokens so every consumer of ``--ds-*``
   flips wholesale. The brand-primary green stays the same hue but
   shifts lighter for AA contrast on dark fills. Page markup and
   component classes do NOT change between themes.

   Status accent backgrounds use a translucent tint of the line
   colour instead of a tinted-pastel light surface — pastel
   backgrounds (success-bg=#dcfce7 etc.) wash out the body text on
   dark surfaces, while a 14% rgba over the dark page bg reads
   correctly as "muted info / warn / success / danger" without
   competing with the body.

   Also overrides the legacy ``--background`` / ``--surface`` family
   in style-custom.css so the app header, footer, and any page still
   reading the legacy tokens flip together. The two families are
   the same surface — splitting them across themes would tear the
   chrome.

   Known gap: dark mode is the system.md "future brief" — only the
   surfaces audited by the chat page are guaranteed AA-clean.
   Other pages may need touch-ups when their templates next change. */
:root[data-theme="dark"] {
    /* Flip native controls (inputs, selects, textareas, scrollbars) to the
       dark UA palette so browser-default form fields aren't white-on-dark.
       Higher specificity than `:root`; `auto` + OS-dark resolves here too. */
    color-scheme: dark;

    /* Brand surface — same hue, lighter for AA contrast on dark fills */
    --ds-primary: #4ec096;
    --ds-primary-dark: #2ea877;
    --ds-primary-light: rgba(78, 192, 150, 0.16);
    --ds-brand-accent: #76d6ad;

    /* Light surface family flips to a navy-tinted dark stack so the
       page reads as a single tonal family with the existing hero. */
    --ds-bg: #0c1224;
    --ds-surface: #141a30;
    --ds-surface-dim: #1c2440;
    /* Sunken reads a touch lighter than the dark canvas so grouping trays
       stay visible (the light-theme "darker than bg" inverts on dark). */
    --ds-surface-sunken: #1a2038;
    --ds-border: #283255;
    --ds-border-light: #1f2845;

    /* Text — pale-ink hierarchy on dark surfaces. */
    --ds-text-primary: #f3f6ff;
    --ds-text-secondary: #b9c1d8;
    --ds-text-muted: #7d86a3;
    --ds-text-disabled: #4a5168;
    --ds-text-inverse: #0e1525;

    /* Status backgrounds: translucent tint of the line colour over
       the page bg. Inks shift lighter so they read on the tint. */
    --ds-accent-info-bg:    rgba(79, 124, 242, 0.18);
    --ds-accent-info-ink:   #a8c1ff;
    --ds-accent-info-line:  #4f7cf2;

    --ds-accent-warn-bg:    rgba(245, 200, 75, 0.18);
    --ds-accent-warn-ink:   #ffd970;
    --ds-accent-warn-line:  #f5c84b;

    --ds-accent-success-bg: rgba(22, 163, 74, 0.20);
    --ds-accent-success-ink: #86e1a3;
    --ds-accent-success-line: #16a34a;

    --ds-accent-danger-bg:  rgba(220, 38, 38, 0.22);
    --ds-accent-danger-ink: #ff9b9b;
    --ds-accent-danger-line: #dc2626;

    /* Read-only sharing — same translucent-tint treatment as the status
       accents above; the light violet pastel would wash out on dark. */
    --ds-readonly-bg:   rgba(168, 85, 247, 0.20);
    --ds-readonly-ink:  #d8b4fe;
    --ds-readonly-line: #a855f7;

    /* Legacy compat shims — these live in style-custom.css and are
       referenced by the app header, footer, and pages that haven't
       moved onto ``--ds-*`` yet. Override them here so the chrome
       flips alongside the design-token surfaces. */
    --background: var(--ds-bg);
    --surface: var(--ds-surface);
    --surface-dim: var(--ds-surface-dim);
    --border: var(--ds-border);
    --border-light: var(--ds-border-light);
    --text-primary: var(--ds-text-primary);
    --text-secondary: var(--ds-text-secondary);
    --text-muted: var(--ds-text-muted);
    --text-disabled: var(--ds-text-disabled);
    --info-bg: var(--ds-accent-info-bg);
    --info-ink: var(--ds-accent-info-ink);
    --info-line: var(--ds-accent-info-line);
    --warn-bg: var(--ds-accent-warn-bg);
    --warn-ink: var(--ds-accent-warn-ink);
    --warn-line: var(--ds-accent-warn-line);

    /* Shadows are mostly invisible on dark surfaces — give them more
       weight so the depth perception still registers. */
    --ds-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);
    --ds-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
    --ds-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.55);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35), 0 1px 3px rgba(0, 0, 0, 0.25);
    --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
    --shadow-card: 0 1px 3px rgba(0, 0, 0, 0.45);
    --shadow-elevated: 0 8px 24px rgba(0, 0, 0, 0.55);

    /* Focus-ring colour stays the brand primary — same green dot on
       dark surfaces reads as "interactive" identically to light. */

    /* Old --ds-info-* / --ds-warn-* vocab → the dark accent tints; the
       light pastel bgs (#eef3ff etc.) wash out body text on dark. */
    --ds-info-bg: var(--ds-accent-info-bg);
    --ds-info-ink: var(--ds-accent-info-ink);
    --ds-info-line: var(--ds-accent-info-line);
    --ds-warn-bg: var(--ds-accent-warn-bg);
    --ds-warn-ink: var(--ds-accent-warn-ink);
    --ds-warn-line: var(--ds-accent-warn-line);
}
