/* ================================================================== */
/*  1. DESIGN TOKENS                                                    */
/*  :root holds the DARK theme (default). [data-theme="light"]         */
/*  overrides every color token. The active theme is set on <html>.    */
/*  Components must reference variables only — never raw hex.          */
/*  Ported from design-language.html §1–4, with four values corrected  */
/*  for WCAG AA — each marked `AA:` with its measured ratio. Mono       */
/*  labels, captions and accent text are all small text here, so 4.5:1 */
/*  is the bar and the original tokens sat at 2.75–3.95.               */
/* ================================================================== */
:root {
  color-scheme: dark;

  /* — Surfaces (darkest → lightest) — */
  --canvas: #0a0b0d;        /* page background, recessed inputs */
  --surface: #131419;       /* cards, panels, header */
  --surface-2: #1b1c22;     /* code blocks, image wells, insets */

  /* — Lines / borders — */
  --line: rgba(255, 255, 255, 0.08);          /* default hairline */
  --line-strong: rgba(255, 255, 255, 0.16);   /* dividers, ghost buttons, hover */

  /* — Ink (text) — */
  --ink: #f4f4f5;           /* headings, primary text, button labels */
  --ink-muted: #9b9da6;     /* body copy, descriptions */
  --ink-faint: #84858c;     /* captions, mono labels, disabled — AA: 4.62 on --surface-2 (was #61636c, 2.84) */

  /* — Accent (the one spark) — */
  --accent: #ff5d2e;        /* CTAs, links, sparks, the card square */
  --accent-soft: #ff8b66;   /* primary-button hover (lighter in dark) */

  /* — Atmosphere — */
  --grid-line: rgba(255, 255, 255, 0.035);
  --grain-opacity: 0.35;
  --grain-blend: overlay;

  /* — Misc surfaces — */
  --skeleton: rgba(255, 255, 255, 0.055);
  --scrollbar-thumb: #2c2d34;
  --scrollbar-thumb-hover: #3c3d45;

  /* — Type families — */
  --font-display: "Bricolage Grotesque", "Geist", ui-sans-serif, sans-serif;
  --font-sans: "Geist", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, monospace;

  /* — Motion (non-themed; constant across modes) — */
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1); /* the house easing */
  --dur-fast: 0.2s;     /* hovers, color/border transitions */
  --dur-mid: 0.3s;      /* arrow nudges, theme cross-fade */
  --dur-reveal: 0.8s;   /* scroll-in reveal */

  /* — Radii (non-themed) — */
  --r-sm: 6px;     /* nav chips, logo tile, icon buttons (square) */
  --r-md: 8px;     /* inputs, small wells */
  --r-lg: 12px;    /* compact cards, code blocks */
  --r-xl: 16px;    /* panels, large cards, dialog */
  --r-pill: 999px; /* buttons, pills, tags, round icon buttons */
}

[data-theme="light"] {
  color-scheme: light;
  --canvas: #f4f3ef;        /* warm cream, not white */
  --surface: #ffffff;
  --surface-2: #eceae3;
  --line: rgba(20, 21, 24, 0.1);
  --line-strong: rgba(20, 21, 24, 0.2);
  --ink: #16171a;
  --ink-muted: #565860;
  --ink-faint: #67686e;     /* AA: 4.61 on --surface-2 (was #8b8d95, 2.75) */
  /* Accent doubles as small text (eyebrow index, meta keys, table keys) *and* as the
     primary button's background under cream text, so it has to clear 4.5:1 against
     white, cream and --surface-2 alike. #e8460f only reached 3.56. */
  --accent: #c03a0c;        /* AA: 4.53 on --surface-2, 5.45 on white */
  --accent-soft: #a33109;   /* darker on hover in light mode */
  --grid-line: rgba(20, 21, 24, 0.055);
  --grain-opacity: 0.22;
  --grain-blend: multiply;
  --skeleton: rgba(20, 21, 24, 0.06);
  --scrollbar-thumb: #cdccc4;
  --scrollbar-thumb-hover: #b6b4aa;
}

/* ================================================================== */
/*  2. BASE                                                            */
/* ================================================================== */
* { box-sizing: border-box; border-color: var(--line); }
html { scroll-behavior: smooth; background-color: var(--canvas); overflow-x: clip; }
body {
  margin: 0; background: transparent; color: var(--ink);
  font-family: var(--font-sans); -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility; line-height: 1.6;
}
::selection { background: var(--accent); color: var(--canvas); }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-track { background: var(--canvas); }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 999px; border: 2px solid var(--canvas); }
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-thumb-hover); }

/* ================================================================== */
/*  3. ATMOSPHERE — fixed decorative layers                            */
/* ================================================================== */
.bg-grid {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 74px 74px;
  -webkit-mask-image: radial-gradient(ellipse 78% 56% at 50% -6%, #000 8%, transparent 80%);
  mask-image: radial-gradient(ellipse 78% 56% at 50% -6%, #000 8%, transparent 80%);
}
.bg-grain {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  opacity: var(--grain-opacity); mix-blend-mode: var(--grain-blend);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

/* ================================================================== */
/*  4. MOTION primitives                                              */
/* ================================================================== */
@keyframes fade-rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } }
.rise { opacity: 0; animation: fade-rise 0.9s var(--ease-out-expo) both; }
@keyframes skeleton-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }
.skeleton { background-color: var(--skeleton); animation: skeleton-pulse 2.6s ease-in-out infinite; border-radius: var(--r-md); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rise { animation: none; opacity: 1; }
  .skeleton { animation: none; }
}

/* Observer-driven reveal: hold the animation until .in is added by js/reveal.js.
   Gated on .js-reveal so the page is never blank if JS fails or is disabled. */
.js-reveal .rise:not(.in) { animation-play-state: paused; }
