/* ═══════════════════════════════════════════════════════════════════════════
  CONISTRA — emotional landing variant (index-emotional.html)
  Standalone: does not share style.css so the dark-first cinematic treatment
  can't be dragged around by the light marketing theme.

  Design rules from docs/landing-page-conversion-2026.md:
    · one primary CTA verb ("Start my page"), everything else quiet
    · full-bleed original imagery, never stock
    · scroll storytelling via transform/opacity only, reduced-motion honoured
    · headline + CTA visible above the fold at 390px
    · LCP image is the hero feed's first thumb; everything else lazy
  ═══════════════════════════════════════════════════════════════════════════ */

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

:root {
  /* Signal gradient — brand core */
  --grad-start: #ff2f8e;
  --grad-mid:   #ff5a5f;
  --grad-end:   #f9820c;
  --signal:     linear-gradient(120deg, #ff2f8e 0%, #ff5a5f 50%, #f9820c 100%);
  --pink:       #ff4f98;
  --solar:      #f97316;

  /* Night palette — warm blacks, not blue-blacks */
  --night:      #0c0b0a;
  --night-2:    #131110;
  --night-3:    #1b1917;
  --night-line: rgba(255, 245, 235, .10);
  --on-night:   #f4f0ea;
  --on-night-2: rgba(244, 240, 234, .66);
  --on-night-3: rgba(244, 240, 234, .40);

  /* Day palette — warm canvas, matches the app shell */
  --canvas:     #f6f4ef;
  --canvas-2:   #efe9df;
  --ink:        #1b1a17;
  --ink-2:      #57534c;
  --ink-3:      #8b857b;
  --line:       #e1d9cd;

  --mono: 'Space Mono', ui-monospace, Menlo, monospace;
  --sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --gut: clamp(20px, 5vw, 56px);
  --maxw: 1240px;
}

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.62;
  color: var(--on-night);
  background: var(--night);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ol, ul { list-style: none; }
::selection { background: var(--pink); color: #fff; }

/* ── Shared type ─────────────────────────────────────────────────────── */

.eyebrow {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--on-night-3);
  margin-bottom: 22px;
}
.eyebrow-dark { color: var(--ink-3); }

.h2 {
  font-size: clamp(2rem, 4.4vw, 3.5rem);
  line-height: 1.04;
  letter-spacing: -.035em;
  font-weight: 700;
  margin-bottom: 26px;
}
.h2-dark { color: var(--ink); }
.h2 .dim { color: var(--on-night-3); }

.signal {
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.lede {
  font-size: clamp(1.05rem, 2.1vw, 1.28rem);
  color: var(--on-night-2);
  max-width: 62ch;
  margin-bottom: 8px;
}
.lede-dark { color: var(--ink-2); }

.prose p { color: var(--on-night-2); max-width: 54ch; margin-bottom: 18px; }
.prose .prose-hit {
  color: var(--on-night);
  font-size: clamp(1.15rem, 2.4vw, 1.45rem);
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: 1.35;
  margin-top: 26px;
}

.callout {
  margin-top: 34px;
  padding: 20px 24px;
  border-left: 2px solid transparent;
  border-image: var(--signal) 1;
  background: rgba(255, 79, 152, .05);
  color: var(--on-night-2);
  font-size: 1rem;
  max-width: 58ch;
}
.callout strong { color: var(--on-night); font-weight: 600; }
.callout-fomo { background: rgba(249, 130, 12, .06); }

/* ── Buttons — one signal button, everything else recedes ────────────── */

.btn-signal, .btn-quiet, .btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--sans);
  font-weight: 600;
  letter-spacing: -.01em;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background .18s ease, border-color .18s ease;
  white-space: nowrap;
}

.btn-signal {
  background: var(--signal);
  color: #fff;
  box-shadow: 0 10px 30px rgba(255, 79, 152, .26);
}
.btn-signal:hover { transform: translateY(-2px); box-shadow: 0 16px 40px rgba(255, 79, 152, .34); }
.btn-arrow { transition: transform .18s ease; }
.btn-signal:hover .btn-arrow { transform: translateX(4px); }

.btn-quiet {
  background: rgba(244, 240, 234, .06);
  border-color: var(--night-line);
  color: var(--on-night);
}
.btn-quiet:hover { background: rgba(244, 240, 234, .11); border-color: rgba(244, 240, 234, .22); }

.btn-ghost { color: var(--on-night-2); }
.btn-ghost:hover { color: var(--on-night); }

.btn-sm { padding: 9px 17px; font-size: .9rem; }
.btn-lg { padding: 15px 30px; font-size: 1.03rem; }
.btn-xl { padding: 19px 42px; font-size: 1.12rem; }

.link-arrow {
  color: var(--solar);
  font-weight: 600;
  border-bottom: 1px solid rgba(249, 115, 22, .3);
}
.link-arrow:hover { border-bottom-color: var(--solar); }

/* ── Nav ─────────────────────────────────────────────────────────────── */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  transition: background .3s ease, border-color .3s ease, backdrop-filter .3s ease;
  border-bottom: 1px solid transparent;
}
.nav.solid {
  background: rgba(12, 11, 10, .82);
  backdrop-filter: saturate(160%) blur(16px);
  -webkit-backdrop-filter: saturate(160%) blur(16px);
  border-bottom-color: var(--night-line);
}
.nav-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 16px var(--gut);
  display: flex;
  align-items: center;
  gap: 32px;
}
.nav-logo { display: flex; align-items: center; gap: 10px; }
.brand-mark { width: 26px; height: 26px; flex: none; }
.wordmark {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 1.02rem;
  letter-spacing: -.02em;
}
.nav-links { display: flex; gap: 26px; margin-left: auto; }
.nav-links a {
  font-size: .93rem;
  color: var(--on-night-2);
  transition: color .16s ease;
}
.nav-links a:hover { color: var(--on-night); }
.nav-cta { display: flex; align-items: center; gap: 12px; }

/* ── Hero ────────────────────────────────────────────────────────────── */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 120px 0 72px;
  overflow: hidden;
  background:
    radial-gradient(900px 620px at 82% 22%, rgba(255, 47, 142, .13), transparent 70%),
    radial-gradient(700px 520px at 8% 78%, rgba(249, 130, 12, .10), transparent 70%),
    var(--night);
}
.hero-grid {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gut);
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1.14fr) minmax(0, .86fr);
  gap: clamp(32px, 4vw, 60px);
  align-items: center;
}

.hero-h1 {
  font-size: clamp(2.5rem, 4.9vw, 4.1rem);
  line-height: .99;
  letter-spacing: -.045em;
  font-weight: 700;
  margin-bottom: 26px;
}
.hero-h1 em {
  font-style: normal;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.hero-answer {
  font-size: clamp(1.05rem, 2vw, 1.22rem);
  color: var(--on-night-2);
  max-width: 50ch;
  margin-bottom: 34px;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
.hero-fine {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .04em;
  color: var(--on-night-3);
}

.hero-proof {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  margin-top: 38px;
  padding-top: 28px;
  border-top: 1px solid var(--night-line);
}
.pstat { display: flex; align-items: baseline; gap: 11px; }
.pnum {
  font-family: var(--mono);
  font-size: 1.65rem;
  font-weight: 700;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.plabel {
  font-size: .74rem;
  line-height: 1.3;
  color: var(--on-night-3);
  text-transform: uppercase;
  letter-spacing: .06em;
}

/* The feed that fills itself — two columns drifting apart */
.hero-feed {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  /* Taller than the old photo wall: a post card is image + counts + caption, and
     the window has to show whole posts for the feed illusion to hold. */
  height: min(84svh, 780px);
  overflow: hidden;
  mask-image: linear-gradient(to bottom, transparent, #000 14%, #000 84%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 14%, #000 84%, transparent);
}
.feed-col { display: flex; flex-direction: column; gap: 14px; will-change: transform; }

/* Each frame is a post, not a picture — image, counts, head of the caption.
   The card carries the border and radius that used to sit on the bare <img>. */
.fpost {
  background: var(--night-3);
  border: 1px solid rgba(255, 245, 235, .14);
  border-radius: 14px;
  overflow: hidden;
  flex: none;
  box-shadow: 0 18px 40px rgba(0, 0, 0, .45);
}
.fpost img {
  width: 100%;
  /* height:auto is load-bearing, not boilerplate. The width/height attributes on
     these <img>s land as presentational hints, so height resolves to 600px on its
     own — and aspect-ratio only fills in a *missing* dimension, so it loses. The
     result was every card rendering 221x600 squashed. */
  height: auto;
  /* Square and 4:5 are the two ratios Instagram actually posts in, so the cards
     read as posts and stay short enough that whole ones drift past rather than
     fragments. Mood frames go square, centre-cropped — they are scenery, so the
     middle is the picture. */
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
/* Idea frames keep the taller 4:5 and crop from the bottom, which costs them the
   burned-in handle — affordable only here, because the card prints @handle on its
   own caption line right underneath. Anchored to the top so the headline, which
   is the whole idea, is never the thing that gets shaved. The uncropped 2:3
   originals still run at full height in .posts-rail. */
.fpost-tall img {
  aspect-ratio: 4 / 5;
  object-position: top;
}
.fpost-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px 0;
}
.fpost-stat { display: inline-flex; align-items: center; gap: 4px; }
.fpost-stat svg {
  width: 12px;
  height: 12px;
  flex: none;
  color: var(--on-night-3);
}
.fpost-like svg { color: var(--pink); }
.fpost-stat > span {
  font-family: var(--mono);
  font-size: .61rem;
  letter-spacing: .01em;
  color: var(--on-night-2);
}
.fpost-cap {
  padding: 6px 10px 10px;
  font-size: .66rem;
  line-height: 1.42;
  color: var(--on-night-3);
  /* Two lines then ellipsis — a caption "beginning", the way a feed truncates.
     max-height is the fallback: line-clamp needs the -webkit-box display type,
     which is exactly the kind of thing that quietly stops applying, and without a
     hard cap a caption that runs long silently makes its card taller than its
     twin in the duplicated half — which desynchronises the loop. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  max-height: 2.84em;
  overflow: hidden;
}
.fpost-cap b { color: var(--on-night-2); font-weight: 600; }
.feed-up   { animation: drift-up 78s linear infinite; }
.feed-down { animation: drift-up 92s linear infinite reverse; }
@keyframes drift-up {
  from { transform: translateY(0); }
  to   { transform: translateY(-50%); }
}

.hero-scrollcue {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--on-night-3);
}
.hero-scrollcue i {
  width: 1px;
  height: 30px;
  background: linear-gradient(to bottom, var(--on-night-3), transparent);
  animation: cue 2.4s ease-in-out infinite;
}
@keyframes cue { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

/* ── Section shells ──────────────────────────────────────────────────── */

.sec { padding: clamp(80px, 11vw, 150px) 0; position: relative; }
.sec-dark   { background: var(--night-2); }
.sec-night  { background: var(--night); }
.sec-light  { background: #fff; color: var(--ink); }
.sec-canvas { background: var(--canvas); color: var(--ink); }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gut); }
.wrap-narrow { max-width: 820px; }
.wrap-split {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(36px, 6vw, 84px);
  align-items: center;
}
.wrap-split-rev .split-copy { order: 2; }
.wrap-split-rev .split-img  { order: 1; }

.split-img img {
  width: 100%;
  /* Safe today only because these frames carry no width/height attributes; set
     explicitly so adding them later can't silently squash the box. */
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: 18px;
  border: 1px solid var(--night-line);
  box-shadow: 0 40px 90px rgba(0, 0, 0, .55);
}
.split-img-stack {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  align-items: start;
}
.split-img-stack img:nth-child(1) { transform: translateY(-18px) rotate(-1.4deg); }
.split-img-stack img:nth-child(2) { transform: translateY(24px) rotate(1.4deg); }

/* The night-mood frames are shot near-black on purpose. Lifted here so they
   read as a photograph on a dark section instead of an empty rectangle. */
.split-img-moody img { filter: brightness(1.5) contrast(.96) saturate(1.08); }

/* ── The reframe / marquee ───────────────────────────────────────────── */

.sec-reveal { overflow: hidden; }
.sec-reveal .lede { margin-bottom: 52px; }

.marquee {
  overflow: hidden;
  padding: 4px 0;
  mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}
.marquee-track {
  display: flex;
  gap: 18px;
  width: max-content;
  animation: slide 96s linear infinite;
  will-change: transform;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
.marquee figure { width: clamp(160px, 20vw, 232px); flex: none; }
.marquee img {
  width: 100%;
  /* Same guard as .split-img — no attributes on these today, pinned anyway. */
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid var(--night-line);
}
.marquee figcaption {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .05em;
  color: var(--on-night-3);
  margin-top: 10px;
  /* One line always — a wrapping caption pushes its neighbours out of line. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reveal-kicker {
  margin-top: 54px;
  font-size: clamp(1.02rem, 2vw, 1.2rem);
  color: var(--on-night-2);
  max-width: 60ch;
}
.reveal-kicker strong { color: var(--on-night); }

/* ── The proof grid — posts, not wallpaper ───────────────────────────────
   These frames carry burned-in type, so they are never cropped:
   aspect-ratio matches the 2:3 source exactly and object-fit stays contain-
   safe. Two up on desktop keeps the smallest overlay line readable. */

/* The proof rail — horizontal, because sideways a frame costs no scroll.
   This section carries the only argument on the page that isn't "we can make a
   pretty picture", so it holds the most frames. Laid out as a snap rail, the
   fourteenth post costs nothing in page height, and phones get a native swipe
   instead of a fourteen-storey column. */
.posts-rail {
  display: flex;
  gap: 22px;
  margin-top: 40px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  /* Full-bleed rail whose first card still lines up with .wrap's text column.
     Percentage, not 100vw: vw includes the vertical scrollbar and .wrap does
     not, which would offset the first card against the heading above it. max()
     guards the narrow case, where the calc() term goes negative. */
  --rail-inset: max(var(--gut), calc((100% - var(--maxw)) / 2 + var(--gut)));
  padding: 4px var(--rail-inset) 18px;
  scroll-padding-left: var(--rail-inset);
  scrollbar-width: thin;
  scrollbar-color: rgba(244, 240, 234, .22) rgba(244, 240, 234, .06);
}
.posts-rail::-webkit-scrollbar { height: 6px; }
.posts-rail::-webkit-scrollbar-track {
  background: rgba(244, 240, 234, .06);
  border-radius: 99px;
}
.posts-rail::-webkit-scrollbar-thumb {
  background: rgba(244, 240, 234, .22);
  border-radius: 99px;
}
.posts-rail .post-proof {
  flex: 0 0 clamp(255px, 30vw, 330px);
  scroll-snap-align: start;
}
.rail-hint {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--on-night-3);
  margin-top: 26px;
}
.post-proof {
  border-radius: 18px;
  overflow: hidden;
  background: var(--night-2);
  border: 1px solid var(--night-line);
  transition: transform .3s cubic-bezier(.2, .8, .25, 1), box-shadow .3s ease;
}
.post-proof:hover {
  transform: translateY(-6px);
  box-shadow: 0 30px 70px rgba(0, 0, 0, .5);
}
.post-proof img {
  display: block;
  width: 100%;
  /* height:auto is load-bearing. These <img>s carry width/height attributes,
     which land as presentational hints — so height resolved to 1020px on its own,
     aspect-ratio (which only fills in a *missing* dimension) lost, and the box
     became 330x1020. object-fit: cover then cropped horizontally and shaved the
     burned-in headline off every frame in the rail. */
  height: auto;
  aspect-ratio: 2 / 3;
  object-fit: cover;
}
/* Frames whose overlay type sits in the left column: anchor the crop to the
   left edge so a centred crop can never shave the text off. */
.post-proof img.pp-left { object-position: left center; }
.post-proof figcaption { padding: 20px 22px 22px; display: block; }
.post-proof .pp-kind:only-child { margin-bottom: 0; }
.post-proof .pp-kind {
  display: block;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--pink);
  margin-bottom: 8px;
}
.post-proof .pp-what {
  display: block;
  font-size: 1.02rem;
  line-height: 1.45;
  color: var(--on-night-2);
}
.post-proof .pp-what strong { color: var(--on-night); font-weight: 600; }

/* ── Act I — the decay chart ─────────────────────────────────────────── */

.decay {
  margin-top: 40px;
  padding: 24px 26px 20px;
  border: 1px solid var(--night-line);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(255, 255, 255, .03), rgba(255, 255, 255, 0));
  max-width: 520px;
}
.decay-head {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--on-night-3);
  margin-bottom: 20px;
}
.decay-bars { display: flex; align-items: flex-end; gap: 10px; height: 130px; }
.decay-bar {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  height: 100%;
  gap: 8px;
}
.decay-bar i {
  display: block;
  width: 100%;
  height: 0;
  /* Cap so the value + week labels always fit inside the 130px track. */
  max-height: calc(100% - 44px);
  border-radius: 5px 5px 2px 2px;
  background: var(--signal);
  transition: height .9s cubic-bezier(.2, .8, .25, 1);
}
.decay.grown .decay-bar i { height: var(--h); }
.decay-bar:nth-child(2) i { transition-delay: .07s; }
.decay-bar:nth-child(3) i { transition-delay: .14s; }
.decay-bar:nth-child(4) i { transition-delay: .21s; }
.decay-bar:nth-child(5) i { transition-delay: .28s; }
.decay-bar:nth-child(6) i { transition-delay: .35s; }
.decay-bar:nth-child(7) i { transition-delay: .42s; }
.decay-bar:nth-child(8) i { transition-delay: .49s; }
.decay-bar.is-dead i { background: rgba(244, 240, 234, .14); }
.decay-bar span {
  font-family: var(--mono);
  font-size: .62rem;
  letter-spacing: .06em;
  color: var(--on-night-3);
}
/* The count sits above its bar — order:-1 with a bottom-justified column. */
.decay-bar b {
  order: -1;
  font-family: var(--mono);
  font-size: .7rem;
  font-weight: 700;
  color: var(--on-night-2);
}
.decay-bar.is-dead b { color: var(--on-night-3); }


/* ── Act II — "you weren't there" grid ───────────────────────────────── */

/* 3 × 2 on desktop — six cards read as two weeks, not as an odd 4 + 2 row. */
/* ── Act II — three whole pages ───────────────────────────────────────────
   Card width is picked so three sit still inside .wrap on a desktop (3×372 +
   2×22 gap = 1160, under the 1240 max) and the rail only genuinely scrolls once
   the viewport can't hold them. On a phone one card fills the width, which is
   the first time a profile screenshot is actually legible on this page. */
.feed-rail {
  display: flex;
  gap: 22px;
  margin-top: 48px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  --rail-inset: max(var(--gut), calc((100% - var(--maxw)) / 2 + var(--gut)));
  padding: 4px var(--rail-inset) 20px;
  scroll-padding-left: var(--rail-inset);
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}
.feed-rail::-webkit-scrollbar { height: 6px; }
.feed-rail::-webkit-scrollbar-track { background: var(--canvas-2); border-radius: 99px; }
.feed-rail::-webkit-scrollbar-thumb { background: var(--line); border-radius: 99px; }

.feed-card {
  /* 360 max, not 372: the inset is padding on BOTH sides, so at the 1240 cap the
     usable track is 1240 - 2×56 = 1128, and 3×360 + 2×22 = 1124 just fits. At 372
     it overflowed by 32px and the rail grew a phantom scrollbar with nothing
     behind it. */
  flex: 0 0 clamp(264px, 80vw, 360px);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
}
/* The brief sits above the screenshot, so the eye reads input → output. */
.fc-brief {
  font-family: var(--mono);
  font-size: .8rem;
  line-height: 1.5;
  color: var(--ink-2);
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: 12px 12px 0 0;
  border-bottom: none;
  padding: 14px 16px;
  min-height: 72px;
}
.fc-quote { color: var(--pink); font-weight: 700; }
.feed-card img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-bottom: none;
}
.feed-card figcaption {
  padding: 16px 18px 18px;
  border: 1px solid var(--line);
  border-top: none;
  border-radius: 0 0 12px 12px;
  background: #fff;
  flex: 1;
}
.fc-handle {
  display: block;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--solar);
  margin-bottom: 8px;
}
.fc-note {
  display: block;
  font-size: .95rem;
  line-height: 1.5;
  color: var(--ink-2);
}
.fc-note strong { color: var(--ink); font-weight: 700; }

.feed-disclaimer {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: .06em;
  color: var(--ink-3);
  margin-top: 4px;
}

/* The published log — the timestamps without the wallpaper they used to sit on. */
.pub-log {
  margin-top: 46px;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: var(--canvas);
  max-width: 760px;
}
.pub-log-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.pub-log-tag { color: var(--ink-3); }
.pub-log ol { list-style: none; margin: 0; padding: 0; }
.pub-log li {
  display: grid;
  grid-template-columns: 84px 148px 1fr;
  gap: 14px;
  align-items: baseline;
  padding: 13px 20px;
  border-bottom: 1px solid var(--line);
}
.pub-log li:last-child { border-bottom: none; }
.pl-when, .pl-what {
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: .04em;
}
.pl-when { color: var(--ink); font-weight: 700; }
.pl-what { color: var(--solar); text-transform: uppercase; letter-spacing: .07em; }
.turn-kicker {
  margin-top: 48px;
  text-align: center;
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
  letter-spacing: -.025em;
  color: var(--ink-2);
}
.turn-kicker strong { color: var(--ink); font-weight: 700; }

/* ── Act III — steps ─────────────────────────────────────────────────── */

.steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(262px, 1fr));
  gap: 22px;
  margin-top: 52px;
  counter-reset: s;
}
.step {
  padding: 30px 28px 32px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 18px;
}
.step-n {
  font-family: var(--mono);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .12em;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.step h3 {
  font-size: 1.28rem;
  letter-spacing: -.028em;
  margin: 12px 0 10px;
  color: var(--ink);
}
.step p { color: var(--ink-2); font-size: .99rem; }

.steps-note {
  margin-top: 34px;
  color: var(--ink-2);
  max-width: 62ch;
  font-size: 1rem;
}

/* ── Act IV — the arithmetic ─────────────────────────────────────────── */

.ahead-table {
  margin-top: 34px;
  border: 1px solid var(--night-line);
  border-radius: 14px;
  overflow: hidden;
  max-width: 520px;
}
.ahead-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 10px;
  padding: 13px 20px;
  border-bottom: 1px solid var(--night-line);
  font-size: .97rem;
}
.ahead-row.ahead-last { border-bottom: 0; }
.ahead-head {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--on-night-3);
  background: rgba(255, 255, 255, .03);
}
.ahead-row > span:first-child { color: var(--on-night-2); }
.ahead-row > span:nth-child(2) { color: var(--on-night-3); }
.ahead-row b {
  font-weight: 700;
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.ahead-note {
  margin-top: 14px;
  font-size: .88rem;
  color: var(--on-night-3);
  max-width: 52ch;
}
.sec-ahead .btn-signal { margin-top: 32px; }

/* ── The math ────────────────────────────────────────────────────────── */

.math-grid {
  display: grid;
  /* Explicit 2-up: auto-fit would leave a collapsed third track and shrink both. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
  margin-top: 50px;
}
.math-col {
  border: 1px solid var(--line);
  border-radius: 20px;
  background: #fff;
  overflow: hidden;
}
.math-good { border-color: rgba(255, 79, 152, .35); box-shadow: 0 20px 50px rgba(255, 79, 152, .10); }
.math-head { padding: 24px 26px 18px; border-bottom: 1px solid var(--line); }
.math-head strong {
  display: block;
  font-size: 1.2rem;
  letter-spacing: -.028em;
  color: var(--ink);
}
.math-head span {
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.math-rows { padding: 8px 26px 16px; }
.math-rows > div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 11px 0;
  border-bottom: 1px dashed var(--line);
  font-size: .97rem;
  color: var(--ink-2);
}
.math-rows > div:last-child { border-bottom: 0; }
.math-rows > div > span:last-child { color: var(--ink); font-weight: 600; white-space: nowrap; }
.math-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  padding: 18px 26px 22px;
  border-top: 1px solid var(--line);
  background: var(--canvas);
  font-family: var(--mono);
  font-size: .76rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.math-total strong {
  font-family: var(--sans);
  font-size: 1.22rem;
  letter-spacing: -.02em;
  text-transform: none;
  color: var(--ink);
}
.math-good .math-total strong {
  background: var(--signal);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.math-save {
  margin-top: 34px;
  font-size: 1.08rem;
  color: var(--ink-2);
}
.math-save .link-arrow { margin-left: 8px; }

/* ── FAQ ─────────────────────────────────────────────────────────────── */

.faq { margin-top: 44px; border-top: 1px solid var(--line); }
.faq-i { border-bottom: 1px solid var(--line); }
.faq-i summary {
  padding: 22px 40px 22px 0;
  font-size: 1.08rem;
  font-weight: 600;
  letter-spacing: -.022em;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
  position: relative;
}
.faq-i summary::-webkit-details-marker { display: none; }
.faq-i summary::after {
  content: '+';
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--mono);
  font-size: 1.3rem;
  color: var(--solar);
  transition: transform .2s ease;
}
.faq-i[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq-i p { padding: 0 40px 24px 0; color: var(--ink-2); max-width: 68ch; }

/* ── Finale ──────────────────────────────────────────────────────────── */

.finale {
  position: relative;
  min-height: 88svh;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--night);
  text-align: center;
}
.finale-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 38%;
  opacity: .78;
}
.finale::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(64% 56% at 50% 52%, rgba(12, 11, 10, .34), rgba(12, 11, 10, .8)),
    linear-gradient(to bottom, var(--night) 0%, transparent 22%, transparent 78%, var(--night) 100%);
}
.finale-inner {
  position: relative;
  z-index: 1;
  max-width: 780px;
  padding: clamp(90px, 12vw, 150px) var(--gut);
}
.finale-h2 {
  font-size: clamp(2.4rem, 6.4vw, 4.6rem);
  line-height: 1;
  letter-spacing: -.045em;
  font-weight: 700;
  margin-bottom: 24px;
  text-shadow: 0 4px 40px rgba(0, 0, 0, .5);
}
.finale-sub {
  font-size: clamp(1.02rem, 2.1vw, 1.22rem);
  color: rgba(244, 240, 234, .8);
  margin: 0 auto 34px;
  max-width: 52ch;
}
.finale-fine {
  margin-top: 20px;
  font-family: var(--mono);
  font-size: .76rem;
  letter-spacing: .09em;
  color: var(--on-night-3);
}

/* ── Footer ──────────────────────────────────────────────────────────── */

.foot { background: var(--night-2); border-top: 1px solid var(--night-line); }
.foot-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 62px var(--gut) 44px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr);
  gap: 44px;
}
.foot-lockup { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.foot-tag { color: var(--on-night-3); font-size: .93rem; }
.foot-cols { display: flex; flex-wrap: wrap; gap: 44px; }
.foot-col { display: flex; flex-direction: column; gap: 10px; }
.foot-col-t {
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--on-night-3);
  margin-bottom: 4px;
}
.foot-col a { font-size: .93rem; color: var(--on-night-2); transition: color .16s ease; }
.foot-col a:hover { color: var(--on-night); }
.foot-bottom {
  border-top: 1px solid var(--night-line);
  padding: 20px var(--gut);
  text-align: center;
  font-family: var(--mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--on-night-3);
}

/* ── Scroll reveals ──────────────────────────────────────────────────── */

.reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s cubic-bezier(.2, .8, .25, 1), transform .7s cubic-bezier(.2, .8, .25, 1);
}
.reveal.in { opacity: 1; transform: none; }

/* ── Responsive ──────────────────────────────────────────────────────── */

@media (max-width: 1040px) {
  .hero-grid { grid-template-columns: 1fr; gap: 44px; }
  /* Below the split the feed becomes a shallow band under the copy — still two
     columns (there are only two .feed-col children), just shorter. */
  .hero-feed {
    height: 400px;
    mask-image: linear-gradient(to bottom, #000 58%, transparent);
    -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent);
  }
  .wrap-split, .wrap-split-rev { grid-template-columns: 1fr; }
  .wrap-split-rev .split-copy { order: 1; }
  .wrap-split-rev .split-img  { order: 2; }
  .split-img { max-width: 460px; }
  .split-img-stack { max-width: 100%; }
}

@media (max-width: 900px) {
  .math-grid { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  .nav-links { display: none; }
  .nav-cta { margin-left: auto; }
}

@media (max-width: 640px) {
  body { font-size: 16px; }
  .hero { min-height: auto; padding: 104px 0 56px; }
  .hero-feed { height: 300px; gap: 10px; }
  .feed-col { gap: 10px; }
  .hero-scrollcue { display: none; }
  .hero-proof { gap: 18px; }
  .pnum { font-size: 1.35rem; }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn-signal, .hero-actions .btn-quiet { justify-content: center; }
  .decay-bars { height: 100px; }
  .split-img-stack img { transform: none !important; }
  .ahead-row { padding: 12px 14px; font-size: .9rem; }
  .finale { min-height: auto; }
}

/* ── Mobile — fewer frames, no motion ────────────────────────────────────
   Desktop keeps the full gallery. Phones and small tablets keep the frames that
   carry an *idea* (the whole .posts-rail) and lose most of the mood photography,
   which only ever argued "we can make a pretty picture" — the claim this page
   itself calls commodity two sections later.

   This is a real saving, not just hidden markup: every frame cut here is
   loading="lazy", and a lazy image in a display:none subtree never gets a layout
   box, so it never intersects, so the browser never fetches it.

   Both carousels animate to -50%, which assumes the track is exactly twice the
   unique set. So on mobile the animation is killed outright and whole frames are
   dropped — cutting frames out of a still-running loop would visibly jump.

   Net: of 75 image slots, 48 never load on a phone. Of the 27 that remain, 22
   sit in three horizontal strips (the proof rail, the marquee, the feed rail)
   that cost one row of page height each — so the vertical column is 5 frames
   deep: the hero band, Act I's calendar, Act IV's pair, and the finale.
   Placed after the 640px block so these rules win on phones too. */
@media (max-width: 900px) {
  /* Hero: two drifting feeds become one still post. A whole card at its natural
     height beats a 260px sliver of cropped photograph — and since the hero
     stacks copy-then-feed on mobile, this sits below the CTA either way. */
  .hero-feed {
    grid-template-columns: 1fr;
    height: auto;
    overflow: visible;
    mask-image: none;
    -webkit-mask-image: none;
  }
  .feed-col { will-change: auto; }
  .feed-down { display: none; }
  .feed-up .fpost + .fpost { display: none; }
  .feed-up .fpost { max-width: 288px; margin: 0 auto; }
  /* The surviving card is the whole showcase here, so it runs uncropped. The 4:5
     crop exists to keep cards short enough to drift past in a column; with one
     still card that buys nothing, and it would cost this frame the burned-in
     handle and the "1 / 9 — swipe" marker along its bottom edge — half of what it
     is demonstrating. */
  .feed-up .fpost:first-child img { aspect-ratio: 2 / 3; }

  /* Marquee: a still swipe strip of five, not fifteen on a loop. */
  .marquee {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    mask-image: none;
    -webkit-mask-image: none;
    padding: 4px var(--gut);
  }
  .marquee::-webkit-scrollbar { display: none; }
  .marquee-track { width: auto; will-change: auto; }
  .marquee figure { width: clamp(190px, 58vw, 250px); scroll-snap-align: center; }
  .marquee figure:not(.mq-keep) { display: none; }

  /* ── Act IV on a phone ────────────────────────────────────────────────
     Desktop's version of this section is the strongest thing on the page and is
     left untouched. Two things break when it collapses to one column, though.

     First, order: the grid stacks .split-copy then .split-img, which lands the
     photographs *below* the CTA — a dangling tail after the ask. `display:
     contents` dissolves .split-copy so its children and .split-img become
     siblings in one column, and then two order rules are enough to slot the
     frames in after the prose: everything defaults to order 0 and sorts by DOM
     position, so only the four items that belong *after* the images need
     naming. Gap goes to 0 because a 36px+ grid gap between all eight items is
     nothing like the rhythm their own margins already describe.

     Second, the table: three columns squeeze each figure into ~110px and the
     distance between 21 and 360 — the entire argument — stops being legible. So
     each row becomes a block with one line per column and a bar scaled off 360.
     Both frames stay: the pair reads as one object, and one orphan frame here
     looked like a mistake. */
  .wrap-split-rev { gap: 0; }
  .wrap-split-rev .split-copy { display: contents; }
  .wrap-split-rev .split-img { order: 0; margin: 10px 0 6px; }
  .wrap-split-rev .ahead-table,
  .wrap-split-rev .ahead-note,
  .wrap-split-rev .callout,
  .wrap-split-rev .btn-signal { order: 1; }
  /* Blockified by the grid, so it fills the column — a bigger tap target, the
     same thing the hero does with its buttons on mobile. */
  .sec-ahead .btn-signal { justify-content: center; }
  .split-img-stack { gap: 12px; }

  .ahead-table { max-width: 100%; }
  /* Its labels are re-emitted per row below, so the header has nothing to say. */
  .ahead-head { display: none; }
  .ahead-row { grid-template-columns: 1fr; gap: 11px; padding: 15px 18px; }
  .ahead-row > span:first-child {
    font-family: var(--mono);
    font-size: .7rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--on-night-3);
  }
  .ahead-row > span:nth-child(2),
  .ahead-row > b {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 0 12px;
    font-size: 1.02rem;
  }
  .ahead-row > span:nth-child(2)::before { content: 'by hand'; }
  .ahead-row > b::before { content: 'with Conistra'; }
  .ahead-row > span:nth-child(2)::before,
  .ahead-row > b::before {
    font-family: var(--mono);
    font-size: .67rem;
    letter-spacing: .09em;
    text-transform: uppercase;
  }
  .ahead-row > span:nth-child(2)::before { color: var(--on-night-3); }
  /* b clips the signal gradient to its own text, and a ::before is part of that
     text — so this label takes the gradient too, tying label to value to bar in
     one colour. It has to be fully transparent to do it cleanly: --on-night-3 is
     40% alpha, which let the gradient bleed through a grey wash and came out a
     muddy pink instead of either colour on purpose. */
  .ahead-row > b::before { -webkit-text-fill-color: transparent; }
  .ahead-row > span:nth-child(2)::after,
  .ahead-row > b::after {
    content: '';
    grid-column: 1 / -1;
    height: 7px;
    width: var(--w, 0);
    min-width: 3px;
    margin-top: 9px;
    border-radius: 4px;
  }
  .ahead-row > span:nth-child(2)::after { background: rgba(244, 240, 234, .17); }
  .ahead-row > b::after { background: var(--signal); }
  /* Month 12 is where the two columns are furthest apart — let it carry it. */
  .ahead-last { background: rgba(255, 79, 152, .045); }
  .ahead-last > b { font-size: 1.2rem; }

  /* The rail survives whole — it's the reason to keep scrolling. Slightly
     tighter type so a 255px card doesn't turn into a wall of text. */
  .posts-rail { gap: 16px; }
  .posts-rail .post-proof { flex-basis: clamp(240px, 76vw, 300px); }
  .post-proof figcaption { padding: 16px 18px 18px; }
  .post-proof .pp-what { font-size: .95rem; }

  /* The fanned offsets read as depth beside a column of text; stacked in one
     narrow column they just look misaligned. Flat pair instead. */
  .split-img-stack img { transform: none !important; }

  /* Act II's log is three columns on a desktop; at 390px the timestamp and
     the kind ride on one line. */
  .pub-log li {
    grid-template-columns: 78px 1fr;
    gap: 4px 12px;
    padding: 12px 16px;
  }
  .pub-log-head { padding: 14px 16px; }
  .fc-brief { min-height: 0; }

  /* No continuous or scroll-triggered motion on a phone. */
  .feed-up, .feed-down, .marquee-track, .hero-scrollcue i { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .post-proof, .feed-card { transition: none; }
  .decay-bar i { transition: none; }
}

/* ── Reduced motion — kill every drift, keep every word ──────────────── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .feed-up, .feed-down, .marquee-track, .hero-scrollcue i { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  .post-proof, .feed-card { transition: none; }
  .decay-bar i { transition: none; }
  .btn-signal:hover, .post-proof:hover { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ENGINE NOTE — names the image model where the visuals are being judged.
   Duplicated in style.css / story.css: each landing arm ships its own sheet.
   ═══════════════════════════════════════════════════════════════════════════ */
.engine-note {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  margin-top: 22px;
  padding: 14px 17px;
  max-width: 62ch;
  border: 1px solid rgba(244, 240, 234, .14);
  border-radius: 14px;
  background: rgba(244, 240, 234, .04);
}
.engine-note p {
  margin: 0;
  font-size: .93rem;
  line-height: 1.55;
  color: var(--on-night-2);
}
.engine-note strong { color: var(--on-night); font-weight: 700; }
.engine-note-tag {
  flex-shrink: 0;
  margin-top: 2px;
  font-family: "Space Mono", ui-monospace, monospace;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #fff;
  background: var(--signal);
  padding: 4px 9px;
  border-radius: 100px;
}
@media (max-width: 560px) {
  .engine-note { flex-direction: column; gap: 10px; }
}
