/* ═══════════════════════════════════════════════════════════════════════════
 * COMPONENT PRIMITIVES — DO NOT OVERWRITE
 *
 * Base styles, animations, layout utilities, and component classes.
 * Theme tokens live in tokens.css (set by the blog-brand skill).
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
 * DEFENSIVE ALIASES
 * Safety net — resolved by tokens.css if it defines the canonical names.
 * These ensure components work regardless of which naming convention
 * tokens.css uses (template placeholders vs styleguide-derived output).
 * ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Color aliases (component names → canonical names) */
  --color-text: var(--color-foreground);
  --color-text-secondary: var(--color-muted-foreground);
  --color-surface-elevated: color-mix(in oklch, var(--color-surface, oklch(0.97 0 0)), white 5%);
  --color-accent: var(--color-primary);
  --color-accent-foreground: var(--color-primary-foreground);
  --color-warning: var(--color-cta);
  --color-primary-light: color-mix(in oklch, var(--color-primary) 60%, white);
  --color-primary-dark: color-mix(in oklch, var(--color-primary) 80%, black);

  /* Static tokens (theme-independent) */
  --shadow-xl: 0 20px 25px -5px oklch(0.2 0 0 / 0.1), 0 8px 10px -6px oklch(0.2 0 0 / 0.05);
  --duration-slower: 1s;
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * BASE STYLES
 * ═══════════════════════════════════════════════════════════════════════════ */

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.7;
  color: var(--color-text);
  background: var(--color-background);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

::selection {
  background: var(--color-primary);
  color: white;
}

:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ANIMATION KEYFRAMES
 * ═══════════════════════════════════════════════════════════════════════════ */

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideInLeft {
  from { opacity: 0; transform: translateX(-40px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes slideInRight {
  from { opacity: 0; transform: translateX(40px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes scaleIn {
  from { opacity: 0; transform: scale(0.9); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

@keyframes successRing {
  from { opacity: 0.6; transform: scale(0.8); }
  to { opacity: 0; transform: scale(1.6); }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ANIMATION UTILITIES
 * Use these classes on elements for entrance animations
 * ═══════════════════════════════════════════════════════════════════════════ */

.fade-up {
  opacity: 0;
  transform: translateY(30px);
  animation: fadeUp var(--duration-slow) var(--ease-out) forwards;
}

.fade-in {
  opacity: 0;
  animation: fadeIn var(--duration-slow) var(--ease-out) forwards;
}

.slide-in-left {
  opacity: 0;
  transform: translateX(-40px);
  animation: slideInLeft var(--duration-slow) var(--ease-out) forwards;
}

.slide-in-right {
  opacity: 0;
  transform: translateX(40px);
  animation: slideInRight var(--duration-slow) var(--ease-out) forwards;
}

.scale-in {
  opacity: 0;
  transform: scale(0.9);
  animation: scaleIn var(--duration-slow) var(--ease-spring) forwards;
}

.pulse {
  animation: pulse 2s ease-in-out infinite;
}

.success-ring {
  animation: successRing 0.8s var(--ease-out) forwards;
}

/* Animation Delays */
.delay-100 { animation-delay: 0.1s; }
.delay-200 { animation-delay: 0.2s; }
.delay-300 { animation-delay: 0.3s; }
.delay-400 { animation-delay: 0.4s; }
.delay-500 { animation-delay: 0.5s; }
.delay-600 { animation-delay: 0.6s; }

/* Hover Effects */
.hover-lift {
  transition: transform var(--duration-normal) var(--ease-out),
              box-shadow var(--duration-normal) var(--ease-out);
}
.hover-lift:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-xl);
}

.hover-scale {
  transition: transform var(--duration-normal) var(--ease-spring);
}
.hover-scale:hover {
  transform: scale(1.02);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * LAYOUT UTILITIES
 * ═══════════════════════════════════════════════════════════════════════════ */

.container {
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 1.5rem;
}

@media (min-width: 768px) {
  .container { padding: 0 2rem; }
}

@media (min-width: 1024px) {
  .container { padding: 0 4rem; }
}

.section {
  padding: 5rem 0;
}

.section-sm {
  padding: 3rem 0;
}

@media (min-width: 768px) {
  .section { padding: 8rem 0; }
  .section-sm { padding: 4rem 0; }
}

.section-accent {
  background: var(--color-accent-bg);
  color: var(--color-accent-text);
}

.section-accent h1,
.section-accent h2,
.section-accent h3,
.section-accent h4 {
  color: var(--color-accent-text);
}

.section-overlay {
  color: white;
}

.section-overlay h1,
.section-overlay h2,
.section-overlay h3,
.section-overlay h4 {
  color: white;
}

.section-alt {
  background: var(--color-surface);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * COMPONENT BASES
 * Minimal styles for common elements - extend as needed
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 1rem 2rem;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: var(--radius-md);
  border: none;
  cursor: pointer;
  transition: all var(--duration-normal) var(--ease-out);
}

.btn-primary {
  background: var(--color-cta);
  color: var(--color-cta-foreground);
  box-shadow: var(--shadow-cta-glow);
}

.btn-primary:hover {
  background: var(--color-cta-hover);
  transform: translateY(-2px);
}

.btn-secondary {
  background: transparent;
  color: var(--color-text);
  border: 2px solid var(--color-border);
}

.btn-secondary:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.btn-lg {
  padding: 1.25rem 2.5rem;
  font-size: 1.125rem;
}

.btn-sm {
  padding: 0.625rem 1.25rem;
  font-size: 0.875rem;
}

/* Inputs */
.input {
  width: 100%;
  padding: 1rem 1.25rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--color-text);
  background: var(--color-surface-elevated);
  border: 2px solid var(--color-border);
  border-radius: var(--radius-md);
  transition: all var(--duration-fast) var(--ease-out);
}

.input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 4px color-mix(in oklch, var(--color-primary) 10%, transparent);
}

.input::placeholder {
  color: var(--color-muted-foreground);
}

.input-accent {
  background: var(--color-accent-surface);
  border-color: var(--color-accent-border);
  color: var(--color-accent-text);
}

.input-accent:focus {
  border-color: var(--color-primary);
}

/* Cards */
.card {
  background: var(--color-surface-elevated);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: 2rem;
  transition: all var(--duration-normal) var(--ease-out);
}

.card:hover {
  box-shadow: var(--shadow-lg);
}

.card-accent {
  background: var(--color-accent-surface);
  border-color: var(--color-accent-border);
}

/* Badges */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text-secondary);
  border: 1px solid var(--color-border);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * SPECIAL EFFECTS
 * ═══════════════════════════════════════════════════════════════════════════ */

.gradient-text {
  background: linear-gradient(135deg, var(--color-primary), var(--color-cta));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.noise-texture {
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0.02;
  z-index: 9999;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}

/* ═══════════════════════════════════════════════════════════════════════════
 * RESPONSIVE UTILITIES
 * ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
  .hide-mobile { display: none !important; }
}

@media (min-width: 769px) {
  .hide-desktop { display: none !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ACCESSIBILITY — REDUCED MOTION
 * ═══════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * BLOG DESIGN TOKENS
 *
 * This file is the single source of truth for color, type, space, motion.
 * Edit the values here to retheme the entire blog without touching components.
 *
 * Token names mirror the Context.dev styleguide response the blog-brand skill
 * receives from `extract_styleguide` (called through `mcp__code_mode__execute`):
 *   styleguide.colors.{accent,background,text} → --styleguide-* anchors below
 *   styleguide.typography.headings / .p        → --font-heading / --font-body
 *   styleguide.elementSpacing.{xs…xl}          → --spacing-{xs…xl}
 *   styleguide.shadows.{sm…xl,inner}           → --shadow-{sm…xl,inner}
 *
 * Loaded AFTER base.css (see globals.css), so the names declared here win
 * over base.css's defensive aliases.
 *
 * The blog-brand skill sets these from the company's website.
 * ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* ─────────────────────────────────────────────────────────────────────────
   * STYLEGUIDE ANCHORS — the only place a pasted literal belongs.
   *
   * Paste styleguide.colors.* from extract_styleguide VERBATIM (hex is fine —
   * `oklch(from …)` below converts natively). Every other color token derives
   * from these three, in both light and dark mode.
   *
   * blesso.ai: the extractor returns the duotone stop #1466ff; the site's own
   * tokens.css carries #2f80ff as the UI accent (oklch 0.62 0.2 259) and
   * #0a0a0a / #ffffff as ink and paper. Anchors were verified against the
   * site's own tokens.css, which wins over the extractor when they disagree.
   *
   * If styleguide.mode is "dark", the extracted colors describe a dark UI:
   * paste accent verbatim, and swap the roles — feed background/text into the
   * DARK PALETTE formulas' L values and derive light here instead.
   *
   * No company domain? Pick anchors by hand from the proven palettes in
   * .claude/skills/blog-brand/references/color.md.
   * ───────────────────────────────────────────────────────────────────────── */
  --styleguide-accent: #2F80FF;
  --styleguide-background: #FFFFFF;
  --styleguide-text: #0A0A0A;

  /* Dark-first, like blesso.ai: the default surface is the dark palette. */
  color-scheme: dark;

  /* ─────────────────────────────────────────────────────────────────────────
   * COLOR — blesso.ai is dark-first, so the dark palette is the default
   * surface and light is the override. Both palettes precompute from the
   * three anchors in OKLCH via relative color syntax, so perceptual
   * discipline (chroma caps, L targets) holds no matter what format the
   * anchors were pasted in.
   * ───────────────────────────────────────────────────────────────────────── */
  /* Sentinel light set, transplanted from the site's html.light block:
     #ffffff bg · #0a0a0a fg · #f5f5f5 surface · #ebebeb elevated · #737373
     muted-fg · #e5e5e5 border · accent stays #2f80ff */
  --light-background: var(--styleguide-background);
  --light-background-elevated: oklch(from var(--styleguide-text) calc(l + 0.777) c h);
  --light-surface: oklch(from var(--styleguide-text) calc(l + 0.825) c h);
  --light-text: var(--styleguide-text);
  --light-text-muted: oklch(from var(--styleguide-text) calc(l + 0.411) calc(c * 0.9) h);
  --light-border: oklch(from var(--styleguide-text) calc(l + 0.777) calc(c * 0.3) h);
  --light-border-soft: oklch(from var(--light-text) calc(l + 0.8) c h);
  --light-accent: var(--styleguide-accent);
  --light-accent-strong: oklch(from var(--styleguide-accent) calc(l - 0.07) calc(c * 1.1) h);
  --light-accent-soft: oklch(from var(--styleguide-accent) 0.95 calc(c * 0.2) h);
  --light-focus: oklch(from var(--styleguide-accent) calc(l + 0.06) calc(c * 1.05) h);
  /* Links read on paper in light mode; the accent itself is too light there. */
  --light-link: var(--light-accent-strong);
  /* Blue-tinted accent panels (site: bg 0.95/0.02, surface 0.91/0.03,
     text 0.35/0.08, border 0.85/0.05) */
  --light-accent-bg: oklch(from var(--styleguide-accent) 0.95 calc(c * 0.1) h);
  --light-accent-surface: oklch(from var(--styleguide-accent) 0.91 calc(c * 0.15) h);
  --light-accent-text: oklch(from var(--styleguide-accent) 0.35 calc(c * 0.4) h);
  --light-accent-border: oklch(from var(--styleguide-accent) 0.85 calc(c * 0.25) h);
  /* Ink-on-paper CTA (site: ink 0.145 on paper, hover 0.3) */
  --light-cta-hover: oklch(from var(--light-text) calc(l + 0.155) c h);

  /* Sentinel dark set, transplanted from the site's :root block:
     #0a0a0a bg · #fafafa fg · #171717 surface · #262626 elevated and border ·
     #a3a3a3 muted-fg · accent stays #2f80ff in dark, like the site */
  --dark-background: oklch(from var(--styleguide-background) 0.145 min(c, 0.01) h);
  --dark-background-elevated: oklch(from var(--dark-background) calc(l + 0.124) c h);
  --dark-surface: oklch(from var(--styleguide-background) 0.205 min(c, 0.01) h);
  --dark-text: oklch(from var(--styleguide-text) 0.985 min(c, 0.01) h);
  --dark-text-muted: oklch(from var(--dark-text) calc(l - 0.277) calc(c * 2.4) h);
  --dark-border: oklch(from var(--dark-text) calc(l - 0.716) calc(c * 1.6) h);
  --dark-border-soft: oklch(from var(--dark-text) calc(l - 0.76) c h);
  --dark-accent: var(--styleguide-accent);
  --dark-accent-strong: oklch(from var(--dark-accent) calc(l + 0.06) calc(c * 1.05) h);
  --dark-accent-soft: oklch(from var(--dark-accent) 0.25 calc(c * 0.4) h);
  --dark-focus: var(--dark-accent-strong);
  --dark-link: var(--dark-accent);
  /* Blue-tinted accent panels (site: bg 0.18/0.02, surface 0.22/0.03,
     text 0.93/0.01, border 0.3/0.05) */
  --dark-accent-bg: oklch(from var(--styleguide-accent) 0.18 calc(c * 0.1) h);
  --dark-accent-surface: oklch(from var(--styleguide-accent) 0.22 calc(c * 0.15) h);
  --dark-accent-text: oklch(from var(--styleguide-accent) 0.93 calc(c * 0.05) h);
  --dark-accent-border: oklch(from var(--styleguide-accent) 0.3 calc(c * 0.25) h);
  /* Paper-on-ink CTA (site: paper 0.985 on ink 0.145, hover 0.87) */
  --dark-cta-hover: oklch(from var(--dark-text) calc(l - 0.115) c h);

  /* Default surface — dark first, like the site */
  --color-background: var(--dark-background);
  --color-text: var(--dark-text);
  --color-accent: var(--dark-accent);
  --color-background-elevated: var(--dark-background-elevated);
  --color-surface: var(--dark-surface);
  /* The site's muted surface equals its surface in both modes */
  --color-muted: var(--color-surface);
  --color-text-muted: var(--dark-text-muted);
  --color-border: var(--dark-border);
  --color-border-soft: var(--dark-border-soft);
  --color-accent-strong: var(--dark-accent-strong);
  --color-accent-soft: var(--dark-accent-soft);
  --color-focus: var(--dark-focus);
  --color-link: var(--dark-link);

  /* Semantic (kept for plan/strategy widgets — template-owned, not styleguide) */
  --color-success: oklch(0.72 0.17 155);
  --color-warning: oklch(0.8 0.16 85);
  --color-error: oklch(0.65 0.2 25);

  /* ─────────────────────────────────────────────────────────────────────────
   * TYPOGRAPHY — Source Serif 4 (headings) + Geist (body) + Geist Mono.
   * Maps: styleguide.typography.headings → --font-heading,
   *       styleguide.typography.p → --font-body (family + fontFallbacks).
   * When styleguide.fontLinks names a Google-hosted font, swap the families
   * in index.html's Bunny Fonts URL — never download font files.
   * Fonts load via Bunny Fonts in index.html. No @import here (would block).
   * ───────────────────────────────────────────────────────────────────────── */
  --font-heading: "Source Serif 4", ui-serif, Georgia, "Times New Roman", serif;
  --font-body: "Geist", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "JetBrains Mono", "SF Mono", monospace;

  /* Clamp-driven type scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.375rem;
  --text-2xl: clamp(1.5rem, 1.2rem + 1.2vw, 1.875rem);
  --text-3xl: clamp(1.875rem, 1.4rem + 2.2vw, 2.5rem);
  --text-4xl: clamp(2.25rem, 1.6rem + 3.2vw, 3.5rem);
  --text-display: clamp(2.75rem, 1.8rem + 4.8vw, 5.25rem);

  /* Editorial measures (line lengths) */
  --measure-body: 65ch;
  --measure-wide: 80ch;
  --measure-narrow: 45ch;
  --content-max: 1280px;
  /* Reading shell: holds a 65ch column + gap + TOC rail and is CENTERED, so
   * the article layout doesn't float a fixed grid against the left of the
   * 1280px landing width (which dumps dead space on the right). */
  --measure-reading: 60rem;   /* ~960px — article column when there is no TOC rail */
  --toc-width: 15rem;         /* 240px sticky table-of-contents rail */

  /* ─────────────────────────────────────────────────────────────────────────
   * SPACING — 4pt scale with semantic names.
   * xs–xl map 1:1 to styleguide.elementSpacing (snap extracted values to the
   * 4pt grid); 3xs/2xs and 2xl–4xl are template extensions for editorial
   * rhythm that Context.dev doesn't report.
   * ───────────────────────────────────────────────────────────────────────── */
  --spacing-3xs: 0.125rem;   /*  2px */
  --spacing-2xs: 0.25rem;    /*  4px */
  --spacing-xs: 0.5rem;      /*  8px */
  --spacing-sm: 1rem;        /* 16px */
  --spacing-md: 1.75rem;     /* 28px */
  --spacing-lg: 2.5rem;      /* 40px */
  --spacing-xl: 4rem;        /* 64px */
  --spacing-2xl: 6rem;       /* 96px */
  --spacing-3xl: 9rem;       /* 144px */
  --spacing-4xl: 12rem;      /* 192px */

  /* Responsive section padding */
  --section-pad-y: clamp(var(--spacing-2xl), 5vw, var(--spacing-4xl));
  --section-pad-x: clamp(var(--spacing-md), 4vw, var(--spacing-2xl));

  /* ─────────────────────────────────────────────────────────────────────────
   * RADII — evidence source: styleguide.components.button.*.borderRadius →
   * --radius-md, styleguide.components.card.borderRadius → --radius-lg.
   * ───────────────────────────────────────────────────────────────────────── */
  --radius-sm: 0.125rem;
  --radius-md: 0.25rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.75rem;
  --radius-full: 9999px;

  /* Blesso's signature: chamfer over radius. --cut-button 9px, --cut-card 34px. */
  --cut-button: 9px;
  --cut-card: 34px;

  /* ─────────────────────────────────────────────────────────────────────────
   * MOTION — three named easings, five durations, transform+opacity only
   * ───────────────────────────────────────────────────────────────────────── */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.4, 0, 1, 0.4);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  /* --ease-spring kept for legacy components in base.css; do not use in new motion */
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  --duration-instant: 0.1s;
  --duration-fast: 0.15s;
  --duration-normal: 0.25s;
  --duration-slow: 0.4s;
  --duration-slower: 0.7s;

  /* ─────────────────────────────────────────────────────────────────────────
   * SHADOWS — soft, low-contrast, tinted from the text anchor.
   * sm–xl and inner map 1:1 to styleguide.shadows; when extracted evidence
   * exists, adapt its character (offset/blur/strength) into these tokens.
   * ───────────────────────────────────────────────────────────────────────── */
  --light-shadow-sm: 0 25px 50px -12px oklch(from var(--styleguide-text) 0.1 min(c, 0.01) h / 8%);
  --light-shadow-md: none;
  --light-shadow-lg: 0 12px 32px oklch(from var(--styleguide-text) 0.1 min(c, 0.01) h / 12%);
  --light-shadow-xl: 0 24px 64px oklch(from var(--styleguide-text) 0.1 min(c, 0.01) h / 16%);
  --light-shadow-inner: none;
  --light-shadow-cta-glow: 0 0 24px oklch(from var(--styleguide-text) 0.1 min(c, 0.01) h / 14%);

  /* Dark shadows (the default surface) */
  --dark-shadow-sm: 0 25px 50px -12px oklch(0 0 0 / 0.45);
  --dark-shadow-md: none;
  --dark-shadow-lg: 0 12px 32px oklch(0 0 0 / 0.45);
  --dark-shadow-xl: 0 24px 64px oklch(0 0 0 / 0.55);
  --dark-shadow-inner: none;
  /* Site: the paper CTA glows white in dark mode */
  --dark-shadow-cta-glow: 0 0 24px oklch(from var(--dark-text) l c h / 0.18);

  --shadow-sm: var(--dark-shadow-sm);
  --shadow-md: var(--dark-shadow-md);
  --shadow-lg: var(--dark-shadow-lg);
  --shadow-xl: var(--dark-shadow-xl);
  --shadow-inner: var(--dark-shadow-inner);
  --shadow-cta-glow: var(--dark-shadow-cta-glow);

  /* ─────────────────────────────────────────────────────────────────────────
   * BASE.CSS COMPATIBILITY — styles/base.css is locked and consumes these
   * names. They are pure aliases; never point components at them directly.
   * --color-*-foreground = text sitting ON that background: paper on the
   * accent in both modes, ink on paper and paper on ink for the CTA, exactly
   * like the site's own tokens.
   * ───────────────────────────────────────────────────────────────────────── */
  --color-foreground: var(--color-text);
  --color-primary: var(--color-accent);
  /* Text on the accent: paper in both modes, like the site */
  --color-primary-foreground: var(--dark-text);
  /* The site's nav-link ink; equals its cta-hover in both modes */
  --color-foreground-dim: var(--color-cta-hover);
  --color-cta: var(--color-text);
  --color-cta-hover: var(--dark-cta-hover);
  --color-cta-foreground: var(--color-background);
  --color-muted-foreground: var(--color-text-muted);
  --color-accent-bg: var(--dark-accent-bg);
  --color-accent-text: var(--dark-accent-text);
  --color-accent-surface: var(--dark-accent-surface);
  --color-accent-border: var(--dark-accent-border);

  /* ─────────────────────────────────────────────────────────────────────────
   * TERMINAL — dark code-block palette. Stays dark in both light and dark
   * theme by design. Override per project if you need a light code aesthetic.
   * ───────────────────────────────────────────────────────────────────────── */
  --color-terminal-bg: oklch(0.16 0.01 264);
  --color-terminal-fg: oklch(0.92 0.005 80);
  --color-terminal-rule: oklch(0.22 0.01 264);
  --color-terminal-meta: oklch(0.6 0.005 80);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * LIGHT MODE — explicit choice (set by ThemeToggle / FOUC script).
 * The blog is dark-first like blesso.ai, so light is the override: pure
 * assignments from the precomputed --light-* palette; every derived alias
 * (cta, surface, muted, …) re-resolves automatically through the anchors.
 * ═══════════════════════════════════════════════════════════════════════════ */

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

  --color-background: var(--light-background);
  --color-background-elevated: var(--light-background-elevated);
  --color-surface: var(--light-surface);
  --color-text: var(--light-text);
  --color-text-muted: var(--light-text-muted);
  --color-border: var(--light-border);
  --color-border-soft: var(--light-border-soft);
  --color-accent: var(--light-accent);
  --color-accent-strong: var(--light-accent-strong);
  --color-accent-soft: var(--light-accent-soft);
  --color-focus: var(--light-focus);
  --color-link: var(--light-link);

  --color-primary-foreground: var(--light-background);
  --color-cta-hover: var(--light-cta-hover);
  --color-accent-bg: var(--light-accent-bg);
  --color-accent-text: var(--light-accent-text);
  --color-accent-surface: var(--light-accent-surface);
  --color-accent-border: var(--light-accent-border);

  --shadow-sm: var(--light-shadow-sm);
  --shadow-md: var(--light-shadow-md);
  --shadow-lg: var(--light-shadow-lg);
  --shadow-xl: var(--light-shadow-xl);
  --shadow-inner: var(--light-shadow-inner);
  --shadow-cta-glow: var(--light-shadow-cta-glow);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * NO SYSTEM-PREFERENCE OVERRIDE — on purpose.
 *
 * blesso.ai is dark unconditionally: its tokens.css sets color-scheme: dark
 * on :root and only flips via an explicit `html.light`, with no
 * prefers-color-scheme fallback. The blog mirrors that exactly, so the
 * default surface is ALWAYS the dark palette, on every visitor's machine.
 * Light appears only when the visitor explicitly chooses it (ThemeToggle or
 * a saved "light" preference). A media-query fallback would render the blog
 * white on light-preferring systems and break the match with the site.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════
 * TYPOGRAPHY DEFAULTS — applied at root so every block inherits
 * ═══════════════════════════════════════════════════════════════════════════ */

body {
  font-family: var(--font-body);
  font-feature-settings: "ss01", "cv11";
  font-variant-numeric: oldstyle-nums proportional-nums;
  font-size: var(--text-base);
  line-height: 1.7;
  color: var(--color-text);
  background: var(--color-background);
  transition: background-color var(--duration-normal) var(--ease-in-out),
              color var(--duration-normal) var(--ease-in-out);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading);
  font-weight: 300;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text);
}

h1 { font-size: var(--text-4xl); font-weight: 400; }
h2 { font-size: var(--text-3xl); font-weight: 400; }
h3 { font-size: var(--text-2xl); font-weight: 400; }

.tabular,
[data-tabular] {
  font-variant-numeric: tabular-nums lining-nums;
}

.smallcaps,
[data-smallcaps] {
  font-variant-caps: all-small-caps;
  letter-spacing: 0.08em;
  font-feature-settings: "smcp";
}

/* Long-form article rhythm (applied inside <article class="prose"> blocks) */
.prose {
  /* width:100% gives the article a DEFINITE size so it fills its grid track
   * and shrinks on mobile. Without it, margin-inline:auto makes the article
   * size to its max-content — a wide image or long code line then blows the
   * column past the viewport. max-width still caps the reading measure. */
  width: 100%;
  max-width: var(--measure-body);
  margin-inline: auto;
  font-size: var(--text-lg);
  line-height: 1.65;
}

/* The column fills the grid track so tables, diagrams and the FAQ use the
 * screen; running text keeps a readable line length inside it. */
.prose :is(p, ul, ol, dl, h2, h3, h4) { max-width: var(--measure-body); }
.prose > * + * { margin-top: var(--spacing-lg); }
.prose > h2 { margin-top: var(--spacing-2xl); margin-bottom: var(--spacing-sm); }
.prose > h3 { margin-top: var(--spacing-xl); margin-bottom: var(--spacing-2xs); }
.prose > figure,
.prose > pre,
.prose > blockquote { margin-block: var(--spacing-xl); }
.prose a { color: var(--color-link); text-decoration: underline; text-underline-offset: 0.2em; text-decoration-thickness: 0.075em; }
.prose a:hover { color: var(--color-accent-strong); }
/* Inline code only — explicitly excludes <code> inside <pre> so CodeBlock keeps its dark Terminal styling */
.prose :not(pre) > code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  padding: 0.12em 0.4em;
  background: var(--color-accent-soft);
  color: var(--color-accent-strong);
  border-radius: var(--radius-sm);
  font-weight: 500;
}
.prose pre code {
  background: transparent;
  padding: 0;
  font-size: inherit;
  color: inherit;
  border-radius: 0;
  font-weight: inherit;
}
/* Article tables: hairline rows, a quiet uppercase header, figures that line
 * up. The table is its own scroll box at every width: when its columns need
 * more room than the article column has (the TOC rail narrows it on desktop),
 * it scrolls sideways inside the column instead of spilling under the rail.
 * Posts never need a wrapper. */
.prose table {
  display: block;
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  margin-block: var(--spacing-xl);
  border-collapse: collapse;
  font-size: var(--text-base);
  line-height: 1.45;
  font-variant-numeric: tabular-nums lining-nums;
}
.prose th,
.prose td {
  padding: var(--spacing-sm) var(--spacing-md) var(--spacing-sm) 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}
.prose th {
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  border-bottom-color: var(--color-text-muted);
  white-space: nowrap;
}
.prose td:first-child { font-weight: 500; min-width: 8rem; }
.prose tbody tr:last-child td { border-bottom: none; }
.prose strong { font-weight: 600; }
.prose em { font-style: italic; }

::selection {
  background: var(--color-accent-soft);
  color: var(--color-text);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * COMPONENT-LEVEL CSS — minimal rules that can't be expressed inline
 * (hover/focus pseudo-states for Footnote tooltip, drop caps, etc.)
 * ═══════════════════════════════════════════════════════════════════════════ */

.footnote {
  position: relative;
  display: inline;
  white-space: nowrap;
}

.footnote:hover .footnote-tooltip,
.footnote:focus-within .footnote-tooltip {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* On touch there is no hover, and a popover beside the marker can overflow
 * the viewport near the column edge. A tap focuses the marker, so show the note
 * as a sheet along the bottom of the screen instead. */
@media (hover: none) {
  .footnote:focus-within .footnote-tooltip {
    position: fixed !important;
    left: var(--spacing-md) !important;
    right: var(--spacing-md) !important;
    bottom: var(--spacing-md) !important;
    width: auto !important;
    transform: none !important;
  }
}

.footnote a:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Article TOC scroll-spy active link */
.toc-link[data-active="true"] {
  color: var(--color-accent);
  border-left-color: var(--color-accent);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * BUTTONS — the site's own button system, overriding the rounded base.css
 * template: a 9px chamfer (--cut-button) on the top-left and bottom-right
 * corners, 40px tall, 14px medium text with wide tracking. Solid is paper on
 * ink; outline is a hairline border over the page surface. (Source: the
 * site's app bundle — its Button with solid/outline variants and the same
 * --cut: 9px clip-path.)
 * ═══════════════════════════════════════════════════════════════════════════ */
.btn {
  height: 2.5rem;
  padding: 0 1.25rem;
  border-radius: 0;
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.025em;
  clip-path: polygon(
    var(--cut-button) 0,
    100% 0,
    100% calc(100% - var(--cut-button)),
    calc(100% - var(--cut-button)) 100%,
    0 100%,
    0 var(--cut-button)
  );
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

.btn-primary {
  background: var(--color-cta);
  color: var(--color-cta-foreground);
  box-shadow: none;
}

.btn-primary:hover {
  background: var(--color-cta-hover);
  transform: none;
}

.btn-secondary {
  background: var(--color-background);
  color: var(--color-text);
  border: 1px solid var(--color-border);
}

.btn-secondary:hover {
  background: var(--color-muted);
  border-color: var(--color-border);
  color: var(--color-text);
}

.btn-sm {
  height: 2.5rem;
  padding: 0 1.25rem;
  font-size: var(--text-sm);
}

.btn-lg {
  height: 3rem;
  padding: 0 1.75rem;
  font-size: var(--text-base);
}


/* The article's reading column + TOC grid collapses below lg, where the TOC is hidden */
@media (max-width: 1023px) {
  .article-grid {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

/* Two-column layout (lg+): the reading column sits flush-left under the title,
 * with the TOC rail to its right. When the grid collapses (below), .prose keeps
 * its default margin-inline:auto so the lone column stays centered — never
 * pinned hard-left in a wide single-column viewport. */
@media (min-width: 1024px) {
  .article-grid > .prose {
    margin-inline: 0;
  }
}

/* A grid item defaults to min-width:auto, so one wide child (a table, a code
 * line, an image) can widen the article track and push it under the TOC rail.
 * min-width:0 pins the column to its track; wide children scroll or shrink
 * inside it. */
.article-grid > .prose {
  min-width: 0;
}
.prose img,
.prose svg {
  max-width: 100%;
}

/* Atelier asymmetric hero: image left / title right on lg, stacked below */
@media (max-width: 1023px) {
  .atelier-hero {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  body { transition: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * LAYOUT UTILITIES — the complete allowed utility-class set
 *
 * This file replaces the Tailwind Play CDN (a dev-only runtime that shipped
 * ~100KB of render-blocking JS). Only the classes below exist — there is no
 * arbitrary utility generation. Anything visual (color, spacing values,
 * radius, motion) comes from tokens.css variables via inline style.
 *
 * Breakpoints match base.css: md = 768px, lg = 1024px.
 * Responsive variants come AFTER the base classes so `hidden md:flex`
 * resolves correctly (media-scoped rule wins at its breakpoint).
 * ═══════════════════════════════════════════════════════════════════════════ */

.block { display: block; }
.hidden { display: none; }
.flex { display: flex; }
.inline-flex { display: inline-flex; }
.grid { display: grid; }

.flex-col { flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.items-baseline { align-items: baseline; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }

.rounded-md { border-radius: var(--radius-md); }

/* Named easing + tokened duration — no default `ease` curve. */
.transition-colors {
  transition:
    color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

/* Screen-reader-only content (accessibility). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (min-width: 768px) {
  .md\:block { display: block; }
  .md\:hidden { display: none; }
  .md\:flex { display: flex; }
  .md\:grid { display: grid; }
}

@media (min-width: 1024px) {
  .lg\:block { display: block; }
  .lg\:hidden { display: none; }
  .lg\:flex { display: flex; }
  .lg\:grid { display: grid; }
}

