/* Detox AI — definitive pass: sticky setup story, Premium scene + carousel, closing emblem,
   mobile hero, scroll-lit text and masked headline reveals. Loaded after atlas.css. */

/* ---------- journey: sticky 3D beside the steps ---------- */
.journey-stage {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: start;
  margin-top: clamp(1.5rem, 4vw, 3rem);
}

.journey-visual {
  position: sticky;
  top: calc(50vh - min(34vw, 560px) / 2 + var(--nav-h) / 2);
  order: 2;
}

.journey-view { aspect-ratio: 1 / 1; }

.journey-stage .journey-steps {
  display: block;
  order: 1;
}

.journey-stage .journey-step {
  min-height: 72vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: 0;
  padding: 0 0 0 1.6rem;
  background: none;
  border: 0;
  border-left: 2px solid rgba(159, 176, 201, 0.15);
  border-radius: 0;
  overflow: visible;
  opacity: 0.35;
  transition: opacity 0.5s var(--ease-out), border-color 0.5s var(--ease-out);
}

.journey-stage .journey-step::before,
.journey-stage .journey-step::after { display: none !important; content: none; }
.journey-stage .journey-step:hover { transform: none; }

.journey-stage .journey-step.is-active {
  opacity: 1;
  border-left-color: var(--teal);
}

.journey-stage .journey-num {
  font-size: clamp(3.4rem, 7vw, 6rem);
  line-height: 1;
  margin-bottom: 0.6rem;
}

.journey-stage .journey-step h3 {
  font-size: clamp(1.8rem, 3vw, 2.6rem);
  letter-spacing: -0.03em;
  margin: 0 0 0.8rem;
}

.journey-stage .journey-step p { max-width: 40ch; font-size: clamp(1rem, 1.2vw, 1.12rem); }

/* ---------- premium ---------- */
.premium-view {
  aspect-ratio: 16 / 7.5;
  margin: calc(clamp(2rem, 4.5vw, 3.25rem) * -1) calc(clamp(2rem, 4.5vw, 3.25rem) * -1) 1.5rem;
  width: calc(100% + 2 * clamp(2rem, 4.5vw, 3.25rem));
  border-radius: 0;
  border: 0;
  border-bottom: 1px solid rgba(206, 155, 61, 0.25);
  box-shadow: none;
  background:
    radial-gradient(ellipse 60% 70% at 50% 45%, rgba(247, 217, 139, 0.1), transparent 70%),
    linear-gradient(180deg, rgba(14, 20, 30, 0.6), rgba(10, 16, 25, 0.2));
}

.premium-view::after { display: none; }

/* A swipeable price row must never widen its grid column: `1fr` is minmax(auto, 1fr), so the column grew to
   the row's four cards side by side (482 px in a 297 px card on a phone) and the card cut every perk, price
   and note off mid-word. minmax(0, …) lets the row scroll inside the column instead. */
.premium-layout { grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.9fr); }
.premium-layout > * { min-width: 0; }
/* the perk list is stretched to the price column's height; its rows must pack to the top, not spread out
   (five perks sat ~100 px apart on desktops) */
.premium-perks { align-content: start; }
@media (max-width: 980px) {
  .premium-layout { grid-template-columns: minmax(0, 1fr); }
}

/* Chapter rail: the active section's name rested beside the content column even where the margin is ~130 px,
   so at 1440 it ran into the copy ("FEATURESEach habit switch…"). Below 1600 px it shows on hover / keyboard
   focus only, as a pill that reads cleanly over whatever is behind it. */
.chapter-dot::after {
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  background: rgba(10, 16, 25, 0.94);
  border: 1px solid rgba(47, 212, 198, 0.28);
}
.chapter-dot:focus-visible::after { opacity: 1; transform: translateY(-50%) translateX(0); }
@media (max-width: 1599px) {
  .chapter-dot.is-active:not(:hover):not(:focus-visible)::after { opacity: 0; transform: translateY(-50%) translateX(-4px); }
}

/* ---------- 3D frames tilt like cards in the hand ----------
   js/gl/gl.js sets each frame's `rotate` (it composes with the entrance `transform`) toward the cursor or with
   the phone's tilt, and moves a soft light across it (--gx/--gy/--go on .view-glare). */
.chapter, .journey-visual, .privacy-gl { perspective: 1600px; }
/* they also ride a gently curved wall as the page scrolls (`rotate` + `translate`, both set per frame by gl.js);
   phones get a nearer eye so the curve still reads on a narrow frame */
@media (max-width: 900px) { .chapter, .journey-visual, .privacy-gl { perspective: 1100px; } }
html.has-gl .chapter-view { will-change: rotate, translate; }

/* the 3D sky (js/gl backdrop.js): flown through on scroll, behind everything; replaces the flat #fx-canvas */
.gl-sky {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  animation: sky-in 0.5s ease-out forwards;
}
body > .gl-sky { z-index: 0; }
/* the two pinned stages were solid slabs: the sky stopped at a hard edge. With the sky on they fade in and
   out of it and let a little of it through, so the flight never cuts. */
html.has-gl .teardown {
  background:
    radial-gradient(ellipse 60% 50% at 50% 55%, rgba(47, 212, 198, 0.09), transparent 70%),
    linear-gradient(180deg, rgba(6, 10, 16, 0), rgba(6, 10, 16, 0.86) 14%, rgba(6, 10, 16, 0.86) 86%, rgba(6, 10, 16, 0));
}
/* their WebGL stages paint an opaque backdrop (bloom needs it): feather its top and bottom so the stage
   dissolves into the sky as the pin arrives and leaves, instead of a hard slab edge */
html.has-gl .td-gl,
html.has-gl .keys-gl {
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 13vh, #000 calc(100% - 13vh), transparent);
  mask-image: linear-gradient(180deg, transparent, #000 13vh, #000 calc(100% - 13vh), transparent);
}
html.has-gl .keys {
  background:
    radial-gradient(ellipse 70% 55% at 50% 62%, rgba(47, 212, 198, 0.1), transparent 70%),
    linear-gradient(180deg, rgba(4, 7, 11, 0), rgba(4, 7, 11, 0.9) 10%, rgba(4, 7, 11, 0.9) 90%, rgba(4, 7, 11, 0));
}
@keyframes sky-in { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .gl-sky { display: none; } }
.view-glare {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  border-radius: inherit;
  opacity: var(--go, 0);
  background: radial-gradient(circle at var(--gx, 50%) var(--gy, 50%), rgba(234, 240, 248, 0.11), rgba(47, 212, 198, 0.05) 32%, transparent 62%);
  mix-blend-mode: screen;
}
/* the hero phone spins when dragged sideways (vertical swipes still scroll the page) */
html.has-gl .hero-visual { cursor: grab; touch-action: pan-y; }
html.has-gl .hero-visual.is-spinning { cursor: grabbing; }

/* ---------- closing emblem ---------- */
.emblem-view {
  position: relative;
  width: min(380px, 78vw);
  aspect-ratio: 1 / 1;
  margin: -1rem auto 0.5rem;
}

.emblem-view.gl-on .view-canvas { opacity: 1; }

/* ---------- mobile: headline in the first screen ---------- */
@media (max-width: 900px) {
  html.has-gl .hero-visual { height: 46vh; min-height: 300px; }
  html.has-gl .hero-visual .phone-stage { display: none; }
  html.has-gl .hero-view { inset: -6% -12% -10%; }
  html.has-gl .hero-logo-wrap { display: none; }

  .journey-stage { grid-template-columns: 1fr; gap: 0; }
  .journey-visual {
    top: calc(var(--nav-h) + 8px);
    order: 0;
    z-index: 2;
  }
  .journey-view {
    aspect-ratio: auto;
    height: 42vh;
    background-color: #070c14;
    box-shadow: 0 30px 50px 10px #0a1019;
  }
  /* each step's text settles in the lower half, below the pinned visual */
  .journey-stage .journey-step { min-height: 80vh; justify-content: flex-end; padding: 0 0 9vh 1.2rem; }

  .premium-view { aspect-ratio: 1 / 0.82; }

  /* four stacked price cards become a swipeable row */
  .pricing-cards {
    display: flex;
    gap: 0.75rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding: 0.6rem 1.25rem 1rem;
    margin: 0 -1.25rem;
    scrollbar-width: none;
  }
  .pricing-cards::-webkit-scrollbar { display: none; }
  .price-card { flex: 0 0 74%; scroll-snap-align: center; }
  .price-card.featured { transform: none; }
}

/* ---------- scroll-lit paragraphs ---------- */
.scrub .w { color: rgba(234, 240, 248, 0.16); transition: color 0.35s var(--ease-soft); }
.scrub .w.on { color: inherit; }

/* ---------- masked headline reveal ---------- */
.split .mw {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.split .mi {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 0.9s var(--ease-out);
  transition-delay: calc(var(--i) * 45ms);
}

.split.is-in .mi { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .split .mi { transform: none !important; transition: none !important; }
  .scrub .w { color: inherit !important; }
  .journey-stage .journey-step { opacity: 1; }
}

/* ---------- Planck pass: measured fixes ---------- */
/* the science panels slide in from ±8px: never let that widen the page on phones */
#problem { overflow-x: hidden; overflow-x: clip; }

/* unlit scroll-text stays readable if the reader stops scrolling */
.scrub .w { color: rgba(234, 240, 248, 0.32); }

/* footer column titles are h3 now (no h2 -> h4 jump) */
.footer-col h3 {
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mist300);
  margin: 0 0 0.85rem;
}

/* 44px touch targets */
.nav-toggle { min-width: 44px; min-height: 44px; }
.nav-brand { min-height: 44px; }
.mobile-dock-item { min-height: 44px; justify-content: center; }
/* desktop: the copyright line ends above the floating scroll button (66px tall, 16px off the bottom) */
@media (min-width: 901px) {
  .footer { padding-bottom: 6rem; }
}
/* phone in landscape: 375px of height can't spare 70 for a dock; the menu button stays */
@media (max-width: 900px) and (max-height: 500px) and (orientation: landscape) {
  .mobile-dock { display: none !important; }
  /* the journey goes back to its desktop shape: steps left, a square scene pinned right (a 42vh strip
     was 627 x 158 here); the Premium banner and the emblem stay inside the screen's height */
  .journey-stage { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.25rem; }
  .journey-visual { order: 2; top: calc(var(--nav-h) + 0.75rem); }
  .journey-view {
    aspect-ratio: 1 / 1;
    height: auto;
    width: min(100%, calc(100svh - var(--nav-h) - 1.5rem));
    margin-inline: auto;
    box-shadow: none;
  }
  .journey-stage .journey-step { min-height: 90vh; justify-content: center; padding: 0 0 0 1.2rem; }
  .premium-view { aspect-ratio: 16 / 7.5; }
  .emblem-view { width: min(380px, 78vw, calc(100svh - var(--nav-h) - 2rem)); }
}
/* dock steps aside while the hero buttons are in its band (motion.js) */
html.exp-mobile .mobile-dock.is-ready.is-tucked {
  transform: translateX(-50%) translateY(120%);
  opacity: 0;
  pointer-events: none;
}
@media (max-width: 900px) {
  .footer-col ul { gap: 0; }
  .footer-col a { display: inline-block; padding: 0.7rem 0; }
}

/* no WebGL (or reduced motion): drop the 3D frames, let each chapter read as text */
html:not(.has-gl) .chapter-view,
html:not(.has-gl) .emblem-view,
html:not(.has-gl) .hero-view { display: none; }
html:not(.has-gl) .chapter { grid-template-columns: 1fr; min-height: 0; max-width: 760px; }
html:not(.has-gl) .chapter-flip .chapter-copy { order: 0; }
html:not(.has-gl) .journey-stage { grid-template-columns: 1fr; }
html:not(.has-gl) .journey-visual { display: none; }
html:not(.has-gl) .journey-stage .journey-step { min-height: 0; padding: 1.5rem 0 1.5rem 1.2rem; opacity: 1; justify-content: flex-start; }

/* keyboard: FAQ questions and the swipeable price row get the same visible focus ring */
summary:focus-visible,
.pricing-cards:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 3px;
  border-radius: 12px;
}

/* the fixed chapter rail (26px pill + label) needs a ~64px side margin; below ~1320px the page
   content starts at ~32px and the rail sat on top of headlines. The top nav covers navigation there. */
@media (max-width: 1320px) {
  .chapter-rail { display: none !important; }
}

/* Hero headline letters: the entrance keyframes ended on rotateX(0), which keeps every letter in a 3D
   compositing layer, where Chromium can drop the per-letter background-clip:text and paint the white
   gradient box instead (the "D" of "Detox AI" showed as a solid block). Ending on transform:none lets
   each letter settle back to normal painting. */
@keyframes char-in-settle {
  to { opacity: 1; transform: none; }
}
.hero-title .split-char {
  animation-name: char-in-settle;
  -webkit-text-fill-color: transparent;
}

/* Once the hero headline is split into per-letter spans (each with its own gradient clip), the
   h1's own background-clip:text gradient has no glyphs of its own to clip to, and Chromium painted
   a stray white block of it beside the "D" of "Detox AI". Drop the parent gradient when split. */
.hero-title:has(.split-char) {
  background: none;
}

/* WebGL context lost mid-session (phones under memory pressure): hide the dead canvases and lines,
   the sections' CSS versions take over (gl.js removes .gl-on / .has-gl) */
.teardown:not(.gl-on) .td-gl,
.teardown:not(.gl-on) .td-lines,
.keys:not(.gl-on) .keys-gl { display: none; }
