/* HyperFocusOZ — shared theme tokens, base styles, dark-mode overrides.
 *
 * Two layers of tokens:
 *   1. Brand constants (--color-*) — never change between themes
 *   2. Semantic tokens (--bg, --fg, --bg-inverted, etc) — light/dark mappings
 *
 * Legacy aliases (--ink, --bone, --paper, --bone-deep, --dark, --muted) are
 * kept so existing inline JSX styles keep working unchanged where they used
 * those names as primary-text or primary-bg. For surfaces that are
 * INTENTIONALLY inverted (a dark band in light mode), use the new
 * --bg-inverted / --fg-on-inverted tokens so they look right in both modes.
 */

:root {
  /* Brand constants — fixed values from the brand sheet */
  --color-ink: #141414;
  --color-bone: #f3eee4;
  --color-paper: #faf7f1;
  --color-bone-deep: #e8e1d3;
  --color-dark: #0f0d0a;
  --color-ember: #c2611f;
  --color-ember-deep: #9d4d12;
  --color-ok: #1f7a4d;

  /* Semantic tokens — light theme defaults */
  --bg: #f3eee4;
  --bg-alt: #e8e1d3;
  --bg-elevated: #faf7f1;
  --bg-inverted: #141414;
  --bg-footer: #0f0d0a;
  --bg-cta: #c2611f;        /* the ember CTA section — stays ember always */
  --bg-cta-fg: #ffffff;

  --fg: #141414;
  --fg-muted: rgba(20, 20, 20, 0.55);
  --fg-on-inverted: #f3eee4;
  --fg-on-inverted-muted: rgba(243, 238, 228, 0.65);
  --fg-on-inverted-subtle: rgba(243, 238, 228, 0.10);

  --line: rgba(20, 20, 20, 0.10);
  --line-soft: rgba(20, 20, 20, 0.06);

  --bg-subtle: rgba(20, 20, 20, 0.04);     /* faint chip / pill background */
  --bg-subtle-2: rgba(20, 20, 20, 0.02);   /* even fainter — sidebar wells */

  --nav-bg: rgba(243, 238, 228, 0.78);
  --shadow-card: 0 1px 0 rgba(20,20,20,0.04), 0 24px 48px -24px rgba(20,20,20,0.12);
  --shadow-lift: 0 30px 60px -20px rgba(20,20,20,0.18), 0 12px 24px -12px rgba(20,20,20,0.10);

  /* Legacy aliases — keep existing JSX working */
  --ink: var(--fg);
  --bone: var(--bg);
  --paper: var(--bg-elevated);
  --bone-deep: var(--bg-alt);
  --dark: var(--bg-footer);
  --muted: var(--fg-muted);
  --ember: var(--color-ember);
  --ember-deep: var(--color-ember-deep);
  --ok: var(--color-ok);

  --max: 1280px;
  --gutter: 32px;
}

/* Dark theme overrides — same semantic vars, different values.
 * Brand constants stay the same; ember and ok remain themselves.
 */
[data-theme="dark"] {
  --bg: #0f0d0a;
  --bg-alt: #161310;
  --bg-elevated: #1c1814;
  --bg-inverted: #050402;       /* even deeper than the page so it still reads as a band */
  --bg-footer: #050402;
  --bg-cta: #c2611f;            /* CTA stays ember */
  --bg-cta-fg: #ffffff;

  --fg: #f3eee4;
  --fg-muted: rgba(243, 238, 228, 0.55);
  --fg-on-inverted: #f3eee4;
  --fg-on-inverted-muted: rgba(243, 238, 228, 0.65);
  --fg-on-inverted-subtle: rgba(243, 238, 228, 0.08);

  --line: rgba(243, 238, 228, 0.10);
  --line-soft: rgba(243, 238, 228, 0.06);

  --bg-subtle: rgba(243, 238, 228, 0.06);
  --bg-subtle-2: rgba(243, 238, 228, 0.03);

  --nav-bg: rgba(15, 13, 10, 0.78);
  --shadow-card: 0 1px 0 rgba(0,0,0,0.4), 0 24px 48px -24px rgba(0,0,0,0.6);
  --shadow-lift: 0 30px 60px -20px rgba(0,0,0,0.6), 0 12px 24px -12px rgba(0,0,0,0.4);
}

/* Smooth theme transitions — but only after first paint, so the initial
 * page-load doesn't fade in. The .ready class is added by theme.js after
 * the next animation frame.
 *
 * IMPORTANT: this only targets html/body, NOT every descendant. The earlier
 * `html.ready *` rule applied a transition-shorthand to every element,
 * which silently wiped per-element transition declarations elsewhere
 * (notably .hf-reveal's opacity/transform transitions). Theme bg/fg colors
 * still flip correctly because var()-driven properties update instantly
 * when the custom properties change; the page just doesn't fade. */
html.ready, html.ready body {
  transition: background-color .25s ease-out, color .25s ease-out;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  font-family: "Hanken Grotesk", system-ui, sans-serif;
  background: var(--bg);
  color: var(--fg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.mono { font-family: "JetBrains Mono", ui-monospace, monospace; }
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }
.container { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }

.eyebrow {
  font-family: "JetBrains Mono", monospace;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--fg-muted);
}
.eyebrow .accent { color: var(--ember); }

/* Form controls — themed for dark mode too */
input, textarea, select {
  font: inherit; color: var(--fg);
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 12px 14px;
  width: 100%;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
input::placeholder, textarea::placeholder { color: var(--fg-muted); }
input:focus, textarea:focus, select:focus {
  outline: none; border-color: var(--ember);
  box-shadow: 0 0 0 4px rgba(194,97,31,0.12);
  background: var(--bg);
}
textarea { resize: vertical; min-height: 132px; }
label { font-size: 13px; font-weight: 600; color: var(--fg); }

/* select arrow visibility in dark mode */
[data-theme="dark"] select {
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
                    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) center, calc(100% - 13px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  appearance: none;
}

/* ───────────────────────────────────────────────────────────────────────
 * Mobile pass — viewport <= 760px
 *
 * The site is JSX-driven so most layout reflow happens in components via
 * useIsMobile(). What lives here:
 *   - Container/gutter shrink
 *   - Defensive media-query overrides on inline patterns that are easier
 *     to fix in CSS than to thread isMobile into deep components.
 * ─────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  :root { --gutter: 20px; }

  /* Tighten the sticky nav height + drop the desktop link row */
  .container { padding: 0 var(--gutter); }

  /* Forms reflow */
  textarea { min-height: 110px; }

  /* Disable hover-tilt on touch — touchscreens don't have hover */
  .hf-lift:hover { transform: none; }
}

@media (hover: none) {
  .hf-lift:hover { transform: none; }
}

/* Hash-navigation offset — keeps the sticky nav from hiding the anchored
 * section when the browser scrolls to it. The JS hash-scroll handler in
 * site-shell.jsx applies a matching offset for late-render targets. */
[id] { scroll-margin-top: 88px; }
@media (max-width: 760px) {
  [id] { scroll-margin-top: 76px; }
}

/* ───────────────────────────────────────────────────────────────────────
 * Performance optimisations
 *
 * Mobile browsers — especially mobile Safari — render `backdrop-filter`
 * and infinite GPU animations expensively. The page-load on a mid-range
 * phone was choppy because:
 *   - the sticky nav recomputed its backdrop-blur on every scroll frame
 *   - the ember "accepting Q3" pulse + process-step pulses ran
 *     continuously, holding the compositor busy
 *   - several .hf-fadeup transitions could overlap mid-scroll
 *
 * Fix: drop the backdrop blur and trim animation cost on small viewports,
 * and fully honour `prefers-reduced-motion`.
 * ─────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {
  /* Sticky nav: solid background instead of backdrop blur */
  nav { backdrop-filter: none !important; -webkit-backdrop-filter: none !important; background: var(--bg) !important; }
  /* Any other element using backdrop-filter (glass CTA cards) loses it
   * on mobile too — the visual loss is small, the perf win is big. */
  [style*="backdrop-filter"], [style*="backdropFilter"] {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  /* Shorter fade-up so reveals don't pile up during a scroll */
  .hf-fadeup { transition-duration: .42s !important; }
  /* Slower pulse → fewer compositor wakeups */
  .hf-pulse { animation-duration: 3.6s; }
  /* Cheaper card-lift hover — but hover is already disabled on touch
   * (see @media (hover: none) above), so this is belt-and-braces. */
  .hf-lift { transition: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .hf-fadeup, .hf-reveal, .hf-focuspull, .hf-dot-snap {
    transition: none !important;
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .hf-pulse, .hf-marquee-track, .hf-404-bignum {
    animation: none !important;
  }
  html.ready, html.ready body {
    transition: none !important;
  }
}
