/* ==========================================================================
   Homepage — "Noise → One Card", Field Manual edition
   Sits on top of styles.css (tokens, type, buttons, cards). Everything here is
   either static layout that reads fine without JS, or state JS opts into via
   classes on <html>:
     .js          JS is running (set inline in <head>)
     .intro       intro cover is up (removed by home.js; CSS failsafe at 2.4s)
     .motion      GSAP + Lenis are running (not under reduced motion)
     .has-stage   the WebGL stage mounted and owns the hero + fold visuals
     .has-cursor  fine pointer: custom cursor is on
   ========================================================================== */

:root {
  /* The one curve every animation on this page uses (GSAP registers the same as "icc"). */
  --ease-icc: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-micro: 400ms;
  --dur-section: 900ms;
}

/* ---------- Night bands: the same tokens, re-pointed at the dark palette ---------- */
.night {
  --paper: var(--night);
  --paper-raised: var(--night-raised);
  --paper-sunk: var(--night-raised);
  --ink: var(--night-ink);
  --graphite: var(--night-dim);
  --rule: var(--night-rule);
  --rule-strong: #4f625e;
  --dash: 1px dashed var(--night-rule);
  background: var(--night);
  color: var(--ink);
}
/* Full-bleed background for a band that sits inside .wrap */
.night-band {
  box-shadow: 0 0 0 100vmax var(--night);
  clip-path: inset(0 -100vmax);
  border-bottom: 0;
}

/* ---------- Lenis (smooth scroll) ---------- */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

/* ---------- Intro ---------- */
/* Cover painted before first frame so the intro never flashes the page underneath. */
html.intro::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--night);
  animation: intro-failsafe 1ms 2.4s forwards;
}
@keyframes intro-failsafe { to { visibility: hidden; } }

.intro-screen {
  position: fixed;
  inset: 0;
  z-index: 201;
  display: grid;
  place-items: center;
  background: var(--night);
  color: var(--night-ink);
  cursor: pointer;
}
.intro-line {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--night-dim);
  white-space: pre;
}
.intro-line b { color: var(--night-ink); font-weight: 500; }
.intro-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 0 rgb(255 106 77 / 0.3);
}
.intro-skip {
  position: absolute;
  bottom: var(--s-5);
  left: 50%;
  transform: translateX(-50%);
  color: var(--night-dim);
}

/* ---------- WebGL stage ---------- */
.stage {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
}
.has-stage .stage { opacity: 1; }
.has-stage .stage.is-off { opacity: 0; transition: opacity var(--dur-section) var(--ease-icc); }
.log, .footer { position: relative; z-index: 1; }
/* Once WebGL paints the night (and the glass), the CSS night and fallback glass fade away. */
.hero-night { transition: background-color 800ms var(--ease-icc); }
.has-stage .hero-night { background-color: transparent; }
.hero-visual > * { transition: opacity var(--dur-section) var(--ease-icc); }
.has-stage .hero-visual > * { opacity: 0; }

/* ---------- Custom cursor (fine pointers only) ---------- */
.cursor, .cursor-ring {
  position: fixed;
  top: 0; left: 0;
  z-index: 300;
  pointer-events: none;
  border-radius: 50%;
  display: none;
  mix-blend-mode: difference; /* reads on night and paper alike */
}
.has-cursor .cursor, .has-cursor .cursor-ring { display: block; }
.has-cursor, .has-cursor * { cursor: none !important; }
.cursor {
  width: 6px; height: 6px;
  margin: -3px 0 0 -3px;
  background: #fff;
}
.cursor-ring {
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border: 1px solid rgb(255 255 255 / 0.6);
  transition:
    width var(--dur-micro) var(--ease-icc), height var(--dur-micro) var(--ease-icc),
    margin var(--dur-micro) var(--ease-icc), border-color var(--dur-micro) var(--ease-icc),
    background-color var(--dur-micro) var(--ease-icc), opacity var(--dur-micro) var(--ease-icc),
    border-radius var(--dur-micro) var(--ease-icc);
}
/* Hovering a link: the ring opens around it. */
.cursor-ring.is-link {
  width: 52px; height: 52px;
  margin: -26px 0 0 -26px;
  border-color: #fff;
}
/* Hovering a button: the ring squares off, like the blocks. */
.cursor-ring.is-cta {
  width: 14px; height: 14px;
  margin: -7px 0 0 -7px;
  border-radius: 0;
  border-color: #fff;
  background: #fff;
}
.cursor-ring.is-hidden, .cursor.is-hidden { opacity: 0; }

/* ---------- Nav: floats over the night hero, turns to paper below it ---------- */
.home .nav {
  position: fixed;
  left: 0; right: 0;
}
.js .home .nav:not(.is-solid) {
  background: color-mix(in srgb, var(--night) 72%, transparent);
  color: var(--night-ink);
  border-bottom-color: var(--night-rule);
  --paper-sunk: rgb(255 255 255 / 0.12);
  --graphite: var(--night-dim);
}
.js .home .nav:not(.is-solid) .btn { --btn-bg: var(--night-ink); --btn-fg: var(--night); }
.js .home .nav:not(.is-solid) .btn:hover { --btn-bg: var(--signal); --btn-fg: #fff; }
.nav-clock { display: none; }
@media (min-width: 1060px) {
  .motion .nav-clock { display: inline-flex; align-items: center; gap: 6px; margin-right: var(--s-2); }
  .nav-clock b { color: inherit; }
  .nav-clock::before {
    content: "";
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--signal);
    transition: background-color var(--dur-micro) var(--ease-icc);
  }
  .nav-clock.is-ok::before { background: var(--mint); }
}

/* Rail dots light up as each entry becomes the live one. */
.entry-stamp::before { transition: background-color var(--dur-micro) var(--ease-icc), border-color var(--dur-micro) var(--ease-icc), box-shadow var(--dur-micro) var(--ease-icc); }
.motion .entry-stamp.is-live::before { background: var(--ink); border-color: var(--ink); }
.motion .entry-stamp.is-ok.is-live::before { background: var(--mint); border-color: var(--mint); box-shadow: 0 0 0 4px rgb(69 196 160 / 0.2); }

/* ---------- Night hero ---------- */
.hero-night {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-top: calc(var(--nav-h) + var(--s-7));
  overflow: hidden;
}
.hero-night .hero { flex: 1; align-items: center; padding-bottom: var(--s-7); }
.hero-kicker { display: inline-flex; align-items: center; gap: var(--s-2); margin-bottom: var(--s-4); color: var(--night-dim); }
.hero-kicker b { color: var(--night-ink); }
.live-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 0 0 rgb(255 106 77 / 0.5);
  animation: live 1.8s var(--ease-icc) infinite;
}
@keyframes live { 70%, 100% { box-shadow: 0 0 0 10px rgb(255 106 77 / 0); } }
.hero-night h1 {
  font-size: clamp(2.125rem, 1.2rem + 2.7vw, 4.5rem);
  /* glow on the rendered text (text-shadow would be clipped by the line masks) */
  filter: drop-shadow(0 0 14px rgb(233 239 237 / 0.3));
}
.hero-night h1 em { color: var(--night-dim); }
.hero-night .hero-lede { color: var(--night-dim); }
.hero-night .hero-lede strong { color: var(--night-ink); }

/* Fallback glass (no WebGL): a frosted pane with a signal streak running behind it. */
.hero-visual { position: relative; min-height: 300px; }
@media (min-width: 1060px) { .hero-visual { min-height: 480px; } }
.glass {
  position: absolute;
  left: 50%; top: 50%;
  width: min(280px, 64vw);
  aspect-ratio: 4 / 5;
  padding: 36px 28px;
  transform: translate(-50%, -50%) perspective(900px) rotateY(-18deg) rotateZ(-8deg);
  border-radius: 18px;
  border: 1px solid rgb(255 255 255 / 0.28);
  background: linear-gradient(140deg, rgb(255 255 255 / 0.18), rgb(255 255 255 / 0.03) 45%, rgb(255 255 255 / 0.09));
  box-shadow: inset 0 0 48px rgb(255 255 255 / 0.07), 0 40px 80px -30px rgb(0 0 0 / 0.7);
  backdrop-filter: blur(4px) saturate(1.5);
  -webkit-backdrop-filter: blur(4px) saturate(1.5);
}
.glass-line { display: block; height: 7px; margin-top: 14px; border-radius: 4px; background: rgb(233 239 237 / 0.35); }
.glass-line:first-child { width: 46%; margin-top: 0; background: rgb(233 239 237 / 0.6); }
.glass-line.is-short { width: 62%; }
.glass-streak {
  position: absolute;
  left: -40%; right: -40%;
  top: 50%;
  height: 5px;
  transform: rotate(-7deg);
  background: linear-gradient(90deg, transparent, var(--signal) 32%, #ffb15c 48%, rgb(255 255 255 / 0.85) 54%, #ffb15c 60%, transparent 85%);
  filter: blur(1.5px);
  box-shadow: 0 0 28px 8px rgb(255 106 77 / 0.28);
}

/* Ticker */
.ticker {
  position: relative;
  border-top: 1px dashed var(--night-rule);
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--night-ink);
  -webkit-mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.ticker-track {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  width: max-content;
  padding-block: var(--s-3);
  animation: ticker 48s linear infinite;
}
.ticker-track i { font-style: normal; color: var(--signal); }
.ticker:hover .ticker-track { animation-play-state: paused; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* ---------- Noise: a statement with inline pills, then the numbers ---------- */
.noise-body { max-width: 56rem; position: relative; }
.pill-text {
  margin-top: var(--s-5);
  max-width: 52rem;
  font-size: clamp(1rem, 0.85rem + 0.6vw, 1.375rem);
  line-height: 2.15;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.pill-text .pill { margin-inline: 0.1em; }

.tally {
  list-style: none;
  margin: var(--s-7) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: var(--dash);
  border-bottom: var(--dash);
}
@media (min-width: 900px) { .tally { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.tally li {
  position: relative;
  display: grid;
  align-content: start;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-4);
  border-left: var(--dash);
}
.tally li:last-child { border-right: var(--dash); }
@media (max-width: 899px) {
  .tally li:nth-child(2) { border-right: var(--dash); }
  .tally li:nth-child(n + 3) { border-top: var(--dash); }
}
/* crosshairs where the cell lines meet the frame */
@media (min-width: 900px) {
  .tally li + li::after {
    --plus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0v24M0 12h24' stroke='%23000' stroke-width='1.2'/%3E%3C/svg%3E");
    content: "";
    position: absolute;
    left: -12px; top: -12px; bottom: -12px;
    width: 24px;
    background: var(--ink);
    -webkit-mask: var(--plus) top / 24px no-repeat, var(--plus) bottom / 24px no-repeat;
            mask: var(--plus) top / 24px no-repeat, var(--plus) bottom / 24px no-repeat;
    pointer-events: none;
  }
}
.tally b {
  font-family: var(--font-display);
  font-stretch: 125%;
  font-weight: 300;
  font-size: clamp(2.25rem, 1.8rem + 1.8vw, 3.25rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tally span { font-size: var(--fs-label); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--graphite); }
.tally li:nth-child(3) b { color: var(--signal); }
.tally .is-answer b { color: var(--ok); }
.tally-note { margin-top: var(--s-4); }

/* ---------- Fold (signature) ---------- */
.fold-grid {
  display: grid;
  gap: var(--s-6);
  align-items: center;
}
@media (min-width: 1060px) {
  .fold-grid { grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr); gap: var(--s-7); }
}
.fold .section-head h2 { font-size: clamp(1.5rem, 1rem + 1.5vw, 2.125rem); }
.fold .pinned { margin-top: var(--s-4); }

/* The pushpin on the card. Position/angle default to the 3D pin's resting pose;
   when WebGL runs, home.js sets them from the projected 3D pin so the hand-off is exact. */
.pin {
  position: absolute;
  left: var(--pin-x, 50%);
  top: var(--pin-y, 16px);
  width: 0; height: 0;
  z-index: 2;
}
.pin-needle {
  position: absolute;
  left: 0; top: -1px;
  width: var(--needle, 15px);
  height: 2px;
  border-radius: 1px;
  background: linear-gradient(90deg, #d4d4d4, #8f8f8f);
  transform-origin: 0 50%;
  transform: rotate(var(--needle-angle, 120deg));
}
.pin-head {
  position: absolute;
  left: calc(var(--pin-r, 11px) * -1);
  top: calc(var(--pin-r, 11px) * -1);
  width: calc(var(--pin-r, 11px) * 2);
  height: calc(var(--pin-r, 11px) * 2);
  border-radius: 50%;
  background:
    radial-gradient(circle at 34% 30%, rgb(255 255 255 / 0.55) 0 10%, transparent 26%),
    radial-gradient(circle at 40% 35%, color-mix(in srgb, var(--signal) 80%, white) 0%, var(--signal) 45%, color-mix(in srgb, var(--signal) 65%, black) 100%);
  box-shadow: 4px 6px 7px -2px rgb(0 0 0 / 0.35);
}

/* ---------- How it works ---------- */
.how-head { display: grid; gap: var(--s-6); align-items: center; }
@media (min-width: 1060px) { .how-head { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); } }
.orbit { width: 100%; max-width: 360px; height: auto; justify-self: center; overflow: visible; }
.orbit ellipse { fill: none; stroke: var(--rule-strong); stroke-width: 0.75; stroke-dasharray: 2 3; }
.orbit circle { fill: var(--mint); }
.orbit circle.is-hot { fill: var(--signal); }
.orbit text { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.08em; fill: var(--graphite); text-transform: uppercase; }

.term::before, .term::after { content: "|"; color: var(--signal); }
.term::before { margin-right: 0.15em; }
[aria-hidden="true"] > .term:not(.is-typed)::before, [aria-hidden="true"] > .term:not(.is-typed)::after { visibility: hidden; }
.term::after { margin-left: 0.15em; }
.typed-caret {
  display: inline-block;
  width: 0.55em; height: 1.1em;
  margin-left: 2px;
  vertical-align: -0.2em;
  background: var(--ink);
  animation: blink 900ms steps(1) infinite;
}

.tags { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: var(--s-3) 0 0; padding: 0; }
.tags li {
  padding: 2px 10px;
  border: 1px solid var(--ink);
  border-radius: var(--pill);
  font-size: 0.6875rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.line { transition: background-color var(--dur-micro) var(--ease-icc); }
@media (hover: hover) { .line:hover { background: color-mix(in srgb, var(--paper-sunk) 55%, transparent); } }

/* Example messages sit in a dashed drafting frame */
.frame { border: var(--dash); padding: 8px; background: var(--paper-sunk); }

.dupe {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  color: var(--signal);
}
.dupe .who { margin: 0; }
.dupe-target {
  padding: 2px var(--s-2);
  border: 1px dashed var(--signal);
  background: var(--signal-wash);
}

.excerpt { transition: transform var(--dur-micro) var(--ease-icc), box-shadow var(--dur-micro) var(--ease-icc); }
@media (hover: hover) {
  .frame:hover .excerpt { transform: translate(-3px, -3px); box-shadow: 3px 3px 0 var(--ink); }
}

/* Body links draw a solid underline over the dashed one on hover. */
@media (hover: hover) {
  .motion main a:not(.btn) {
    text-decoration: none;
    background: linear-gradient(currentColor, currentColor) no-repeat 0 100% / 0% 1px,
                repeating-linear-gradient(90deg, var(--rule-strong) 0 3px, transparent 3px 6px) 0 100% / 100% 1px no-repeat;
    transition: background-size var(--dur-micro) var(--ease-icc);
  }
  .motion main a:not(.btn):hover { background-size: 100% 1px, 100% 1px; }
}

/* ---------- Boundaries: "Doesn't" items are struck, like the old hypothesis ---------- */
.checklist li > span { justify-self: start; }
.checklist .doesnt li span {
  background: linear-gradient(var(--signal), var(--signal)) no-repeat 0 58% / var(--strike, 100%) 1.5px;
}

/* ---------- Closing (night band) ---------- */
.closing-copy { position: relative; }
.night-band h2 { filter: drop-shadow(0 0 14px rgb(233 239 237 / 0.25)); }
.resolved-stamp {
  display: inline-block;
  margin-bottom: var(--s-4);
  padding: 6px 12px;
  border: 1.5px solid var(--mint);
  color: var(--mint);
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  transform: rotate(-4deg);
}
.btn-lg { min-height: 64px; font-size: var(--fs-body); }
.btn-lg > .btn-label { padding: 0 var(--s-6); }
.btn-lg > span[aria-hidden="true"] { width: 64px; }
.night-band .notice[data-state="success"] { background: rgb(69 196 160 / 0.12); }

/* Arrow block: the arrow slides through on hover */
.btn > span[aria-hidden="true"] { position: relative; }
@media (hover: hover) {
  .motion .btn:hover > span[aria-hidden="true"] { animation: arrow-through 500ms var(--ease-icc); }
}
@keyframes arrow-through { 0% { text-indent: 0; } 49% { text-indent: 60px; } 50% { text-indent: -60px; } 100% { text-indent: 0; } }

/* Magnetic targets are moved by transform. */
.motion [data-magnetic]:active { transform: none; }

/* ---------- Headline fill: letters go from rule-grey to ink as you scroll ---------- */
.fill-char { color: var(--rule-strong); transition: color 250ms var(--ease-icc); }
.fill-char.is-on { color: var(--ink); }
em .fill-char.is-on { color: var(--graphite); }

/* ---------- Reveals (GSAP-era timing for the classes styles.css already uses) ---------- */
.motion .reveal {
  transform: translateY(24px);
  transition: opacity var(--dur-section) var(--ease-icc), transform var(--dur-section) var(--ease-icc);
}
.motion .reveal.is-in { transform: none; }

/* SplitText line masks shouldn't clip descenders. */
/* word masks clip descenders and the glow without a little room below */
.split-word-mask { padding-bottom: 0.08em; margin-bottom: -0.08em; }
/* Split chars are inline-blocks, which the browser may wrap between; keep each word whole. */
.split-word { white-space: nowrap; }

/* ---------- Reduced motion: content, no choreography ---------- */
@media (prefers-reduced-motion: reduce) {
  html.intro::after { display: none; }
  .intro-screen, .stage, .cursor, .cursor-ring { display: none !important; }
  .has-cursor, .has-cursor * { cursor: auto !important; }
  .ticker-track { animation: none; }
  .live-dot { animation: none; }
}
