/**
 * ClosingVista design tokens
 * ---------------------------------------------------------------------------
 * Generated by design-lead · 2026-07-07 · pairs with:
 *   docs/designpowers/design/2026-07-07-visual-system.md   (rationale, contrast tables)
 *   docs/designpowers/design/2026-07-07-screen-specs.md    (layout application)
 *
 * Layer order in this file:
 *   1. Primitives   — raw color ramps, type/space/radius/shadow/motion scales.
 *                     Never reference these directly in component code.
 *   2. Semantic     — role-based tokens (--color-bg-canvas, --color-text-primary,
 *                     etc.) that components actually consume. Light values live
 *                     at :root / [data-theme="light"]; dark overrides live in
 *                     [data-theme="dark"].
 *   3. Reduced motion — universal safety net. Do not remove; motion-designer
 *                     layers richer choreography on top of this, never instead
 *                     of it (design principle: reduced-motion-first).
 *
 * Theming contract: the app shell (SPA, dark-first) sets
 *   <html data-theme="dark">   on mount, always — regardless of OS preference,
 *   per taste profile ("portals may ship dark-only this build").
 * Public/marketing pages (light-first) omit the attribute (light is the
 *   :root default) or set data-theme="light" explicitly. The
 *   prefers-color-scheme block below lets a public page opt into automatic
 *   dark mode later just by deleting its explicit data-theme="light" — no
 *   token changes required.
 *
 * All contrast ratios below are computed against the paired background named
 * in the comment (WCAG 2.1 relative-luminance formula). AA text minimum is
 * 4.5:1 (3:1 for ≥24px/19px-bold); AA non-text/UI-component minimum is 3:1.
 * ---------------------------------------------------------------------------
 */

/* =============================================================================
   1. PRIMITIVES
   ========================================================================== */

:root {
  /* --- Light neutrals (near-white → near-black) --------------------------- */
  --gray-0:   #FFFFFF; /* canvas */
  --gray-25:  #FBFBFC; /* surface-1 */
  --gray-50:  #F5F5F7; /* surface-2 */
  --gray-100: #EDEDF0; /* surface-3 */
  --gray-150: #E4E5E9; /* decorative hairline on white — 1.26:1, non-informational only */
  --gray-300: #B8B9C0; /* decorative / disabled fill */
  --gray-400: #9A9CA5; /* decorative icon, non-text */
  --gray-450: #8C8E97; /* interactive border on white — 3.27:1 vs #FFFFFF (AA non-text) */
  --gray-500: #6B6D76; /* placeholder / tertiary text on white — 5.15:1 */
  --gray-600: #53555D; /* secondary text on white — 7.43:1 */
  --gray-900: #17181C; /* primary text on white — 17.74:1 */

  /* --- Dark neutrals (soft-black canvas → near-white text) ----------------- */
  --ink-950: #0A0A0C; /* deepest, rarely used (e.g. scrims) */
  --ink-900: #121316; /* canvas */
  --ink-850: #1A1B1F; /* surface-1 */
  --ink-800: #212227; /* surface-2 */
  --ink-750: #292A30; /* surface-3 (modal/popover top layer) — NON-INTERACTIVE
    CHROME ONLY past this point (FIX-P2-7 / a11y latent-risk minor, DD-17,
    independently recomputed, matches accessibility-reviewer's figures to 4
    decimal places): --claret-400 (dark button fill) on this surface computes
    to 2.9987:1 — under the 3:1 AA non-text floor (it passes on ink-800/850/
    900: 3.33/3.61/3.89:1, so the fill itself is fine everywhere else).
    --color-border-interactive (ink-600) computes to 2.54:1 here — also
    under 3:1, and it *also* fails on ink-800 (2.81:1); it only clears 3:1 on
    ink-850 (3.05:1, its actually-validated pairing) and ink-900 (3.29:1).
    Nothing shipped renders a button or bordered input directly on ink-750
    today (verified live) — keep it that way, or bump the relevant token
    value first if a real component ever needs to. */
  --ink-700: #33343A; /* decorative hairline on dark, non-informational only */
  --ink-600: #65676F; /* interactive border on surface-1 — 3.05:1 vs #1A1B1F (AA non-text) */
  --ink-500: #83858F; /* secondary icon / inactive tab on surface-1 — 4.68:1 */
  --ink-400: #A8AAB3; /* secondary text on canvas — 8.02:1 / on surface-1 — 7.43:1 */
  --ink-100: #EDEDEF; /* primary text on canvas — 15.89:1 */

  /* --- Claret — the one accent family -------------------------------------
     A deep wine/garnet. Chosen precisely to sit outside every disqualified
     hue family: not Zillow's saturated azure blue, not a SaaS indigo/teal
     (the family most "Rela-like" competitors reach for), not "AI startup"
     purple, not the retired brass/gold. Reads as a poured glass of wine at a
     private viewing — expensive, warm-cool neutral, restrained. See
     visual-system.md §2 for the full rejection rationale. */
  --claret-50:  #FBEFF1;
  --claret-100: #F5D9DF;
  --claret-200: #E9B3C0;
  --claret-300: #DC7593; /* dark-theme accent text/link/focus — 6.20:1 vs ink-900 */
  --claret-400: #C1486A; /* dark-theme button fill — 4.77:1 white text / 3.89:1 vs ink-900.
    Also clears 3:1 on ink-850 (3.61:1) and ink-800 (3.33:1). Vs ink-750
    (surface-3) it drops to 2.9987:1, under the 3:1 non-text floor — see the
    ink-750 comment above. Safe on ink-900/ink-850/ink-800; never ink-750. */
  --claret-500: #A83A5C; /* mid — illustrative/decorative use only */
  --claret-600: #8C2843; /* light-theme button fill/text/link/focus — 8.40:1 vs white */
  --claret-700: #6E1F35; /* light-theme visited-link / pressed — 10.99:1 vs white */
  --claret-800: #521726; /* pressed-state darken (light theme) */
  --claret-900: #38101A; /* near-black wine, rare (tint-bg base for dark theme) */

  /* --- Warm paper (marketing section bands; the smallest-touch tint) ---------
     A warm off-white, not a cool gray-white and not the retired identity's
     ivory: it is a bounded, sparingly-used SURFACE tint (a section band or a
     card), never the page's own base color the way the old ivory field was.
     No metallic/gold pairing — claret still does all accent work.
     2026-07-13 visual-elevation amendment §1.1. */
  --paper-50:  #F7F4EE;
  --paper-100: #EFEAE0;

  /* --- Sand/cream (Cornerstone template + Photographers pricing column) ------
     Warmer and more saturated than paper, deliberately still gray-leaning
     (not a pale creamy yellow) to stay clear of the retired ivory identity. */
  --sand-50:  #F5EFE4;
  --sand-100: #E8DFCB;

  /* --- Stone/sage-muted (Atelier template + Brokerages pricing column) -------
     A barely-there desaturated gray-green — closer to "stone" than "sage" at
     the -50/-100 tiers; --stone-700 (text tier) is muted enough to read as a
     quiet neutral, not a brand-green accent (nowhere near the retired forest). */
  --stone-50:  #F1F2ED;
  --stone-100: #E4E7DE;
  --stone-700: #565B4F; /* text-scale only — kickers/captions on light bg */

  /* --- Claret-500 is now sanctioned for decorative text/washes (2026-07-13
     amendment supersedes the 2026-07-08 "functional + kickers only" budget).
     No new hex — --claret-500 (#A83A5C) already exists, labeled "illustrative/
     decorative use only." See docs/designpowers/design/2026-07-13-visual-elevation.md
     §1.3/§2.2 for verified pairings. */

  /* --- Semantic hues (status), light + dark tuned, verified per theme ------ */
  --success-600: #1B7A4A; /* light text/icon on white — 5.34:1 */
  --success-tint-bg-light: #EAF6EF; /* success-600 on this tint — 4.82:1 */
  --success-400: #5FBE8A; /* dark text/icon on ink-900 — 8.16:1 */
  --success-tint-bg-dark: #173226; /* success-400 on this tint — 6.06:1 */

  --warning-700: #8A5A00; /* light text/icon on white — 5.93:1 */
  --warning-tint-bg-light: #FDF3E0; /* warning-700 on this tint — 5.38:1 */
  --warning-400: #E3A73F; /* dark text/icon on ink-900 — 8.73:1 */
  --warning-tint-bg-dark: #332405; /* warning-400 on this tint — 7.07:1 */

  --error-600: #B42318; /* light text/icon on white — 6.57:1 */
  --error-tint-bg-light: #FDECEA; /* error-600 on this tint — 5.75:1 */
  --error-400: #F17A6D; /* dark text/icon on ink-900 — 6.85:1 */
  --error-tint-bg-dark: #3A1613; /* error-400 on this tint — 5.94:1 */

  --info-600: #3457B2; /* light text/icon on white — 6.66:1 (used for "running/in-progress" — deliberately distinct from brand accent) */
  --info-tint-bg-light: #EAF0FC; /* info-600 on this tint — 5.83:1 */
  --info-300: #8FB4FF; /* dark text/icon on ink-900 — 8.97:1 */
  --info-tint-bg-dark: #132038; /* info-300 on this tint — 7.85:1 */

  /* --- Type families (OFL 1.1, self-hostable, variable fonts) --------------
     Two families, no third. Fraunces for editorial display (public surfaces
     only); Archivo for everything else (all UI, all data, both themes,
     both portals). Tabular numerals ship via Archivo's `tnum` feature. */
  --font-display: "Fraunces", ui-serif, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", Georgia, serif;
  --font-sans: "Archivo", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* --- Type scale (size / line-height, rem @ 16px root) -------------------- */
  --fs-display-2xl: 4rem;      --lh-display-2xl: 1.05; /* 64px — marketing hero H1, desktop */
  --fs-display-xl:  3rem;      --lh-display-xl:  1.08; /* 48px — hero H1 mobile / section H1 */
  --fs-display-lg:  2.25rem;   --lh-display-lg:  1.12; /* 36px — property headline, unlock headline */
  --fs-display-md:  1.75rem;   --lh-display-md:  1.2;  /* 28px — card/section headline */
  --fs-heading-lg:  1.5rem;    --lh-heading-lg:  1.25; /* 24px — panel title */
  --fs-heading-md:  1.25rem;   --lh-heading-md:  1.3;  /* 20px — subsection title */
  --fs-heading-sm:  1.0625rem; --lh-heading-sm:  1.35; /* 17px — card title, table section header */
  --fs-body-lg:     1.0625rem; --lh-body-lg:     1.5;  /* 17px — buyer-facing reading text (Priya) */
  --fs-body-md:     0.9375rem; --lh-body-md:     1.5;  /* 15px — default UI text, workspace density */
  --fs-body-sm:     0.8125rem; --lh-body-sm:     1.45; /* 13px — secondary/meta text */
  --fs-label:       0.8125rem; --lh-label:       1.2;  /* 13px — form labels, table headers, chip text */
  --fs-data-lg:     1.5rem;    --lh-data-lg:     1.2;  /* 24px — stat tile figures, invoice totals */
  --fs-data-md:     0.9375rem; --lh-data-md:     1.4;  /* 15px — table-row amounts */
  --fs-caption:     0.75rem;   --lh-caption:     1.4;  /* 12px — timestamps, photo captions */

  --tracking-tight:  -0.01em; /* display sizes ≥28px */
  --tracking-normal: 0;
  --tracking-wide:   0.04em; /* --fs-label, uppercase usage only */

  --fw-regular:  400;
  --fw-medium:   500;
  --fw-semibold: 600;
  --fw-bold:     700;

  /* --- Spacing (4px base) --------------------------------------------------- */
  --space-1:  0.25rem;  /* 4px */
  --space-2:  0.5rem;   /* 8px */
  --space-3:  0.75rem;  /* 12px */
  --space-4:  1rem;     /* 16px */
  --space-5:  1.25rem;  /* 20px */
  --space-6:  1.5rem;   /* 24px */
  --space-7:  2rem;     /* 32px */
  --space-8:  2.5rem;   /* 40px */
  --space-9:  3rem;     /* 48px */
  --space-10: 4rem;     /* 64px */
  --space-11: 5rem;     /* 80px */
  --space-12: 6rem;     /* 96px */
  --space-13: 8rem;     /* 128px — flagship editorial section air (marketing hero / term sheet, ≥1280px) */

  /* --- Radius (small vocabulary, consistent by component class) ------------ */
  --radius-sm:   4px;  /* chips, badges, small controls, checkboxes */
  --radius-md:   8px;  /* buttons, inputs, standard cards */
  --radius-lg:   12px; /* panels, modals, photo containers, large cards */
  --radius-full: 999px; /* pills, avatars, circular icon buttons */

  /* --- Borders --------------------------------------------------------------- */
  --border-thin:  1px;
  --border-thick: 2px; /* focus rings, selected-state emphasis */

  /* --- Shadows (light theme: two-layer, tight + ambient) --------------------
     Dark theme does NOT use these for surface elevation — it steps through
     the ink-900→ink-750 surface ramp instead (glow-free, "workroom not
     nightclub"). Only floating overlays that must separate from any surface
     (modal, popover, toast) get a dark-theme shadow — see --shadow-elevation-4-dark. */
  --shadow-elevation-1: 0 1px 2px rgba(23, 24, 28, 0.06), 0 1px 1px rgba(23, 24, 28, 0.04);
  --shadow-elevation-2: 0 4px 8px rgba(23, 24, 28, 0.08), 0 2px 4px rgba(23, 24, 28, 0.06);
  --shadow-elevation-3: 0 8px 16px rgba(23, 24, 28, 0.10), 0 2px 6px rgba(23, 24, 28, 0.06);
  --shadow-elevation-4: 0 16px 32px rgba(23, 24, 28, 0.14), 0 4px 12px rgba(23, 24, 28, 0.08);
  --shadow-elevation-4-dark: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06) inset;

  /* --- Motion (baseline tokens; motion-designer choreographs on top) -------- */
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --duration-slow: 320ms;
  --ease-standard: cubic-bezier(0.2, 0, 0, 1); /* decelerate, physical, no bounce */
  --ease-in:  cubic-bezier(0.4, 0, 1, 1);
  --ease-out: cubic-bezier(0, 0, 0.2, 1);

  /* --- Breakpoints & containers (reference values — see note below) -------- */
  --bp-mobile:  375px;
  --bp-tablet:  600px;
  --bp-desktop: 1024px;
  --bp-wide:    1440px;
  --container-marketing: 1200px;
  --container-app:       1440px;
  --container-reading:   640px; /* ~68-character measure for property descriptions */
  /* NOTE: custom properties cannot be read inside @media (width) conditions in
     any shipping browser today. These exist as the single documented source of
     truth for the pixel values — hardcode the literal px in media queries and
     keep them in sync with this file. See visual-system.md §5. */
}

/* =============================================================================
   2. SEMANTIC TOKENS — LIGHT (default; also explicit [data-theme="light"])
   ========================================================================== */

:root,
[data-theme="light"] {
  color-scheme: light;

  /* Surfaces */
  --color-bg-canvas:    var(--gray-0);
  --color-bg-surface-1: var(--gray-25);
  --color-bg-surface-2: var(--gray-50);
  --color-bg-surface-3: var(--gray-100);
  --color-border-hairline: var(--gray-150);   /* decorative dividers only */
  --color-border-interactive: var(--gray-450); /* inputs, outlined buttons — 3.27:1 */

  /* Text */
  --color-text-primary:   var(--gray-900); /* 17.74:1 */
  --color-text-secondary: var(--gray-600); /* 7.43:1 */
  --color-text-tertiary:  var(--gray-500); /* 5.15:1 — placeholder, captions */
  --color-text-disabled:  var(--gray-300); /* exempt from AA per WCAG disabled-control carve-out */
  --color-text-on-accent: var(--gray-0);
  --color-text-inverse:   var(--ink-100);  /* text on any dark-surface chip embedded in a light page */

  /* Brand accent */
  --color-accent:          var(--claret-600); /* 8.40:1 on canvas */
  --color-accent-hover:    var(--claret-700);
  --color-accent-active:   var(--claret-800);
  --color-accent-tint-bg:  var(--claret-50);
  --color-accent-visited:  var(--claret-700); /* 10.99:1 */
  --color-focus-ring:      var(--claret-600);

  /* Semantic status */
  --color-success-text: var(--success-600);
  --color-success-tint: var(--success-tint-bg-light);
  --color-warning-text: var(--warning-700);
  --color-warning-tint: var(--warning-tint-bg-light);
  --color-error-text:   var(--error-600);
  --color-error-tint:   var(--error-tint-bg-light);
  --color-info-text:    var(--info-600);
  --color-info-tint:    var(--info-tint-bg-light);

  /* Elevation */
  --shadow-card:   var(--shadow-elevation-1);
  --shadow-raised: var(--shadow-elevation-2);
  --shadow-popover: var(--shadow-elevation-3);
  --shadow-modal:  var(--shadow-elevation-4);
}

/* =============================================================================
   2b. SEMANTIC TOKENS — DARK
   ========================================================================== */

[data-theme="dark"] {
  color-scheme: dark;

  /* Surfaces — elevation via lightness steps, not shadow */
  --color-bg-canvas:    var(--ink-900);
  --color-bg-surface-1: var(--ink-850);
  --color-bg-surface-2: var(--ink-800);
  --color-bg-surface-3: var(--ink-750);
  --color-border-hairline: var(--ink-700);   /* decorative dividers only */
  --color-border-interactive: var(--ink-600); /* inputs, outlined buttons — 3.05:1 vs
    surface-1 (ink-850), the pairing this token is actually validated against.
    Vs ink-800 it's 2.81:1 and vs ink-750 it's 2.54:1 — both under 3:1 (FIX-P2-7
    / DD-17). Keep interactive borders on ink-900/ink-850; treat ink-800/
    ink-750 as non-interactive-chrome-only surfaces for bordered controls. */

  /* Text */
  --color-text-primary:   var(--ink-100); /* 15.89:1 */
  --color-text-secondary: var(--ink-400); /* 8.02:1 / 7.43:1 */
  --color-text-tertiary:  var(--ink-500); /* 4.68:1 */
  --color-text-disabled:  var(--ink-700);
  --color-text-on-accent: var(--gray-0);
  --color-text-inverse:   var(--gray-900);

  /* Brand accent — one step brighter than light theme; "glows gently, never neon" */
  --color-accent:          var(--claret-300); /* 6.20:1 — text/links/focus */
  --color-accent-hover:    var(--claret-200);
  --color-accent-active:   var(--claret-400);
  --color-accent-tint-bg:  #33131C; /* claret-300 on this — 5.60:1 */
  --color-accent-visited:  var(--claret-300);
  --color-focus-ring:      var(--claret-300);

  /* Button fills need more body than link-weight accent text, so buttons use
     claret-400 explicitly (see components: Button) rather than --color-accent. */
  --color-accent-button-fill: var(--claret-400); /* 4.77:1 white text / 3.89:1 vs canvas */

  /* Semantic status */
  --color-success-text: var(--success-400);
  --color-success-tint: var(--success-tint-bg-dark);
  --color-warning-text: var(--warning-400);
  --color-warning-tint: var(--warning-tint-bg-dark);
  --color-error-text:   var(--error-400);
  --color-error-tint:   var(--error-tint-bg-dark);
  --color-info-text:    var(--info-300);
  --color-info-tint:    var(--info-tint-bg-dark);

  /* Elevation — no ambient shadows on the 1–3 scale; only floating overlays
     get a shadow, and it's tuned for a dark surround (see primitive above). */
  --shadow-card:    none;
  --shadow-raised:  none;
  --shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.45);
  --shadow-modal:   var(--shadow-elevation-4-dark);
}

/* =============================================================================
   2c. Automatic dark mode for public pages that opt in (prefers-color-scheme)
   Portals set data-theme="dark" explicitly and are unaffected by this block.
   A public page opts in simply by NOT setting data-theme="light" itself.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  /* :not([data-theme="obsidian"]) — the obsidian theme (2d) is explicit like
     light/dark; without the exclusion this higher-specificity selector
     (0,3,0 vs 2d's 0,2,0) would repaint obsidian pages ink+claret on any
     dark-OS device. */
  :root:not([data-theme="light"]):not([data-theme="dark"]):not([data-theme="obsidian"]) {
    color-scheme: dark;
    --color-bg-canvas:    var(--ink-900);
    --color-bg-surface-1: var(--ink-850);
    --color-bg-surface-2: var(--ink-800);
    --color-bg-surface-3: var(--ink-750);
    --color-border-hairline: var(--ink-700);
    --color-border-interactive: var(--ink-600);
    --color-text-primary:   var(--ink-100);
    --color-text-secondary: var(--ink-400);
    --color-text-tertiary:  var(--ink-500);
    --color-text-disabled:  var(--ink-700);
    --color-text-on-accent: var(--gray-0);
    --color-text-inverse:   var(--gray-900);
    --color-accent:          var(--claret-300);
    --color-accent-hover:    var(--claret-200);
    --color-accent-active:   var(--claret-400);
    --color-accent-tint-bg:  #33131C;
    --color-accent-visited:  var(--claret-300);
    --color-focus-ring:      var(--claret-300);
    --color-accent-button-fill: var(--claret-400);
    --color-success-text: var(--success-400);
    --color-success-tint: var(--success-tint-bg-dark);
    --color-warning-text: var(--warning-400);
    --color-warning-tint: var(--warning-tint-bg-dark);
    --color-error-text:   var(--error-400);
    --color-error-tint:   var(--error-tint-bg-dark);
    --color-info-text:    var(--info-300);
    --color-info-tint:    var(--info-tint-bg-dark);
    --shadow-card: none;
    --shadow-raised: none;
    --shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.45);
    --shadow-modal: var(--shadow-elevation-4-dark);
  }
}

/* =============================================================================
   2d. SEMANTIC TOKENS — OBSIDIAN (2026-07-16 marketing rebrand)
   The public marketing surface's dark theme: true near-black zinc scale with a
   single violet accent, per the owner's DESIGN.md ("Obsidian — High-Contrast
   Dark") and the art-direction spec. Additive: light (2), dark (2b — the SPA's
   ink scale), and auto-dark (2c) are untouched. Pages opt in via
   publicShell({ theme: "obsidian" }). All ratios computed vs #09090b.
   ========================================================================== */

:root[data-theme="obsidian"] {
  color-scheme: dark;

  /* Obsidian primitives (scoped here — consumed only under this theme) */
  --obs-bg:                 #09090b; /* canvas */
  --obs-surface-lowest:     #0c0c0f; /* recessed bands, footer */
  --obs-surface-1:          #18181b; /* cards, opaque placards */
  --obs-surface-2:          #212124; /* hover/active shift */
  --obs-surface-3:          #27272a; /* highest elevation */
  --obs-border-hairline:    #27272a; /* decorative dividers only — 1.3:1, exempt */
  --obs-border-interactive: #71717a; /* inputs/outlined buttons — 4.1:1, clears 3:1 */
  --obs-text-primary:       #fafafa; /* 19.1:1 */
  --obs-text-secondary:     #a1a1aa; /* 7.76:1 — darkest allowed body-text gray */
  --obs-text-tertiary:      #71717a; /* 4.1:1 — large/bold/decorative only */
  --obs-violet-300:         #c4b5fd; /* gradient light end, hover */
  --obs-violet-400:         #a78bfa; /* the accent — 7.3:1 as text on canvas */
  --obs-violet-600:         #7c3aed; /* deep container end of the gradient scale */
  --obs-success:            #34d399; /* 10.3:1 */
  --obs-error:              #ef4444; /* 5.3:1 */

  /* Surfaces */
  --color-bg-canvas:    var(--obs-bg);
  --color-bg-surface-1: var(--obs-surface-1);
  --color-bg-surface-2: var(--obs-surface-2);
  --color-bg-surface-3: var(--obs-surface-3);
  --color-border-hairline: var(--obs-border-hairline);
  --color-border-interactive: var(--obs-border-interactive);

  /* Text */
  --color-text-primary:   var(--obs-text-primary);
  --color-text-secondary: var(--obs-text-secondary);
  --color-text-tertiary:  var(--obs-text-tertiary);
  --color-text-disabled:  #52525b;
  /* Near-black on the violet button fill (7.3:1). White-on-violet is 2.7:1
     and FAILS — never revert this to a light value. */
  --color-text-on-accent: var(--obs-bg);
  --color-text-inverse:   var(--gray-900);

  /* Accent — violet, function only (links, focus, CTAs, the "us" column) */
  --color-accent:          var(--obs-violet-400);
  --color-accent-hover:    var(--obs-violet-300);
  --color-accent-active:   var(--obs-violet-400);
  --color-accent-tint-bg:  rgba(167, 139, 250, 0.10);
  --color-accent-visited:  var(--obs-violet-300);
  --color-focus-ring:      var(--obs-violet-400);
  --color-accent-button-fill: var(--obs-violet-400);

  /* Semantic status */
  --color-success-text: var(--obs-success);
  --color-success-tint: rgba(52, 211, 153, 0.10);
  --color-warning-text: var(--warning-400);
  --color-warning-tint: var(--warning-tint-bg-dark);
  --color-error-text:   var(--obs-error);
  --color-error-tint:   rgba(239, 68, 68, 0.10);
  --color-info-text:    var(--obs-violet-300);
  --color-info-tint:    rgba(167, 139, 250, 0.08);

  /* Elevation — borders over shadows (DESIGN.md); overlays keep a real shadow */
  --shadow-card:    none;
  --shadow-raised:  none;
  --shadow-popover: 0 8px 24px rgba(0, 0, 0, 0.6);
  --shadow-modal:   var(--shadow-elevation-4-dark);

  /* Typography — all-Geist (self-hosted OFL, public/fonts/geist/). The serif
     display face is a light-theme voice; obsidian headings are Geist too.
     GUARD: marketing.css sets font-family: var(--font-display) on every
     heading — without this override they'd silently render Fraunces. */
  --font-sans: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-display: var(--font-sans);

  /* Support-widget aliases — support-widget.css consumes these names (with
     light-hex fallbacks); defining them here keeps the launcher/panel legible
     on the dark marketing pages. */
  --color-surface-1: var(--obs-surface-1);
  --color-text:      var(--obs-text-primary);
  --color-border:    var(--obs-surface-3);
}

/* =============================================================================
   3. BASELINE RESETS THAT ARE PART OF THE TOKEN CONTRACT
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  font-size: 100%; /* 16px root — all rem values above stay zoom-correct at 200% */
}

body {
  background: var(--color-bg-canvas);
  color: var(--color-text-primary);
  font-family: var(--font-sans);
  font-size: var(--fs-body-md);
  line-height: var(--lh-body-md);
  font-feature-settings: "tnum" 1, "lnum" 1; /* tabular + lining figures wherever numerals appear */
}

/* Visible focus everywhere, both themes — never suppressed, never color-only. */
:focus-visible {
  outline: var(--border-thick) solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Reduced motion — universal safety net. Motion-designer builds richer
   choreography ON TOP of this; nothing overrides it back to "reduce". */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
