/* =========================================================
   Ambix homepage — the counter after close
   ---------------------------------------------------------
   Near-black, and the product screens are the only light in
   the room.

   That inversion is the whole design. A dark product on a flat
   dark ground disappears — which is why the dark hero treatment
   was rejected the first time. A dark product LIGHTING a dark
   room does the opposite: the screens become the brightest
   objects on the page and everything else falls away from them.

   So: no filled blocks, no outlined boxes, no offset shadows.
   Depth is glow, haze, hairlines and perspective. Anything that
   reads as a sticker on paper is wrong here.

   Every colour pair is checked as a real computation by
   landingDesignSystem.test.ts.
   ========================================================= */

/* ── Type ─────────────────────────────────────────────────
   One self-hosted face plus the system monospace, which costs
   zero bytes and does the "terminal" work a display serif was
   doing badly. font-src is 'self', so a Google Fonts URL here
   would be blocked by CSP and the page would silently fall back
   to the stack.
   ───────────────────────────────────────────────────────── */
@font-face {
  font-family: "Inter";
  src: url("fonts/Inter.woff2") format("woff2");
  font-weight: 400 700;
  font-display: swap;
}

:root {
  /* The room. */
  --void:     oklch(11% 0.008 60);
  --void-2:   oklch(13% 0.008 60);
  --panel:    oklch(16% 0.008 60);
  --panel-2:  oklch(20% 0.009 60);

  /* Edges are light at low alpha, never a drawn border colour. */
  --edge:     oklch(100% 0 0 / 0.09);
  --edge-hot: oklch(100% 0 0 / 0.2);

  --text:       oklch(95% 0.008 75);
  --text-dim:   oklch(74% 0.012 70);
  --text-faint: oklch(62% 0.012 70);

  /* The light. --amber is what you read; --amber-fill is what
     you put dark text ON; --amber-deep is for haze and glow,
     always with alpha. They are not interchangeable. */
  --amber:      oklch(80% 0.15 72);
  --amber-fill: oklch(74% 0.15 70);
  --amber-deep: oklch(58% 0.14 66);
  --on-amber:   oklch(14% 0.02 60);

  --font-text: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --step--1: clamp(0.82rem, 0.8rem + 0.1vw, 0.9rem);
  --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.08rem);
  --step-1: clamp(1.12rem, 1.05rem + 0.35vw, 1.3rem);
  --step-2: clamp(1.5rem, 1.3rem + 0.9vw, 2.1rem);
  --step-3: clamp(1.9rem, 1.5rem + 1.7vw, 2.9rem);
  --step-4: clamp(2.4rem, 1.7rem + 3.1vw, 4.2rem);

  --space-section: clamp(4.5rem, 3rem + 5vw, 8.5rem);
  --radius: 10px;
  --radius-sm: 6px;
  --duration: 300ms;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

*,
*::before,
*::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--void);
  color: var(--text);
  font-family: var(--font-text);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* A single grain plate over the whole page. Fixed, so it does not
   scroll with the content and never tiles visibly. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  opacity: 0.22;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.5'/></svg>");
}

h1, h2, h3 {
  font-family: var(--font-text);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.03em;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); letter-spacing: -0.02em; }

p { margin: 0 0 1em; }

a { color: var(--amber); text-underline-offset: 3px; }

/* ── Layout primitives ────────────────────────────────────── */
.wrap {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
}

.section { padding-block: var(--space-section); }

/* The mono kicker is the page's tech signal. It appears above
   every section and carries the amber. */
.kicker {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber);
  margin: 0 0 16px;
}

.head {
  max-width: 46ch;
  margin-bottom: clamp(2.5rem, 2rem + 2vw, 4rem);
  padding-top: 1.75rem;
  border-top: 1px solid var(--edge);
}

.head h2 { margin-bottom: 0; }

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-dim);
  max-width: 56ch;
}

/* ── Screens ──────────────────────────────────────────────
   A screen is a lit object: a hairline bezel, a black body and
   a glow that spills onto whatever is behind it.
   ───────────────────────────────────────────────────────── */
.screen {
  position: relative;
  background: #000;
  border: 1px solid var(--edge-hot);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow:
    0 0 0 1px oklch(0% 0 0 / 0.6),
    0 40px 90px -30px oklch(0% 0 0 / 0.9),
    0 0 100px -30px oklch(80% 0.15 72 / 0.28);
}

.screen img,
.screen video {
  display: block;
  width: 100%;
  height: auto;
}

.clip {
  display: block;
  width: 100%;
  height: auto;
  background: #000;
}

/* ── Controls ─────────────────────────────────────────────── */
.btn-primary,
.btn-quiet {
  display: inline-block;
  font-family: var(--font-text);
  font-weight: 600;
  font-size: var(--step-0);
  padding: 13px 26px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: transform var(--duration) var(--ease),
              box-shadow var(--duration) var(--ease),
              background-color var(--duration) var(--ease),
              border-color var(--duration) var(--ease),
              color var(--duration) var(--ease);
}

.btn-primary {
  background: var(--amber-fill);
  color: var(--on-amber);
  box-shadow: 0 0 40px -12px oklch(80% 0.15 72 / 0.7);
}

.btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 60px -10px oklch(80% 0.15 72 / 0.9);
}

.btn-quiet {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--edge-hot);
  padding: 12px 25px;
}

.btn-quiet:hover {
  border-color: var(--amber);
  color: var(--amber);
}

.btn-primary:focus-visible,
.btn-quiet:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
}

/* ── Motion ───────────────────────────────────────────────
   Compositor-friendly properties only, and all of it off for a
   visitor who asked for less. video.js, reveal.js and scene.js
   each make the same check before doing anything at all.
   ───────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Scroll reveal ────────────────────────────────────────
   FAIL-OPEN. Nothing is hidden by this stylesheet alone — the
   rule is scoped to [data-reveal-active], an attribute only
   reveal.js sets, and only after it has confirmed it can finish
   the job. No script, old browser, reduced motion: everything is
   simply visible.
   ───────────────────────────────────────────────────────── */
[data-reveal-active] [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
}

[data-reveal-active] [data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 600ms var(--ease), transform 600ms var(--ease);
}

/* ── Header ───────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: oklch(11% 0.008 60 / 0.72);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--edge);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  max-width: 1200px;
  margin: 0 auto;
  padding: 12px 24px;
}

.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.18em;
  color: var(--text);
  text-decoration: none;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 28px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--step--1);
}

.nav-links a {
  color: var(--text-dim);
  text-decoration: none;
  transition: color var(--duration) var(--ease);
}

.nav-links a:hover,
.nav-links a:focus-visible { color: var(--text); }

.nav-links .btn-primary { color: var(--on-amber); }

.btn-sm {
  padding: 9px 18px;
  font-size: var(--step--1);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: 0;
  padding: 8px;
  cursor: pointer;
}

.nav-toggle span {
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--text);
}

/* =========================================================
   HERO — the staged counter
   ========================================================= */
.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: clamp(620px, 90vh, 920px);
  display: flex;
  align-items: center;
  background:
    radial-gradient(70% 55% at 62% 42%, oklch(58% 0.14 66 / 0.13) 0%, transparent 70%),
    linear-gradient(180deg, oklch(13% 0.008 60) 0%, var(--void) 62%, oklch(9% 0.008 60) 100%);
}

/* ── The stage ────────────────────────────────────────────
   A fixed box with a definite aspect on desktop, because the
   markers are positioned as PERCENTAGES of it. If the stage can
   change shape independently of the scene, the markers drift off
   the objects they label.
   ───────────────────────────────────────────────────────── */
.stage {
  position: absolute;
  inset: 0 0 0 32%;
  z-index: 1;
  perspective: 1500px;
  perspective-origin: 48% 44%;
}

/* The scrim lives INSIDE the stage, between the scene and the markers.
   As a child of .hero it covered the markers too and dimmed the one
   control the hero exists for. It only has to darken the strip the copy
   overlaps — roughly the left quarter of the stage — not the whole thing. */
.stage::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(90deg,
    var(--void) 0%,
    oklch(11% 0.008 60 / 0.86) 11%,
    oklch(11% 0.008 60 / 0.3) 22%,
    transparent 34%);
}

.scene {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  /* scene.js writes these. The defaults are the composition you
     get with no script at all, so it must look right at 0,0. */
  transform:
    translateY(var(--sy, 0px))
    rotateX(var(--rx, 0deg))
    rotateY(var(--ry, 0deg));
  transition: transform 380ms var(--ease);
  will-change: transform;
}

/* The counter surface: a plane laid down in Z with a grid on it
   and a pool of amber where the screens are pointing. */
.floor {
  position: absolute;
  left: -40%;
  right: -40%;
  bottom: -34%;
  height: 120%;
  transform-origin: 50% 100%;
  transform: rotateX(76deg);
  background:
    radial-gradient(38% 40% at 46% 34%, oklch(70% 0.15 70 / 0.3) 0%, transparent 72%),
    linear-gradient(oklch(100% 0 0 / 0.055) 1px, transparent 1px),
    linear-gradient(90deg, oklch(100% 0 0 / 0.055) 1px, transparent 1px);
  background-size: auto, 62px 62px, 62px 62px;
  -webkit-mask-image: radial-gradient(58% 62% at 50% 34%, #000 0%, transparent 80%);
  mask-image: radial-gradient(58% 62% at 50% 34%, #000 0%, transparent 80%);
}

/* The back bar: bottles as silhouettes, rim-lit and mostly gone.
   Deliberately abstract — drawn bottles would put the page back
   into illustration. */
.rack {
  position: absolute;
  top: 5%;
  left: 2%;
  right: 2%;
  height: 24%;
  display: flex;
  align-items: flex-end;
  gap: 2.2%;
  transform: translateZ(-420px);
  filter: blur(2.5px);
  opacity: 0.55;
}

.rack span {
  flex: 1;
  background: linear-gradient(180deg, oklch(24% 0.02 60) 0%, oklch(13% 0.01 60) 100%);
  border-left: 1px solid oklch(70% 0.14 70 / 0.35);
  border-radius: 40% 40% 4px 4px / 18% 18% 4px 4px;
}

.rack span:nth-child(odd)  { height: 78%; }
.rack span:nth-child(3n)   { height: 92%; }
.rack span:nth-child(4n)   { height: 66%; }

.obj { position: absolute; }

.obj video,
.obj img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 6px;
}

/* Nexus: furthest back, turned away, dimmest. */
.obj-nexus {
  top: 17%;
  right: 4%;
  width: 41%;
  transform: translateZ(-190px) rotateY(-22deg) rotateX(4deg);
  border-radius: 8px;
  overflow: hidden;
  background: #000;
  border: 1px solid var(--edge);
  box-shadow:
    0 30px 70px -24px #000,
    0 0 70px -24px oklch(80% 0.15 72 / 0.24);
}

/* Distance haze. Without it the portal's light interface, sitting furthest
   back, was the brightest thing in the room and pulled the eye off Station. */
.obj-nexus::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(200deg,
    oklch(11% 0.008 60 / 0.34) 0%,
    oklch(11% 0.008 60 / 0.6) 100%);
}

.panel-chrome {
  display: flex;
  gap: 5px;
  padding: 7px 9px;
  background: oklch(18% 0.008 60);
  border-bottom: 1px solid var(--edge);
}

.panel-chrome i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: oklch(38% 0.01 60);
}

/* The printer. A prop: it should read as a shape in the dark, not
   as an object anyone is meant to look at. */
.obj-printer {
  bottom: 27%;
  left: 20%;
  width: 15%;
  height: 7%;
  transform: translateZ(-40px) rotateX(58deg) rotateY(-16deg);
  background: linear-gradient(180deg, oklch(20% 0.008 60), oklch(12% 0.008 60));
  border-radius: 4px 4px 2px 2px;
  box-shadow: 0 14px 30px -12px #000;
}

.obj-printer .slot {
  position: absolute;
  left: 12%;
  right: 12%;
  top: 26%;
  height: 2px;
  background: oklch(70% 0.14 70 / 0.45);
  border-radius: 2px;
}

/* Station, on the dock. The brightest object on the page. */
.obj-ipad {
  top: 24%;
  left: 12%;
  width: 53%;
  transform: translateZ(70px) rotateY(-15deg) rotateX(6deg);
  border-radius: 10px;
  background: #000;
  padding: 6px;
  border: 1px solid var(--edge-hot);
  box-shadow:
    0 40px 90px -26px #000,
    0 0 130px -18px oklch(80% 0.15 72 / 0.4);
}

.obj-ipad .dock {
  position: absolute;
  left: 22%;
  right: 22%;
  bottom: -13%;
  height: 13%;
  background: linear-gradient(180deg, oklch(19% 0.008 60), oklch(11% 0.008 60));
  border-radius: 3px;
  transform: rotateX(64deg);
  transform-origin: 50% 0;
  box-shadow: 0 10px 40px -10px oklch(80% 0.15 72 / 0.35);
}

/* Daisho, face up on the counter. The steep rotateX is what makes
   it read as lying down rather than standing up. */
.obj-iphone {
  bottom: 4%;
  right: 15%;
  width: 15%;
  transform: translateZ(150px) rotateX(66deg) rotateY(-12deg) rotateZ(7deg);
  border-radius: 10px;
  background: #000;
  padding: 4px;
  border: 1px solid var(--edge-hot);
  box-shadow:
    0 26px 50px -14px #000,
    0 0 90px -16px oklch(80% 0.15 72 / 0.42);
}

/* ── Markers ──────────────────────────────────────────────
   <details> on purpose: they open with no script at all, they are
   keyboard reachable for free, and a phone gets them on tap rather
   than on a hover it cannot perform.

   ⚠️ The overlay is a SIBLING of .stage, not a child, and it is
   deliberately positioned to the same box. Two reasons:

     - inside the scene's preserve-3d subtree a card gets clipped
       and z-fights for no benefit; and
     - `.stage` sets `perspective`, which makes it the containing
       block for any fixed-position descendant. A card inside it
       could never be pinned to the VIEWPORT, only to the stage —
       which on a phone put it below the fold and made a tap look
       like it had done nothing.

   The inset here must track `.stage`'s. If one moves, both move.
   ───────────────────────────────────────────────────────── */
.spots {
  position: absolute;
  inset: 0 0 0 32%;
  z-index: 5;
  pointer-events: none;
}

.spot { position: absolute; }

.spot-station { top: 47%; left: 33%; }
.spot-daisho  { top: 80%; left: 79%; }
.spot-nexus   { top: 22%; left: 84%; }
.spot-counter { top: 88%; left: 38%; }

.spot summary {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  list-style: none;
  cursor: pointer;
  pointer-events: auto;
  padding: 5px 12px 5px 5px;
  border-radius: 999px;
  background: oklch(11% 0.008 60 / 0.6);
  border: 1px solid var(--edge);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: border-color var(--duration) var(--ease),
              color var(--duration) var(--ease);
}

.spot summary::-webkit-details-marker { display: none; }

.spot summary:hover,
.spot summary:focus-visible,
.spot[open] summary {
  color: var(--text);
  border-color: var(--amber);
}

.spot summary:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
}

.node {
  position: relative;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 14px 2px oklch(80% 0.15 72 / 0.8);
  flex: none;
}

/* The ping. It is the only thing on the page that loops forever,
   which is exactly why it is small. */
.node::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--amber);
  animation: ping 2.6s var(--ease) infinite;
}

@keyframes ping {
  0%   { opacity: 0.9; transform: scale(0.6); }
  70%  { opacity: 0;   transform: scale(1.5); }
  100% { opacity: 0;   transform: scale(1.5); }
}

.spot[open] .node::after { animation: none; opacity: 0; }

.spot-card {
  position: absolute;
  top: -10px;
  left: calc(100% + 14px);
  width: min(320px, 62vw);
  pointer-events: auto;
  padding: 20px 22px;
  background: oklch(13% 0.008 60 / 0.9);
  border: 1px solid var(--edge-hot);
  border-radius: var(--radius);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  box-shadow: 0 30px 70px -24px #000;
}

/* Cards on the right-hand markers open leftwards, or they leave
   the stage entirely. */
.spot-daisho .spot-card,
.spot-nexus .spot-card {
  left: auto;
  right: calc(100% + 14px);
}

.spot-daisho .spot-card { top: auto; bottom: -10px; }

.spot-kicker {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--amber);
  margin: 0 0 8px;
}

.spot-card h2 {
  font-size: var(--step-1);
  margin: 0 0 8px;
}

.spot-card p:last-child {
  margin: 0;
  color: var(--text-dim);
  font-size: var(--step--1);
  line-height: 1.6;
}

/* ── Hero copy ────────────────────────────────────────────
   Sits over the darkest part of the room, with a scrim so the
   scene can never cost it legibility.
   ───────────────────────────────────────────────────────── */
/* ⚠️ POINTER-EVENTS IS LOAD-BEARING. .hero-copy is a full-width block sitting
   above the stage. Left solid, its empty right-hand half swallowed every click
   aimed at a marker, and the markers — the entire point of the hero — were
   unreachable while looking perfectly normal. Only a real click in a browser
   catches that; nothing about the page renders wrongly. */
.hero-copy {
  position: relative;
  z-index: 4;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 24px;
  width: 100%;
  pointer-events: none;
}

.hero-copy a,
.hero-copy button { pointer-events: auto; }

.hero-copy > * { max-width: 30ch; }
.hero-copy .lede { max-width: 42ch; }

/* The measure is for prose only. Inside 30ch the mono kicker and the hint
   both wrapped onto a second line and looked like a mistake. */
.hero-copy .kicker,
.hero-copy .hero-hint { max-width: none; }

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 4px;
  max-width: none;
}

.hero-hint {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 30px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.pulse {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 10px 1px oklch(80% 0.15 72 / 0.8);
  animation: breathe 2.6s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

/* ── Ticker ───────────────────────────────────────────────── */
.ticker {
  overflow: hidden;
  padding-block: 18px;
  background: var(--void-2);
  border-block: 1px solid var(--edge);
}

.ticker-track {
  display: flex;
  align-items: center;
  gap: 24px;
  width: max-content;
  font-family: var(--font-mono);
  font-size: clamp(0.8rem, 0.72rem + 0.4vw, 1rem);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
  animation: ticker 52s linear infinite;
}

.ticker-track i {
  color: var(--amber);
  font-style: normal;
}

/* The track holds the list twice, so -50% lands exactly on the copy. */
@keyframes ticker {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

/* ── What it does: the sticky invoice sequence ────────────
   `.flow` must never gain an overflow value — sticky dies inside
   a scroll container and does so silently.
   ───────────────────────────────────────────────────────── */
.flow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 1rem + 4vw, 4.5rem);
  align-items: start;
}

.flow-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2.5rem, 2rem + 4vw, 5.5rem);
}

.flow-steps li {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}

/* ⚠️ The heading and paragraphs MUST stay inside .flow-body. As
   direct children of the <li> they are grid items in their own
   right, and auto-placement wraps the paragraph into the 58px
   NUMBER column — one word per line. That shipped once. */
.flow-body > :first-child { margin-top: 0; }
.flow-steps li > :not(.flow-n) { grid-column: 2; }

.flow-n {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.1em;
  color: var(--amber);
  padding-top: 6px;
  border-top: 1px solid var(--amber);
}

.flow-steps h3 { margin: 0 0 0.5rem; }

.flow-steps p {
  color: var(--text-dim);
  margin: 0 0 0.8em;
  max-width: 46ch;
}

.note {
  font-size: var(--step--1);
  color: var(--text-faint);
  border-left: 1px solid var(--edge-hot);
  padding-left: 14px;
  max-width: 44ch;
}

.flow-media {
  position: sticky;
  top: 96px;
}

/* ── Capabilities ─────────────────────────────────────────
   Panels, not cards. A hairline and a lift on hover — nothing
   that reads as a sticker sitting on paper.
   ───────────────────────────────────────────────────────── */
.capabilities { background: var(--void-2); border-block: 1px solid var(--edge); }

.bento {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.cell {
  position: relative;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: clamp(1.4rem, 1.1rem + 1vw, 2.1rem);
  transition: border-color var(--duration) var(--ease),
              background-color var(--duration) var(--ease),
              transform var(--duration) var(--ease);
}

.cell::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(70% 90% at 50% 0%, oklch(80% 0.15 72 / 0.12), transparent 70%);
  transition: opacity var(--duration) var(--ease);
}

.cell:hover {
  transform: translateY(-3px);
  border-color: var(--edge-hot);
  background: var(--panel-2);
}

.cell:hover::before { opacity: 1; }

.cell-index {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--text-faint);
  margin: 0 0 14px;
}

.cell h3 { margin-bottom: 0.5rem; }

.cell p { margin: 0; color: var(--text-dim); }

.cell-feature {
  grid-column: span 2;
  grid-row: span 2;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.cell-feature h3 { font-size: var(--step-2); }

.cell-wide { grid-column: span 2; }

/* One cell carries the light, so the grid has a subject. */
.cell-amber {
  background:
    linear-gradient(140deg, oklch(58% 0.14 66 / 0.22) 0%, transparent 60%),
    var(--panel);
  border-color: oklch(80% 0.15 72 / 0.35);
}

.cell-amber .cell-index { color: var(--amber); }
.cell-amber:hover { border-color: var(--amber); }

/* ── Guardian ─────────────────────────────────────────────
   The Guardian dashboard is itself dark, with amber charts, so it
   sits in this room as a lit panel rather than as a white
   rectangle punched into the page.
   ───────────────────────────────────────────────────────── */
.guardian {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.guardian-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(46% 50% at 78% 40%, oklch(58% 0.14 66 / 0.22) 0%, transparent 70%),
    linear-gradient(oklch(100% 0 0 / 0.04) 1px, transparent 1px),
    linear-gradient(90deg, oklch(100% 0 0 / 0.04) 1px, transparent 1px);
  background-size: auto, 70px 70px, 70px 70px;
  -webkit-mask-image: radial-gradient(72% 66% at 62% 40%, #000 0%, transparent 78%);
  mask-image: radial-gradient(72% 66% at 62% 40%, #000 0%, transparent 78%);
}

.guardian-grid {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.7fr);
  gap: clamp(2rem, 1rem + 4vw, 5rem);
  align-items: center;
}

.guardian h2 { font-size: var(--step-4); max-width: 16ch; }

.screen-portrait {
  max-width: 320px;
  margin-inline: auto;
}

.link-more {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--amber);
  text-decoration: none;
  padding-bottom: 4px;
  border-bottom: 1px solid oklch(80% 0.15 72 / 0.4);
  transition: border-color var(--duration) var(--ease);
}

.link-more:hover { border-color: var(--amber); }

/* ── Founder ──────────────────────────────────────────────── */
.founder-inner { max-width: 68ch; }

.pull {
  margin: 0 0 1.4rem;
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.03;
  letter-spacing: -0.035em;
  max-width: 16ch;
}

.pull p { margin: 0; }

/* ── Questions ────────────────────────────────────────────── */
.faq { background: var(--void-2); border-block: 1px solid var(--edge); }

.faq-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr);
  gap: clamp(2rem, 1rem + 4vw, 5rem);
  align-items: start;
}

.faq-head { position: sticky; top: 96px; }

.faq-aside {
  color: var(--text-faint);
  font-size: var(--step--1);
  max-width: 32ch;
}

.faq-item {
  border-top: 1px solid var(--edge);
  padding: 2px 0;
}

.faq-item:last-child { border-bottom: 1px solid var(--edge); }

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  cursor: pointer;
  list-style: none;
  padding: 20px 0;
  font-size: var(--step-1);
  font-weight: 600;
  letter-spacing: -0.02em;
  transition: color var(--duration) var(--ease);
}

.faq-item summary::-webkit-details-marker { display: none; }

.faq-item summary:hover { color: var(--amber); }

.faq-item summary::after {
  content: "+";
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--edge-hot);
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 1rem;
  line-height: 1;
  color: var(--text-dim);
  transition: transform var(--duration) var(--ease),
              border-color var(--duration) var(--ease),
              color var(--duration) var(--ease);
}

.faq-item[open] summary::after {
  content: "\2212";
  transform: rotate(180deg);
  border-color: var(--amber);
  color: var(--amber);
}

.faq-item summary:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 3px;
}

.faq-item p {
  color: var(--text-dim);
  max-width: 62ch;
  margin: 0 0 20px;
}

/* ── Pricing ──────────────────────────────────────────────── */
.pricing {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.pricing-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(52% 70% at 22% 50%, oklch(58% 0.14 66 / 0.26) 0%, transparent 72%);
}

.pricing-inner {
  position: relative;
  z-index: 2;
  max-width: 62ch;
}

.pricing h2 { font-size: var(--step-4); max-width: 18ch; }

/* ── Demo form ────────────────────────────────────────────── */
.demo { border-top: 1px solid var(--edge); }

.demo-inner { max-width: 62ch; }

.demo-form {
  display: grid;
  gap: 12px;
  margin-top: 2rem;
  max-width: 26rem;
}

.demo-form input {
  font: inherit;
  font-size: var(--step-0);
  padding: 14px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--edge-hot);
  background: var(--panel);
  color: var(--text);
  transition: border-color var(--duration) var(--ease);
}

.demo-form input::placeholder { color: var(--text-faint); }

.demo-form input:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
  border-color: transparent;
}

/* Without this the button fills the form column and its glow
   reads as a stray bar rather than a button. */
.btn-submit { justify-self: start; }

/* The honeypot must be in the DOM and reachable — display:none lets some bots
   skip it — but never visible and never focusable. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.form-error { color: oklch(76% 0.16 28); margin: 0; }

.form-success p {
  margin: 2rem 0 0;
  font-size: var(--step-1);
}

.hidden { display: none; }

/* ── Footer ───────────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--edge);
  padding-block: 3rem;
  background: oklch(9% 0.008 60);
}

.footer-inner {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 40px;
  align-items: flex-start;
  justify-content: space-between;
}

.footer-brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.18em;
  color: var(--text-dim);
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  font-size: var(--step--1);
}

.footer-links a {
  color: var(--text-faint);
  text-decoration: none;
  transition: color var(--duration) var(--ease);
}

.footer-links a:hover,
.footer-links a:focus-visible { color: var(--amber); }

.footer-legal {
  font-size: var(--step--1);
  color: var(--text-faint);
  margin: 0;
  line-height: 1.7;
}

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (max-width: 1180px) {
  .spot-card { width: min(280px, 54vw); }
}

@media (max-width: 1080px) {
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cell-feature { grid-row: span 1; }
}

/* ── The stage stops being a backdrop and becomes a block ──
   Below this width there is no room beside the copy, so the
   scene moves under it. The markers keep their percentages,
   which is why the stage gets a fixed aspect ratio here.
   ───────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  /* The stage comes FIRST in the markup because it is absolutely positioned
     on desktop, where source order is irrelevant. Once it becomes a block in
     the flow, that order puts the scene above the headline — the visitor meets
     a room before being told what it is. Flex order fixes it without moving
     the markup, which would change nothing on desktop and break the stacking
     there. */
  .hero {
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding-top: clamp(2.5rem, 2rem + 3vw, 4rem);
  }

  .hero-copy { order: -1; }

  .stage::before { display: none; }

  .hero-copy > *,
  .hero-copy .lede { max-width: none; }

  .stage {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 4 / 3;
    margin-top: 2.5rem;
  }

  .flow,
  .guardian-grid,
  .faq-grid { grid-template-columns: minmax(0, 1fr); }

  /* Sticky in a single column pins a screen over the text below it. */
  .flow-media,
  .faq-head { position: static; }

  .guardian h2 { max-width: none; }

  /* The overlay stops being an overlay. Pinning a 320px card beside a marker
     needs 320px beside it, and a 390px stage has nowhere to put one; docking
     it over the scene covers the object it describes. So the markers become a
     row of chips under the counter and the open card expands in place — the
     same information, laid out for a thumb.

     This is why the markers had to leave `.stage`: an aspect-ratio box cannot
     also be a flow container for a list of chips. */
  .spots {
    position: static;
    inset: auto;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 1.5rem;
    /* The scene is deliberately full-bleed; the chips are content and line up
       with the copy above them. */
    padding-inline: 24px;
    pointer-events: auto;
  }

  .spot { position: static; }

  /* The open one takes a full row so its card has the width; the rest wrap
     around it. */
  .spot[open] { width: 100%; }

  .spot-card,
  .spot-daisho .spot-card,
  .spot-nexus .spot-card {
    position: static;
    width: auto;
    margin-top: 10px;
  }
}

@media (max-width: 720px) {
  .nav-toggle { display: flex; }

  .nav-links {
    display: none;
    width: 100%;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 16px 0 6px;
  }

  /* The menu is revealed by home.js, which THIS page loads. */
  .nav-links.open { display: flex; }

  .nav { flex-wrap: wrap; }

  .bento { grid-template-columns: minmax(0, 1fr); }
  .cell-feature,
  .cell-wide { grid-column: span 1; }

  /* Plain block flow. Keeping the grid here put the number and the
     text in the same cell, and the numeral sat on its own heading. */
  .flow-steps li { display: block; }
  .flow-steps li > :not(.flow-n) { grid-column: auto; }

  .flow-n {
    display: inline-block;
    margin-bottom: 1rem;
  }

  /* Below 900px the markers are chips in a row rather than dots on objects,
     so the labels are the whole affordance and must stay.
     The padding is for the target, not the look: at the desktop size these
     chips measured 28px tall, well under the 44px a thumb needs. */
  .spot summary {
    font-size: 10px;
    padding: 10px 14px 10px 10px;
  }
}
