/* ════════════════════════════════════════════════════════════════
   Observatory — Reaves Labs typography system v1
   Single source of truth, loaded site-wide via:
     <link rel="stylesheet" href="/css/observatory.css">

   Body stays Inter. Display becomes Fraunces (variable, with
   optical-size + soft-edge axes). Eyebrows stay Space Grotesk
   tracked uppercase. UI controls stay Space Grotesk. Numerals get
   tabular figures so columns align.

   Update once → propagates to every page that links this file.
   ════════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════════
   Self-hosted variable fonts — Phase 3D (2026-05-07)
   No more Google Fonts CDN dependency. All Latin-only woff2
   served from /assets/fonts/. Total wire weight: ~430KB.
   font-display: swap so text renders immediately with fallback.
   ════════════════════════════════════════════════════════════════ */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 25% 151%;
  font-display: swap;
  src: url('/assets/fonts/fraunces-variable-roman.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 100 900;
  font-stretch: 25% 151%;
  font-display: swap;
  src: url('/assets/fonts/fraunces-variable-italic.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/bricolage-grotesque-variable.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-variable.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-variable.woff2') format('woff2-variations');
}

:root {
  /* ── Typography (canonical) ─────────────────────────────────── */
  --rll-serif: 'Fraunces', 'Iowan Old Style', 'Hoefler Text', Georgia, serif;
  /* Phase 3D.1 (2026-05-07): Bricolage Grotesque replaces Space
     Grotesk — variable opsz+wght, distinctive grade, free OFL.
     Brand fingerprint instead of generic SaaS sans. */
  --rll-sans:  'Bricolage Grotesque', 'Space Grotesk', system-ui, sans-serif;
  --rll-body:  'Inter', system-ui, sans-serif;
  --rll-mono:  'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --rll-vf-display: "opsz" 144, "wght" 450, "SOFT" 30;
  --rll-vf-italic:  "opsz" 144, "wght" 400, "SOFT" 60;
  --rll-vf-sub:     "opsz" 96,  "wght" 500, "SOFT" 30;
  --rll-eyebrow-track: 0.2em;

  /* ── Legacy aliases (Phase 3A consolidation 2026-05-06) ──────
     Pages historically declared these in their own inline :root
     blocks. Now they live here once. Inline :root duplicates can
     be deleted. Keep names stable for backward compatibility. */
  --font-heading: var(--rll-sans);
  --font-body:    var(--rll-body);

  /* Color tokens — match brand canon in CLAUDE.md / RLL Brand Canon v1 */
  --base:         #0B0F1A;
  --base-light:   #111827;
  --surface:      rgba(255,255,255,0.05);
  --surface-hover: rgba(255,255,255,0.08);
  --border:       rgba(255,255,255,0.1);
  --text:         #F9FAFB;
  --text-muted:   #9CA3AF;
  --primary:      #3B82F6;
  --primary-glow: rgba(59,130,246,0.3);
  --gold:         #FCD34D;
  --gold-glow:    rgba(252,211,77,0.3);
  --cyan:         #00D4FF;
  --cyan-glow:    rgba(0,212,255,0.3);
  --emerald:      #34D399;

  /* Layout */
  --max-width:  1200px;
  --radius:     16px;
  --radius-sm:  10px;
  --radius-lg:  24px;

  /* Easings (legacy aliases of motion-system tokens defined below) */
  --bounce:     cubic-bezier(0.34, 1.56, 0.64, 1);
  --smooth:     cubic-bezier(0.4, 0, 0.2, 1);

  /* ── Phase 3C: OKLCH semantic palette (2026-05-07) ───────────
     Perceptually-uniform color tokens. Pages still reference legacy
     names (--base, --primary, etc.) which point at the same hex; new
     work should prefer semantic tokens for consistent dark/light
     pairing later. */

  /* Semantic foreground/background/border */
  --fg-primary:    oklch(98% 0.01 250);   /* near-white, slight cool tint */
  --fg-muted:      oklch(74% 0.02 250);   /* secondary text */
  --fg-subtle:     oklch(52% 0.02 250);   /* tertiary / placeholder */
  --bg-base:       oklch(15% 0.03 250);   /* primary page background */
  --bg-elevated:   oklch(20% 0.02 250);   /* cards, raised surfaces */
  --bg-sunken:     oklch(11% 0.03 250);   /* deepest surfaces */
  --border-subtle: oklch(98% 0.01 250 / 0.06);
  --border-default: oklch(98% 0.01 250 / 0.10);
  --border-strong: oklch(98% 0.01 250 / 0.20);

  /* Brand accents — single hue per accent, OKLCH ramp */
  --accent-brand:    oklch(65% 0.18 252); /* primary blue */
  --accent-gold:     oklch(85% 0.16 80);
  --accent-cyan:     oklch(82% 0.14 215);
  --accent-emerald:  oklch(78% 0.16 158);

  /* Elevation shadows — OKLCH-aware (cool shadows on dark surfaces) */
  --shadow-1: 0 1px 2px oklch(0% 0 0 / 0.18);
  --shadow-2: 0 4px 12px oklch(0% 0 0 / 0.22);
  --shadow-3: 0 12px 32px oklch(0% 0 0 / 0.28);
  --shadow-4: 0 24px 60px oklch(0% 0 0 / 0.34);
}

/* ── Display headings — Fraunces across the site ───────────────── */
h1,
h2,
h3,
.hero h1,
.section-header h2,
.cat-title,
.tier h3,
.pkg-title,
.contact-info h3,
#bloom-consulting-hero h1,
#bloom-consulting-hero .tier h3,
.feature-list h3,
.product-detail h2,
.product-detail h3,
.cta-section h2,
.faq-q,
.testimonial-name {
  font-family: var(--rll-serif) !important;
  letter-spacing: -0.012em;
  line-height: 1.18;
  font-feature-settings: "ss01" 1, "calt" 1;
}

/* Hero headlines */
h1,
.hero h1,
#bloom-consulting-hero h1 {
  font-variation-settings: var(--rll-vf-display);
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  font-weight: 450;
  line-height: 1.08;
  letter-spacing: -0.022em;
}

/* Section headers */
h2,
.section-header h2,
.cta-section h2,
.product-detail h2 {
  font-variation-settings: var(--rll-vf-display);
  font-size: clamp(1.5rem, 3.1vw, 2.3rem);
  font-weight: 500;
  line-height: 1.14;
  letter-spacing: -0.018em;
}

/* h3-class titles (cards, packages, tiers, contacts) */
h3,
.tier h3,
.pkg-title,
.contact-info h3,
.product-detail h3,
#bloom-consulting-hero .tier h3 {
  font-variation-settings: var(--rll-vf-sub);
  font-weight: 500;
}

/* Italic accent rule — subtle editorial highlight (use <em>) */
h1 em,
h2 em,
h3 em,
.cat-title em,
.hero h1 em,
.hero h1 .gradient,
#bloom-consulting-hero h1 .highlight {
  font-style: italic;
  font-variation-settings: var(--rll-vf-italic);
  /* Strip any legacy gradient text-fill so the serif italic is the accent */
  -webkit-text-fill-color: currentColor;
  background: none;
  background-clip: initial;
  -webkit-background-clip: initial;
  color: inherit;
  font-weight: 450;
}

/* ── Eyebrow labels — Space Grotesk, tracked, uppercase ─────────── */
.section-label,
.cat-eyebrow,
.hero-label,
.tier-label,
.pkg-section-title,
.footer-col h4 {
  font-family: var(--rll-sans);
  letter-spacing: var(--rll-eyebrow-track);
  text-transform: uppercase;
  font-weight: 500;
  font-size: 0.7rem;
  /* Drop the rounded pill background; let typography carry the eyebrow */
  background: transparent !important;
  border: 0 !important;
  padding: 0 !important;
  border-radius: 0 !important;
  margin-bottom: 14px !important;
  display: inline-block;
}

/* Pill-style eyebrows on consulting hero get the same treatment */
#bloom-consulting-hero .bloom-badge,
#bloom-consulting-hero .tier .tier-label {
  font-family: var(--rll-sans);
  letter-spacing: var(--rll-eyebrow-track);
}

/* ── Body copy — Inter, kept as-is for readability ──────────────── */
body,
p,
li,
.hero p,
.section-header p,
.cat-lede,
.pkg-tagline,
.testimonial-quote {
  font-family: var(--rll-body);
}

.hero p,
.section-header p,
.cat-lede {
  font-size: 1.04rem;
  line-height: 1.62;
}

/* Testimonial quote — italic serif works here */
.testimonial-quote {
  font-family: var(--rll-serif);
  font-variation-settings: var(--rll-vf-italic);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.6;
}

/* ── UI controls stay Space Grotesk — explicit guard against
      Fraunces inheritance via h-tag selectors ───────────────────── */
.btn,
button,
.cta,
.book-cta,
.btn-buy-sm,
.btn-sub-sm,
.btn-bundle-sm,
.filter-tab,
input,
select,
textarea {
  font-family: var(--rll-sans);
}

/* ── Numerals — tabular figures so dollars / counters line up ──── */
.trust-item .num,
.roi-stat .value,
.pkg-price,
.pkg-number,
.coming-soon-label {
  font-family: var(--rll-mono);
  font-feature-settings: "tnum" 1;
  letter-spacing: 0;
}

/* The big trust-bar numbers (12 patents / 45 agents) read as a
   typographic display — keep mono for the figure, calm the color */
.trust-item .num {
  font-size: clamp(1.6rem, 2.4vw, 2rem);
  font-weight: 500;
}

/* ── Nav logo — keep Space Grotesk, tighter tracking ───────────── */
.nav-logo {
  font-family: var(--rll-sans);
  letter-spacing: -0.005em;
}

/* ════════════════════════════════════════════════════════════════
   Hero system v3 — investor-grade hero, shared across pages.
   Pages opt in by adding markup inside .hero (or .obs-hero):
     .hero-eyebrow · h1 with optional <em> · .hero p · .hero-ctas
     .hero-personas · .hero-trust
   ════════════════════════════════════════════════════════════════ */
.hero-eyebrow {
  display: inline-block;
  font-family: var(--rll-sans);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(252,211,77,0.85);
  margin-bottom: 22px;
  padding: 6px 14px;
  border: 1px solid rgba(252,211,77,0.25);
  border-radius: 999px;
  background: rgba(252,211,77,0.04);
}
.hero-eyebrow .dot {
  display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: #FCD34D; margin-right: 8px; vertical-align: middle;
  animation: hero-dot-pulse 2.4s ease-in-out infinite;
}
@keyframes hero-dot-pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.55; transform: scale(0.85); } }

/* Eyebrow color variants — set color tokens on the element via inline style */
.hero-eyebrow[data-tone="cyan"]    { color: rgba(0,212,255,0.85); border-color: rgba(0,212,255,0.25); background: rgba(0,212,255,0.04); }
.hero-eyebrow[data-tone="cyan"] .dot    { background: #00D4FF; }
.hero-eyebrow[data-tone="emerald"] { color: rgba(52,211,153,0.85); border-color: rgba(52,211,153,0.25); background: rgba(52,211,153,0.04); }
.hero-eyebrow[data-tone="emerald"] .dot { background: #34D399; }
.hero-eyebrow[data-tone="violet"]  { color: rgba(168,85,247,0.85); border-color: rgba(168,85,247,0.25); background: rgba(168,85,247,0.04); }
.hero-eyebrow[data-tone="violet"] .dot   { background: #A855F7; }

/* Hero CTAs */
.hero-ctas .btn-hero-primary {
  background: linear-gradient(135deg, #3B82F6 0%, #00D4FF 100%);
  color: #0B0F1A;
  padding: 14px 28px;
  border-radius: 10px;
  font-family: var(--rll-sans);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  border: 0;
  box-shadow: 0 8px 32px rgba(0,212,255,0.35), 0 2px 8px rgba(59,130,246,0.2);
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s;
  cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 8px;
}
.hero-ctas .btn-hero-primary:hover {
  transform: translateY(-2px); color: #0B0F1A;
  box-shadow: 0 12px 40px rgba(0,212,255,0.5), 0 4px 12px rgba(59,130,246,0.3);
}
.hero-ctas .btn-hero-secondary {
  background: transparent; color: #F1F5F9;
  padding: 14px 24px;
  border-radius: 10px;
  border: 1px solid rgba(255,255,255,0.18);
  font-family: var(--rll-sans);
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 8px;
  transition: border-color 0.2s, background 0.2s, transform 0.2s;
}
.hero-ctas .btn-hero-secondary:hover {
  border-color: rgba(0,212,255,0.6); background: rgba(0,212,255,0.06);
  color: #F1F5F9; transform: translateY(-1px);
}
.hero-ctas .btn-hero-secondary .ear {
  font-family: var(--rll-serif);
  font-style: italic; font-weight: 400; font-size: 1.05em;
  color: #00D4FF;
}

/* Demoted persona-routing chips */
.hero-personas {
  margin-top: 26px;
  display: flex; gap: 10px; justify-content: center; flex-wrap: wrap;
  align-items: center;
  font-family: var(--rll-sans);
}
.hero-personas-label {
  font-family: var(--rll-serif);
  font-style: italic; font-size: 0.95rem;
  color: rgba(255,255,255,0.55);
}
.hero-personas a {
  color: rgba(255,255,255,0.72); text-decoration: none;
  padding: 6px 14px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,0.1);
  font-size: 0.78rem; font-weight: 500; letter-spacing: 0.04em;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.hero-personas a:hover {
  color: #F1F5F9; border-color: rgba(0,212,255,0.4); background: rgba(0,212,255,0.06);
}

/* Single-line trust strip */
.hero-trust {
  margin-top: 28px;
  display: flex; gap: 10px 18px; justify-content: center; flex-wrap: wrap;
  font-family: var(--rll-mono);
  font-size: 0.72rem;
  color: rgba(255,255,255,0.4);
  letter-spacing: 0.04em;
}
.hero-trust span.sep { opacity: 0.4; }

@media (max-width: 640px) {
  .hero-eyebrow { font-size: 0.6rem; padding: 5px 10px; }
  .hero-ctas .btn-hero-primary, .hero-ctas .btn-hero-secondary { padding: 12px 18px; font-size: 0.88rem; }
}

/* ── A small reset so legacy gradient-text headlines don't fight
      with the new serif italic ──────────────────────────────────── */
.hero h1 .gradient {
  font-style: italic;
}

/* ════════════════════════════════════════════════════════════════
   Motion system — durations + easings + reduced-motion override
   Single source of truth. Every page loading observatory.css
   inherits these tokens AND the global reduced-motion behavior.
   ════════════════════════════════════════════════════════════════ */
:root {
  /* Durations — 5 named steps from instant to deliberate */
  --dur-instant: 80ms;     /* hover paints, focus rings */
  --dur-fast:    160ms;    /* button states, small reveals */
  --dur-base:    260ms;    /* card lifts, panel transitions */
  --dur-slow:    420ms;    /* section reveals, route entries */
  --dur-deliberate: 640ms; /* hero animations, structural moves */

  /* Easings — 4 named curves */
  --ease-snap:        cubic-bezier(0.4, 0, 0.2, 1);     /* default UI */
  --ease-soft:        cubic-bezier(0.32, 0.72, 0, 1);   /* refined deceleration */
  --ease-spring:      cubic-bezier(0.34, 1.56, 0.64, 1); /* card lifts, bouncy reveals */
  --ease-emphasized:  cubic-bezier(0.22, 1, 0.36, 1);   /* signature interactions */

  /* Stagger spacing for list reveals */
  --stagger-step: 50ms;
}

/* Global reduced-motion override — accessibility critical.
   Anyone who's set system-level "Reduce motion" gets near-zero
   animation/transition durations and disabled scroll-snap. We
   intentionally keep durations at 0.01ms (not 0) so React/Framer-
   style animation libs that fire onAnimationEnd still trigger. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
