/* Design tokens — the only file allowed to carry raw color, duration, or
   z-index literals. Everything else consumes vars so a rebrand is one edit
   of --accent (rebrand.mjs writes it) and dark mode is a token swap.

   Frame direction (design/vidsoon-premium): warm paper canvas, graphite ink,
   a single vermilion accent used sparingly, local Manrope/Geist faces. */

/* Reviewed local faces. Served from explicit /fonts/* Worker routes
   (registerSiteRoutes) so CSP font-src 'self' stays airtight — no external
   font CDN. Absolute paths survive the /assets-<hash>/ fingerprint copy. */
@font-face {
  font-family: Manrope;
  src: url("/fonts/manrope-700.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Geist;
  src: url("/fonts/geist-400.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: Geist;
  src: url("/fonts/geist-600.ttf") format("truetype");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Accent — single source. Derived roles come from color-mix so changing
     one value re-brands every component. Frame uses vermilion sparingly:
     primary buttons are graphite ink, not accent. */
  --accent: oklch(51% 0.175 36);
  --accent-strong: color-mix(in oklch, var(--accent) 78%, oklch(22% 0.008 65));
  --accent-soft: oklch(94% 0.035 50);
  --accent-ring: color-mix(in oklch, var(--accent) 32%, transparent);
  --on-accent: oklch(99% 0.004 80);

  /* Surfaces — warm paper page, lifted card, recessed well. */
  --surface-page: oklch(97.5% 0.009 80);
  --surface-raised: oklch(99.5% 0.003 80);
  --surface-sunken: oklch(93.5% 0.012 80);
  --surface-overlay: oklch(99.5% 0.003 80);
  --surface-inverse: oklch(22% 0.008 65);

  /* Always-dark band (price band, media windows). Independent of theme —
     these stay dark in dark mode too, unlike --surface-inverse. */
  --band-bg: oklch(22% 0.008 65);
  --band-inset: oklch(29% 0.009 65);
  --on-band: oklch(97.5% 0.009 80);
  --on-band-muted: oklch(77% 0.012 80);
  --band-rule: oklch(44% 0.01 65);

  /* Ink — AA-checked roles on --surface-page/--surface-raised. */
  --ink-strong: oklch(22% 0.008 65);
  --ink-body: oklch(37% 0.012 65);
  --ink-muted: oklch(48% 0.012 65);
  --ink-faint: oklch(62% 0.012 70);
  --on-inverse: oklch(97.5% 0.009 80);

  /* Hairline rules; the stronger one is reserved for field borders. */
  --rule: oklch(85% 0.015 80);
  --rule-strong: oklch(64% 0.015 80);

  /* Semantic roles (text + soft surface + rule for alerts/badges). */
  --success: oklch(39% 0.085 158);
  --success-soft: oklch(94% 0.025 158);
  --success-rule: oklch(84% 0.06 158);
  --warning: oklch(43% 0.085 70);
  --warning-soft: oklch(94% 0.045 85);
  --warning-rule: oklch(84% 0.07 85);
  --danger: oklch(45% 0.17 27);
  --danger-strong: color-mix(in oklch, var(--danger) 82%, oklch(22% 0.008 65));
  --danger-soft: oklch(95% 0.025 27);
  --danger-rule: oklch(86% 0.05 27);
  --info: var(--accent);
  --info-soft: var(--accent-soft);
  --info-rule: var(--accent-ring);

  /* Type — Frame pairs Manrope (display) with Geist (UI). 500-weight
     requests resolve to the Geist 600 face. */
  --font-display: "Manrope", "Geist", system-ui, sans-serif;
  --font-ui:
    "Geist", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans",
    sans-serif;
  --font-mono:
    ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-md: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.375rem;
  --text-2xl: 1.75rem;
  --text-3xl: 2.25rem;
  --text-display: clamp(2.75rem, 4.65vw, 4.5rem);
  --text-title: clamp(2rem, 3.2vw, 3.25rem);

  --leading-tight: 1.06;
  --leading-heading: 1.2;
  --leading-body: 1.55;

  --tracking-tight: -0.02em;
  --tracking-heading: -0.035em;
  --tracking-display: -0.055em;
  --tracking-caps: 0.06em;

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

  /* Spacing — 4px base scale. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  /* Radii. */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 20px;
  --radius-pill: 999px;

  /* Elevation — Frame is a flat, ruled surface; shadows stay rare and warm. */
  --shadow-1: 0 1px 2px rgb(36 34 31 / 0.05), 0 1px 3px rgb(36 34 31 / 0.04);
  --shadow-2: 0 4px 12px rgb(36 34 31 / 0.07), 0 1px 3px rgb(36 34 31 / 0.05);
  --shadow-3: 0 16px 40px rgb(36 34 31 / 0.14), 0 4px 12px rgb(36 34 31 / 0.06);
  --ring-focus: 0 0 0 3px var(--accent-ring);

  /* Scrim behind dialogs; scroll-edge fade mask for tab strips. */
  --scrim: oklch(16% 0.01 65 / 0.6);
  --scroll-fade-mask: linear-gradient(
    to right,
    transparent 0,
    #000 var(--mask-left, 0px),
    #000 calc(100% - var(--mask-right, 0px)),
    transparent 100%
  );

  /* Motion — four durations, three easings. Reduced motion removes all. */
  --dur-instant: 0.01ms;
  --dur-stagger: 40ms;
  --dur-1: 120ms;
  --dur-2: 220ms;
  --dur-3: 340ms;
  --dur-4: 520ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Layers. */
  --z-header: 50;
  --z-menu: 60;
  --z-dialog: 80;
  --z-toast: 90;
  --z-skip: 100;

  /* Layout. */
  --container: 80rem;
  --container-narrow: 46rem;
  --header-height: 4.75rem;
  --page-gutter: clamp(1.25rem, 4vw, 4rem);
  --target: 2.75rem;
}

/* Dark theme: token overrides only. Components never branch on theme —
   if a component needs a dark rule, the tokens above are wrong. The warm
   Frame neutrals carry over; the accent lightens to stay legible and the
   always-dark band tokens intentionally keep their values. */
@media (prefers-color-scheme: dark) {
  :root {
    --accent: oklch(63% 0.16 36);
    --accent-strong: color-mix(in oklch, var(--accent) 88%, oklch(97.5% 0.009 80));
    --accent-soft: oklch(28% 0.045 45);
    --accent-ring: color-mix(in oklch, var(--accent) 40%, transparent);
    --on-accent: oklch(19% 0.008 65);

    --surface-page: oklch(19% 0.008 65);
    --surface-raised: oklch(24% 0.01 68);
    --surface-sunken: oklch(16% 0.008 65);
    --surface-overlay: oklch(28% 0.012 68);
    --surface-inverse: oklch(96% 0.008 80);

    --ink-strong: oklch(96% 0.008 80);
    --ink-body: oklch(86% 0.012 72);
    --ink-muted: oklch(72% 0.014 72);
    --ink-faint: oklch(55% 0.015 70);
    --on-inverse: oklch(19% 0.008 65);

    --rule: oklch(34% 0.014 68);
    --rule-strong: oklch(48% 0.016 70);

    --success: oklch(72% 0.11 158);
    --success-soft: oklch(27% 0.03 158);
    --success-rule: oklch(40% 0.05 158);
    --warning: oklch(72% 0.1 75);
    --warning-soft: oklch(28% 0.035 75);
    --warning-rule: oklch(42% 0.05 75);
    --danger: oklch(68% 0.16 27);
    --danger-strong: color-mix(in oklch, var(--danger) 88%, oklch(97% 0.008 80));
    --danger-soft: oklch(27% 0.05 27);
    --danger-rule: oklch(42% 0.06 27);

    --scrim: rgb(0 0 0 / 0.6);

    --shadow-1: 0 1px 2px rgb(0 0 0 / 0.4);
    --shadow-2: 0 4px 12px rgb(0 0 0 / 0.45);
    --shadow-3: 0 16px 40px rgb(0 0 0 / 0.55);
  }
}
