/* ==========================================================================
   base.css — reset, fonts, tokens, type scale, shared components.

   The default (:root) tokens are the Home world: the Oh! graphite frame.
   Every value is traceable to the apps (see NOTES-source-analysis.md):
   graphite/paper/LED come from ohasynth.css; the product swatches from each
   app's own palette. Product pages re-skin via html[data-page] overrides in
   their own stylesheet — same variables, different world.
   ========================================================================== */

/* ---- fonts (self-hosted, SIL OFL — see assets/fonts/FONTS-LICENSES.txt) -- */
@font-face {
  font-family: 'Archivo';
  src: url('../assets/fonts/Archivo-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Archivo';
  src: url('../assets/fonts/Archivo-Variable-Italic.woff2') format('woff2');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: italic;
  font-display: swap;
}

/* ---- tokens -------------------------------------------------------------- */
:root {
  /* Home world (graphite frame) */
  --bg: #141416;            /* ohasynth.css body background */
  --surface: #232327;       /* ohasynth --panel-2 */
  --surface-2: #2b2b30;     /* ohasynth --panel */
  --rule: #38383e;          /* ohasynth section border */
  --paper: #ece5d5;         /* ohasynth --cream */
  --muted: #b9b2a2;         /* ohasynth --cream-dim */
  --accent: #ff5a3c;        /* ohasynth --led */
  --accent-ink: #141416;    /* text on accent fills */
  --swatch-synth: #c8413b;  /* ohasynth --red */
  --swatch-comber: #4ade80; /* Comber --green */

  --font-display: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-body: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --stretch-display: 125%;
  --stretch-body: 100%;

  /* fluid type scale — deliberate jumps, not eight shades of medium */
  --step--1: clamp(0.79rem, 0.75rem + 0.2vw, 0.89rem);
  --step-0: clamp(0.95rem, 0.9rem + 0.25vw, 1.06rem);
  --step-1: clamp(1.19rem, 1.1rem + 0.45vw, 1.42rem);
  --step-2: clamp(1.66rem, 1.45rem + 1vw, 2.25rem);
  --step-3: clamp(2.3rem, 1.9rem + 2vw, 3.55rem);
  --step-4: clamp(3.2rem, 2.4rem + 4vw, 5.6rem);

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 2rem;
  --space-4: 3.5rem;
  --space-5: 6rem;

  --radius: 6px;            /* ohasynth section radius */
  --measure: 62ch;
  --container: 68rem;
}

/* ---- reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--paper);
  font-family: var(--font-body);
  font-stretch: var(--stretch-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

main { flex: 1; }

img, video, svg { max-width: 100%; height: auto; display: block; }

a { color: inherit; text-underline-offset: 0.2em; }
a:hover { color: var(--accent); }

h1, h2, h3 {
  font-family: var(--font-display);
  font-stretch: var(--stretch-display);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
h3 { font-size: var(--step-1); }

p { max-width: var(--measure); }

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

/* Keyboard focus is always visible, on every world. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--space-2);
  top: -4rem;
  z-index: 100;
  background: var(--accent);
  color: var(--accent-ink);
  padding: 0.5em 1em;
  border-radius: var(--radius);
  transition: top 0.15s ease-out;
}
.skip-link:focus { top: var(--space-2); color: var(--accent-ink); }

/* ---- layout primitives ----------------------------------------------------- */
.container {
  width: min(100% - 2 * var(--space-2), var(--container));
  margin-inline: auto;
}

.section { padding-block: var(--space-5); }
.section + .section { padding-block-start: 0; }

.kicker {
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.prose > * + * { margin-block-start: var(--space-2); }

/* ---- header / nav ----------------------------------------------------------- */
.site-header {
  border-bottom: 1px solid var(--rule);
  background: var(--bg);
}
.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: var(--space-2);
  flex-wrap: wrap;
}
.brand {
  font-family: var(--font-display);
  font-stretch: var(--stretch-display);
  font-weight: 900;
  font-size: var(--step-1);
  letter-spacing: -0.02em;
  text-decoration: none;
}
.brand:hover { color: var(--paper); }
.brand .bang { color: var(--accent); }

.site-header nav ul {
  display: flex;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  flex-wrap: wrap;
}
.site-header nav a {
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.35em 0;
}
.site-header nav a:hover { color: var(--paper); }
.site-header nav a[aria-current="page"] {
  color: var(--paper);
  box-shadow: 0 2px 0 0 var(--accent);
}

.nav-toggle {
  border: 1px solid var(--rule);
  background: var(--surface);
  color: var(--paper);
  font: inherit;
  font-size: var(--step--1);
  letter-spacing: 0.08em;
  padding: 0.4em 0.9em;
  border-radius: var(--radius);
  cursor: pointer;
}

@media (max-width: 40rem) {
  .site-header nav {
    flex-basis: 100%;
  }
  /* JS-off: menu simply stays visible. JS unhides .nav-toggle and collapses. */
  .site-header:has(.nav-toggle:not([hidden])) nav { display: none; }
  .site-header.nav-open nav { display: block; }
  .site-header nav ul { flex-direction: column; gap: var(--space-1); padding-block: var(--space-1); }
}
@media (min-width: 40.01rem) {
  .nav-toggle { display: none; }
}

/* ---- footer ------------------------------------------------------------------ */
.site-footer {
  border-top: 1px solid var(--rule);
  margin-block-start: var(--space-5);
  padding-block: var(--space-4);
  color: var(--muted);
  font-size: var(--step--1);
}
.site-footer .container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  justify-content: space-between;
}
.site-footer ul {
  list-style: none;
  display: flex;
  gap: var(--space-2);
  padding: 0;
  flex-wrap: wrap;
}
.site-footer a { color: var(--muted); }
.site-footer a:hover { color: var(--paper); }

/* ---- buttons ------------------------------------------------------------------ */
.btn {
  display: inline-block;
  background: var(--accent);
  color: var(--accent-ink);
  border: 1px solid transparent;
  border-radius: var(--radius);
  font: inherit;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 0.7em 1.4em;
  text-decoration: none;
  cursor: pointer;
}
.btn:hover { filter: brightness(1.08); color: var(--accent-ink); }
.btn:active { transform: translateY(1px); }

.btn-ghost {
  background: transparent;
  color: var(--paper);
  /* --rule is a hairline divider tone (1.58:1) — too faint to be a control
     boundary. --muted clears the 3:1 non-text-contrast floor in every world. */
  border-color: var(--muted);
}
.btn-ghost:hover { border-color: var(--paper); filter: none; }

/* ---- email capture -------------------------------------------------------------- */
.capture form { max-width: 30rem; }
.capture .form-row {
  display: flex;
  gap: var(--space-1);
  flex-wrap: wrap;
}
.capture label {
  display: block;
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.06em;
  margin-block-end: var(--space-1);
}
.capture input[type="email"] {
  flex: 1 1 14rem;
  font: inherit;
  color: var(--paper);
  background: var(--surface);
  /* --muted keeps the field boundary above the 3:1 non-text-contrast floor
     in every world (see NOTES §4 palettes) */
  border: 1px solid var(--muted);
  border-radius: var(--radius);
  padding: 0.65em 0.9em;
}
.capture input[type="email"]::placeholder { color: var(--muted); }
.capture input[type="email"]:disabled { opacity: 0.6; }

.form-status {
  display: block;
  min-height: 1.5em;
  margin-block-start: var(--space-1);
  font-size: var(--step--1);
}
.form-status[data-state="invalid"],
.form-status[data-state="error"] { color: var(--accent); font-weight: 600; }
.form-status[data-state="submitting"] { color: var(--muted); }
.form-status[data-state="success"] { color: var(--paper); font-weight: 600; }

.form-fallback { color: var(--muted); }
.form-fallback a { color: var(--paper); font-weight: 600; }

/* ---- media slots (§8: labeled placeholders at real filenames) -------------------- */
figure.media-slot {
  position: relative;
  margin: 0;
}
.media-slot .frame {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.media-slot .frame > img,
.media-slot .frame > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.media-slot .frame.ar-16x9 { aspect-ratio: 16 / 9; }
.media-slot .frame.ar-16x10 { aspect-ratio: 16 / 10; }
/* iPad captures with the iOS status bar cropped off: 2752x1988. Using the
   real ratio means nothing is cut off inside the frame. */
.media-slot .frame.ar-chord { aspect-ratio: 2752 / 1988; }
.media-slot figcaption {
  font-size: var(--step--1);
  color: var(--muted);
  padding-block-start: var(--space-1);
}
.media-pause {
  position: absolute;
  right: 0.75rem;
  bottom: 0.75rem;
  z-index: 2;
  border: 1px solid var(--rule);
  background: var(--bg);
  color: var(--paper);
  font: inherit;
  font-size: var(--step--1);
  line-height: 1;
  padding: 0.5em 0.7em;
  border-radius: var(--radius);
  cursor: pointer;
  opacity: 0.85;
}
.media-pause:hover { opacity: 1; }

/* ---- product-page shared skeleton -------------------------------------------------- */
.hero { padding-block: var(--space-5) var(--space-4); }
.hero .positioning {
  font-size: var(--step-1);
  color: var(--muted);
  margin-block: var(--space-2) var(--space-3);
  max-width: 46ch;
}

.feature {
  display: grid;
  gap: var(--space-3);
  align-items: center;
  padding-block: var(--space-4);
}
@media (min-width: 52rem) {
  .feature { grid-template-columns: 1fr 1fr; }
  .feature:nth-of-type(even) .feature-copy { order: 2; }
}
.feature h3 {
  font-size: var(--step--1);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-weight: 700;
  padding-block-end: var(--space-1);
  border-bottom: 2px solid var(--accent);
  display: inline-block;
}
.feature .what { margin-block: var(--space-2) var(--space-1); }
.feature .why { color: var(--muted); }

/* spec sheet — an equipment table, not a pricing grid */
.spec-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--step--1);
}
.spec-table caption { text-align: left; }
.spec-table th[scope="row"] {
  text-align: left;
  vertical-align: top;
  white-space: nowrap;
  padding: 0.65em 1.5em 0.65em 0;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  width: 1%;
}
.spec-table td { padding: 0.65em 0; }
.spec-table tr { border-bottom: 1px solid var(--rule); }
.spec-wrap { overflow-x: auto; }

/* FAQ */
.faq details {
  border-bottom: 1px solid var(--rule);
  padding-block: var(--space-2);
}
.faq summary {
  cursor: pointer;
  font-weight: 700;
  font-size: var(--step-1);
  font-family: var(--font-display);
  font-stretch: var(--stretch-display);
  letter-spacing: -0.01em;
  list-style-position: outside;
}
.faq summary:hover { color: var(--accent); }
.faq details p { margin-block-start: var(--space-2); color: var(--muted); }

.cta-repeat { text-align: center; }
.cta-repeat p { margin-inline: auto; }
.cta-repeat .btn { margin-block-start: var(--space-2); }

/* ---- custom cursors (js/cursor.js) — (pointer: fine) only, see §7 ------------------- */
html.cursor-hidden,
html.cursor-hidden * { cursor: none !important; }

.cursor {
  position: fixed;
  left: 0; top: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0;
}
.cursor-crosshair { width: 0; height: 0; }
.cursor-crosshair::before,
.cursor-crosshair::after {
  content: "";
  position: absolute;
  background: var(--paper);
}
.cursor-crosshair::before { left: -11px; top: -0.5px; width: 22px; height: 1px; }
.cursor-crosshair::after { left: -0.5px; top: -11px; width: 1px; height: 22px; }
.cursor-crosshair {
  outline: 1px solid color-mix(in srgb, var(--paper) 45%, transparent);
  outline-offset: 6px;
  border-radius: 50%;
}

.cursor-caret {
  width: 0.62em;
  height: 1.15em;
  margin: -0.55em 0 0 -0.3em;
  background: #4ade80;
  box-shadow: 0 0 10px rgba(74, 222, 128, 0.55);
  animation: caret-blink 1.06s steps(1) infinite;
}
.cursor-trail {
  position: fixed;
  left: 0; top: 0;
  z-index: 9998;
  pointer-events: none;
  width: 0.62em;
  height: 1.15em;
  margin: -0.55em 0 0 -0.3em;
  background: #4ade80;
  opacity: 0;
}
.cursor-trail.fade { animation: trail-fade 0.35s ease-out forwards; }
@keyframes caret-blink { 50% { opacity: 0.25; } }
@keyframes trail-fade { from { opacity: 0.35; } to { opacity: 0; } }

/* ---- reduced motion: the one global kill switch (§7) -------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- App Store call to action ------------------------------------------------ */
/* Apple's official "Download on the App Store" badge (assets/img/app-store-badge.svg,
   fetched from Apple's App Store Marketing Tools and self-hosted — nothing loads
   from Apple at runtime). Per Apple's marketing guidelines the artwork is used
   unmodified: no recolouring, no filters, no rotation, no rounded corners of our
   own. Only its size changes, and it scales proportionally.

   Sizing: 48px tall, comfortably above Apple's 40px minimum. Clear space is kept
   at >= 1/4 the badge height on every side, which the flex gap and margin below
   satisfy. */
.appstore-badge {
  display: inline-block;
  line-height: 0;            /* no descender gap under the image */
  border-radius: 8px;        /* matches the artwork, so focus ring hugs it */
}
.appstore-badge img {
  height: 48px;
  width: auto;
}
.appstore-badge:focus-visible { outline-offset: 4px; }
.cta-pair,
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  max-width: none;
}
.hero-actions { margin-block-start: var(--space-3); }
.product-block .cta-pair { margin-block-end: 0; }
