*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
  --bg: #080B1A; --bg-center: #0A1628; --bg-edge: #020408;
  --bg-glass: rgba(10,22,40,0.6); --bg-card: rgba(255,255,255,0.03);
  --teal: #00D4FF; --teal-dim: rgba(0,212,255,0.15); --teal-glow: rgba(0,212,255,0.25);
  --purple: #7B2FBE; --purple-dim: rgba(123,47,190,0.15);
  /* 2026-04-30 — Blue Chips Mono. Coral tokens retained for backwards
     compat (hundreds of consumers across pages); values flipped to
     pure cyan #00FFFF. Hover uses a brighter cyan tint, glow uses
     the same alpha at cyan. --text-action also flipped — it was an
     orange CTA-text token in the same family. */
  --cyan: #00FFFF; --cyan-hover: #7CFFFF; --cyan-glow: rgba(0,255,255,0.35);
  /* Cyan tier palette (added 2026-05-19 with THEME_RULES.md). Every
     hard-coded rgba(0,255,255,*) in component CSS routes through one of
     these tokens — they have light-mode counterparts below so every
     surface adapts. Lower numbers = fainter alpha. */
  --cyan-bg-faint: rgba(0,255,255,0.06);
  --cyan-bg-soft: rgba(0,255,255,0.10);
  --cyan-bg-hover: rgba(0,255,255,0.18);
  --cyan-border-faint: rgba(0,255,255,0.22);
  --cyan-border: rgba(0,255,255,0.32);
  --cyan-border-strong: rgba(0,255,255,0.55);
  --cyan-glow-soft: rgba(0,255,255,0.25);
  --cyan-glow-strong: rgba(0,255,255,0.50);
  --cyan-text-action: rgba(0,255,255,0.85);
  /* Text color to use ON a cyan-filled surface (button bg = var(--cyan),
     text on it = var(--on-cyan)). Light mode flips to white because
     light-mode cyan resolves to dark teal. */
  --on-cyan: #0a0a0f;
  /* Error palette — used by inline error states (form errors, chat
     errors, dock error messages). Both modes pass AA. */
  --error-bg: rgba(255, 80, 80, 0.08);
  --error-border: rgba(255, 80, 80, 0.32);
  --error-text: rgba(255, 200, 200, 0.92);
  /* Neutral muted surface tokens — for non-cyan tints (chat bubbles,
     input bg, dividers). */
  --surface-soft: rgba(255, 255, 255, 0.04);
  --surface-border: rgba(255, 255, 255, 0.10);
  --surface-border-faint: rgba(255, 255, 255, 0.06);
  --icon-muted: rgba(255, 255, 255, 0.32);
  /* Tooltips read as "system message" and stay dark in both themes —
     the bg/fg pair is identical across :root and [data-theme="light"]. */
  --tooltip-bg: rgba(20, 20, 28, 0.94);
  --tooltip-fg: rgba(255, 255, 255, 0.92);
  --mint: #00FFB3; --mint-dim: rgba(0,255,179,0.1);
  --white: #FFFFFF; --body: #B8C9D9; --muted: #6B7F94;
  --border: rgba(0,212,255,0.12); --border-hover: rgba(0,212,255,0.35);
  --text-primary: rgba(255,255,255,0.95);
  --text-secondary: rgba(255,255,255,0.72);
  --text-tertiary: rgba(255,255,255,0.45);
  --text-action: rgba(0,255,255,0.85);
  --card-bg: #141921;
  --card-bg-hover: #1a2230;
  --card-bg-featured: #1e2a3a;
  --tag-bg: rgba(255,255,255,0.08);
  --tag-border: rgba(255,255,255,0.12);
  /* Locked design invariant 2026-05-01 — see CLAUDE.md.
     Inter for everything; JetBrains Mono is loaded alongside on key
     surfaces for technical/numeric overlays when a monospace cue is
     warranted. Tabular-nums + lining-nums declared globally so
     big-number stats (rankings, citations, position) align in
     columns even when individual cards forget to opt in. */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* Light mode token overrides (Blue Chips Mono, light variant).
   Pure #00FFFF cyan washes out on white — light mode swaps the accent
   token to a darker teal (#007A8E) so every consumer of var(--cyan)
   / var(--teal) / var(--text-action) automatically reads as a real
   color on white. --white stays a literal #FFFFFF (used by surfaces
   that are intentionally white, e.g. modal fills); body color is set
   directly in the light-mode body rule below. */
[data-theme="light"] {
  --bg: #F5F8FA; --bg-center: #FFFFFF; --bg-edge: #E2EAEF;
  --bg-glass: rgba(255,255,255,0.78); --bg-card: rgba(14,31,38,0.03);
  --teal: #007A8E; --teal-dim: rgba(0,122,142,0.10); --teal-glow: rgba(0,122,142,0.20);
  --cyan: #007A8E; --cyan-hover: #005F70; --cyan-glow: rgba(0,122,142,0.28);
  --cyan-bg-faint: rgba(0,122,142,0.06);
  --cyan-bg-soft: rgba(0,122,142,0.10);
  --cyan-bg-hover: rgba(0,122,142,0.16);
  --cyan-border-faint: rgba(0,122,142,0.25);
  --cyan-border: rgba(0,122,142,0.45);
  --cyan-border-strong: rgba(0,122,142,0.65);
  --cyan-glow-soft: rgba(0,122,142,0.18);
  --cyan-glow-strong: rgba(0,122,142,0.32);
  --cyan-text-action: #007A8E;
  --on-cyan: #FFFFFF;
  --error-bg: rgba(200, 30, 30, 0.06);
  --error-border: rgba(200, 30, 30, 0.40);
  --error-text: #B33;
  --surface-soft: rgba(14, 31, 38, 0.04);
  --surface-border: rgba(14, 31, 38, 0.12);
  --surface-border-faint: rgba(14, 31, 38, 0.08);
  --icon-muted: rgba(14, 31, 38, 0.40);
  /* Tooltip pair stays identical to dark mode — see :root comment. */
  --tooltip-bg: rgba(20, 20, 28, 0.94);
  --tooltip-fg: rgba(255, 255, 255, 0.92);
  --mint: #00997A; --mint-dim: rgba(0,153,122,0.10);
  --body: #3F4D55; --muted: #6B7C84;
  --border: rgba(14,31,38,0.12); --border-hover: rgba(0,122,142,0.40);
  --text-primary: #0E1F26;
  --text-secondary: rgba(14,31,38,0.72);
  --text-tertiary: rgba(14,31,38,0.50);
  --text-action: #007A8E;
  --card-bg: #F5FAFC; --card-bg-hover: #ECF3F7; --card-bg-featured: #E0EBF0;
  --tag-bg: rgba(14,31,38,0.06); --tag-border: rgba(14,31,38,0.12);
}
html { scroll-behavior: smooth; }
body {
  font-family: var(--font); background: radial-gradient(ellipse at 50% 30%, var(--bg-center), var(--bg-edge) 70%);
  background-attachment: fixed; color: var(--white); line-height: 1.6;
  -webkit-font-smoothing: antialiased; min-height: 100vh; overflow-x: hidden;
  font-feature-settings: "tnum" on, "lnum" on;
}
[data-theme="light"] body { color: var(--text-primary); }
/* Helpers for surfaces that want explicit tabular-nums affordance
   (e.g. big-number stat tiles, ranking columns). The body-level rule
   already turns it on globally; these are class hooks for inline-style
   surfaces that re-declare font-variant-numeric and need to opt back
   in without touching the body rule. */
.tabular-nums,
.ro-stat-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" on, "lnum" on;
}
a { color: var(--teal); text-decoration: none; }
a:hover { color: var(--mint); }

/* Nav */
.app-nav {
  position: sticky; top: 0; z-index: 100; min-height: 60px;
  background: rgba(2,4,8,0.9); backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--border); display: flex; align-items: center; padding: 0 24px;
}
.app-nav-inner { max-width: 1080px; margin: 0 auto; width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.nav-left { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.nav-logo { font-size: 20px; font-weight: 800; color: var(--white); text-decoration: none; }
.nav-otto { width: 28px; height: 28px; }
.nav-links { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.nav-links a { font-size: 13px; font-weight: 600; color: var(--body); transition: color 0.2s; text-decoration: none; white-space: nowrap; }
.nav-links a:hover, .nav-links a.active { color: var(--white); }
.nav-links button {
  background: none; border: none; font-size: 13px; font-weight: 600; color: var(--muted);
  cursor: pointer; font-family: var(--font); transition: color 0.2s; white-space: nowrap;
}
.nav-links button:hover { color: var(--cyan); }
@media (max-width: 720px) {
  .app-nav { padding: 8px 16px; }
  .nav-links { gap: 12px; width: 100%; justify-content: flex-start; padding-top: 6px; border-top: 1px solid rgba(0,212,255,0.06); margin-top: 4px; overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch; }
  .nav-links::-webkit-scrollbar { display: none; }
}

/* Containers */
.container { max-width: 960px; margin: 0 auto; padding: 0 24px; }
.page { padding: 48px 0; }

/* Cards */
.card {
  position: relative; border-radius: 18px; padding: 2px;
  background: linear-gradient(135deg, var(--teal), var(--purple));
}
.card-inner {
  background: var(--bg-glass); backdrop-filter: blur(16px); border-radius: 16px; padding: 32px 28px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
}
.card-flat {
  background: var(--bg-glass); backdrop-filter: blur(12px);
  border: 1px solid var(--border); border-radius: 16px; padding: 28px 24px;
  transition: border-color 0.3s, box-shadow 0.3s;
}
.card-flat:hover { border-color: var(--border-hover); box-shadow: 0 0 24px var(--teal-glow); }

/* Buttons — "Ask Otto" pattern (2026-05-15 contrast pass).
   Both buttons share the cyan-border identity of the sidebar's Ask
   Otto pill. .btn-cyan ships filled by default (primary CTA); .btn-outline
   ships transparent with cyan text and fills on hover. Borders are 2px
   so cyan reads as a real outline (1px washed out on light bg).
   Both modes use var(--cyan), which resolves to #00FFFF in dark and
   #007A8E in light, so contrast is real on white backgrounds without
   per-page overrides. */
.btn-cyan {
  display: inline-block; font-size: 15px; font-weight: 700; padding: 12px 30px;
  background: var(--cyan); color: #0a0a0f; border: 2px solid var(--cyan); border-radius: 10px;
  cursor: pointer; font-family: var(--font); transition: all 0.2s ease;
  box-shadow: 0 4px 20px var(--cyan-glow); text-decoration: none; text-align: center;
  letter-spacing: 0.01em;
}
.btn-cyan:hover { background: var(--cyan-hover); border-color: var(--cyan-hover); transform: translateY(-1px); box-shadow: 0 6px 30px var(--cyan-glow); color: #0a0a0f; }
.btn-cyan:disabled { opacity: 0.5; cursor: not-allowed; box-shadow: none; transform: none; }
/* In light mode, .btn-cyan's filled darker-teal needs a darker text
   for AA (white on #007A8E fails). #0a0a0f already passes — keep. */
[data-theme="light"] .btn-cyan { color: #FFFFFF; }
[data-theme="light"] .btn-cyan:hover { color: #FFFFFF; }

.btn-outline {
  display: inline-block; font-size: 14px; font-weight: 600; padding: 10px 22px;
  background: transparent; color: var(--cyan); border: 2px solid var(--cyan); border-radius: 10px;
  cursor: pointer; font-family: var(--font); transition: all 0.2s ease; text-decoration: none;
  letter-spacing: 0.01em;
}
.btn-outline:hover {
  background: var(--cyan); color: #0a0a0f; box-shadow: 0 0 24px var(--cyan-glow);
}
[data-theme="light"] .btn-outline:hover { color: #FFFFFF; }

/* Focus rings — accessibility floor for the two shared button
   primitives. Without this, keyboard users get no visible indicator
   when these CTAs receive focus. The 2px cyan outline at 3px offset
   stands off the cyan fill of .btn-cyan via the transparent gap, and
   sits cleanly outside .btn-outline. Pages on light backgrounds where
   cyan-on-light contrast feels weak can strengthen with a local
   :focus-visible rule (see content.html:140 — uses --tp-focus-ring). */
.btn-cyan:focus-visible,
.btn-outline:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
}

/* Form elements */
.input {
  width: 100%; padding: 16px 20px; font-size: 16px; font-family: var(--font);
  background: var(--bg-glass); border: 2px solid var(--border); border-radius: 12px;
  color: var(--white); outline: none; backdrop-filter: blur(12px); transition: border-color 0.3s, box-shadow 0.3s;
}
.input:focus { border-color: var(--teal); box-shadow: 0 0 20px rgba(0,212,255,0.15); }
.input::placeholder { color: var(--muted); }
[data-theme="light"] .input { color: var(--text-primary); }
[data-theme="light"] .input:focus { box-shadow: 0 0 20px var(--cyan-glow); }

/* Labels */
.label { font-size: 12px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--teal); margin-bottom: 8px; display: block; }

/* Typography */
/* Heading weights — Blue Chips spec (CLAUDE.md, locked).
   h1/h2 at 600, h3 at 500. Operator-tool aesthetic — Linear / Vercel /
   Stripe — calmer than marketing-bold weights. Pages with explicit
   weight overrides have been removed in this same PR; new pages should
   inherit these defaults. Per-surface narrowing is allowed (see
   .rch-page-title--radar in reach.html for the canonical example). */
h1 { font-size: clamp(28px, 4vw, 42px); font-weight: 600; letter-spacing: -1px; line-height: 1.1; margin-bottom: 12px; }
h2 { font-size: 22px; font-weight: 600; letter-spacing: -0.5px; margin-bottom: 8px; }
h3 { font-size: 17px; font-weight: 500; margin-bottom: 6px; }
.text-muted { color: var(--muted); }
.text-body { color: var(--body); }
.text-teal { color: var(--teal); }
.text-cyan { color: var(--cyan); }
.text-mint { color: var(--mint); }

/* Status badges */
.badge { display: inline-block; font-size: 11px; font-weight: 700; padding: 4px 12px; border-radius: 6px; text-transform: uppercase; letter-spacing: 1px; }
.badge-building { background: var(--teal-dim); color: var(--teal); }
.badge-ready { background: var(--mint-dim); color: var(--mint); }
/* .badge-trial — Blue Chips cyan/glass variant. */
.badge-trial { background: rgba(0,255,255,0.10); color: var(--cyan); border: 1px solid rgba(0,255,255,0.22); }

/* Progress bar */
.progress { height: 6px; background: rgba(255,255,255,0.06); border-radius: 3px; overflow: hidden; margin-top: 8px; }
.progress-bar { height: 100%; border-radius: 3px; background: linear-gradient(90deg, var(--teal), var(--mint)); transition: width 0.5s; }

/* Grid */
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }
.grid-4 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
@media (min-width: 768px) { .grid-4 { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 640px) { .grid-2 { grid-template-columns: 1fr; } }

/* Modal */
.modal-bg { display: none; position: fixed; inset: 0; z-index: 200; background: rgba(2,4,8,0.8); backdrop-filter: blur(6px); align-items: center; justify-content: center; }
.modal-bg.open { display: flex; }
.modal-box { background: rgba(10,22,40,0.95); border: 1px solid var(--border); border-radius: 20px; padding: 36px 32px; max-width: 500px; width: 90%; max-height: 80vh; overflow-y: auto; }
.modal-box h3 { margin-bottom: 16px; }
.modal-close { position: absolute; top: 14px; right: 14px; background: none; border: none; color: var(--muted); font-size: 22px; cursor: pointer; }
[data-theme="light"] .modal-box { background: rgba(255,255,255,0.98); color: var(--text-primary); }

/* Utility */
.hidden { display: none !important; }
.center { text-align: center; }
.mt-4 { margin-top: 16px; }
.mt-6 { margin-top: 24px; }
.mt-8 { margin-top: 32px; }
.mb-4 { margin-bottom: 16px; }
.gap-3 { gap: 12px; }

/* Animation */
.fade-in { animation: fadeIn 0.5s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }

/* Otto arm animation */
.otto-svg .otto-arm { transform-origin: center top; }
.otto-svg .otto-arm:nth-child(1) { animation: armWave 4s ease-in-out 0s infinite; }
.otto-svg .otto-arm:nth-child(2) { animation: armWave 4s ease-in-out 0.3s infinite; }
.otto-svg .otto-arm:nth-child(3) { animation: armWave 4s ease-in-out 0.6s infinite; }
.otto-svg .otto-arm:nth-child(4) { animation: armWave 4s ease-in-out 0.9s infinite; }
.otto-svg .otto-arm:nth-child(5) { animation: armWave 4s ease-in-out 0.15s infinite; }
.otto-svg .otto-arm:nth-child(6) { animation: armWave 4s ease-in-out 0.45s infinite; }
.otto-svg .otto-arm:nth-child(7) { animation: armWave 4s ease-in-out 0.75s infinite; }
.otto-svg .otto-arm:nth-child(8) { animation: armWave 4s ease-in-out 1.05s infinite; }
@keyframes armWave { 0%,100%{transform:rotate(0)} 25%{transform:rotate(8deg)} 75%{transform:rotate(-8deg)} }
@keyframes ottoBob { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-8px)} }
