/* Phone block — five sections in NORMAL DOCUMENT FLOW (flowty pattern).
   Measured off flowty at 1440x900 and 375x812:
     · sections are 100vh, stacked in flow with a large gap between them
     · headline 8.85vw desktop / 12.2vw mobile, line-height ~0.9, tight tracking
     · body ~16.5px
     · the text NEVER moves under scroll — only the phone does, and it lives in
       the fixed WebGL canvas, scrubbed from section to section.
   Copy alternates right / left; the phone always travels to the opposite side. */

/* THIS PADDING SETS THE WHOLE RHYTHM OF THE PHONE BLOCK. Two things read it:

   1. The LAST section's dwell. Without trailing room the block's bottom lands
      exactly on the last section's arrive point — `.sect` is min-height:100svh
      and the copy always fits, so section height === viewport height, which
      makes arrive[n-1] (top + h/2 - vh/2) and exitStart (blockBottom - vh)
      reduce to the same scroll position. The last section then got ZERO dwell:
      the phone began rising the instant it landed.

   2. The face-on HOLD at every other section. hero/hero-timeline.js reads this
      value back off the computed style and uses it as `depart[i] - arrive[i]`,
      the distance the phone stands still before it starts turning again.

   Because exitStart = blockBottom - vh = arrive[n-1] + padding, both come to
   the same number, so all five sections hold for exactly as long. Change this
   one declaration to make the phone linger more or less; nothing else needs
   touching, and the settle can never drift apart from the dwell. */
.phone-block {
  position: relative;
  z-index: 2;
  color: var(--hero-ink);
  padding-bottom: clamp(200px, 34svh, 380px);
}

.sect {
  position: relative;
  min-height: 100svh;
  padding: calc(var(--nav-h) + var(--sp-6)) var(--gutter) var(--sp-16);
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;      /* copy spans the full height, like the hero */
}
.sect + .sect { margin-top: var(--sect-gap); }

.sect__copy {
  position: relative;
  max-width: none;
  height: 90%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* heading -> sub-text -> button spacing, 10% tighter than the 24px step */
  gap: calc(var(--sp-6) * 0.81);
}
/* Heading at the top; body copy and button pushed to the bottom — the hero's
   vertical rhythm, now shared by every section. */
.sect__body { margin-top: auto; }

.sect__title {
  font-size: var(--fs-hero);
  line-height: 0.88;   /* flowty: 112.2 / 127.5 */
  letter-spacing: -0.02em;
  color: var(--hero-ink);
}
/* flowty's headlines span 54–67% of the viewport and run behind the phone —
   they are not boxed into the copy column. Ours do the same: the title grows
   past its column toward the phone, which renders on top of it. */
/* `and (orientation: landscape)` for the same reason the stacked block below
   gained `(orientation: portrait)`: these rules push the headline out past its
   column and align it to the side the phone is NOT on, which only makes sense
   in the two-column hero. On a 1024x1366 iPad they applied on top of the
   stacked layout and dragged the headline off to one edge. The two queries are
   exact complements, so every viewport gets one of them and never both. */
@media (min-width: 1024px) and (orientation: landscape) {
  .sect__title { width: min(60vw, 920px); }
  .sect--right .sect__title { align-self: flex-end; text-align: right; }
  .sect--right .sect__copy  { align-items: flex-end; text-align: right; }
  .sect--left  .sect__title { align-self: flex-start; }
  /* the hero line 'connect with God' needs a little more measure */
  .sect--hero .sect__title { width: min(72vw, 1040px); }
}
.sect__body {
  max-width: 42ch;
  font-size: var(--fs-lead);
  font-weight: 400;
  line-height: 1.5;
  color: var(--hero-ink-mut);
}
.sect__actions { display: flex; align-items: center; gap: var(--sp-5); flex-wrap: wrap; }
.sect__trust { font-size: var(--fs-sm); color: var(--hero-ink-mut); }
/* The reassurance line belongs with the hero's primary CTA; repeating it under
   every feature section is noise. */
.sect:not(.sect--hero) .sect__trust { display: none; }

/* copy RIGHT → phone travels left · copy LEFT → phone travels right */
.sect--right .sect__copy { grid-column: 2; justify-self: end; }
.sect--left  .sect__copy { grid-column: 1; justify-self: start; }

/* ---- Hero: headline top-left, body + CTA bottom-left, card bottom-right ---- */
.sect--hero {
  grid-template-rows: auto 1fr auto;
  align-items: start;
}
.sect--hero .sect__copy {
  grid-column: 1;
  grid-row: 1 / -1;
  justify-content: space-between;
  max-width: none;
  /* 100%, not the 90% every other section uses: the hero's bottom copy has to
     sit on the same line as the card in the right column. */
  height: 100%;
}
.sect--hero .sect__title { max-width: none; }  /* the <br> sets the breaks */
.sect--hero .sect__body { max-width: 44ch; }

/* ---- SplitText line reveals (see src/hero/copy-reveal.js) ------------------
   GSAP's `mask: "lines"` wraps each split line in a clipping box and names that
   box after linesClass + "-mask". So `.rvl` is the line that moves and
   `.rvl-mask` is the box it climbs out of.

   THE CLIP BOX HAS TO BE TALLER THAN THE LINE BOX. `.sect__title` runs
   line-height: 0.88 (flowty's ratio), which is shorter than the type actually
   is — Playfair's descenders drop well below the bottom of a 0.88em line box.
   `overflow: clip` cuts exactly at the padding edge, so with no padding the
   tail of every g, y, j and p was sliced off. Measured at 1440x900: "Begin
   Your" and "Faith Journey" both lost their descenders as soon as the split
   ran.

   padding-bottom opens the clip box downward; the matching negative margin
   takes that space straight back, so adding the reveal cannot shift the layout
   it was added to. A line never shows its neighbour through that gap: every
   line has its own mask, and a line still waiting to be revealed sits at
   yPercent 105 inside its OWN box, not in the one above it. */
.rvl-mask {
  padding-bottom: 0.3em;
  margin-bottom: -0.3em;
}
.sect__body .rvl-mask {
  /* line-height 1.5 already clears the descenders — this is only insurance
     against sub-pixel rounding at odd zoom levels. */
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}
.rvl { will-change: transform; }

.sect__card {
  grid-column: 2;
  grid-row: 3;
  align-self: end;
  justify-self: end;
  width: min(30ch, 30vw);
  padding: var(--sp-6);
  background: var(--secondary);
  border-radius: var(--sp-5);
  /* No backdrop-filter — it re-blurs on every custom-cursor frame and made the
     cursor stutter over the card. */
  backdrop-filter: none;
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}
.sect__card-text { font-size: var(--fs-sm); line-height: 1.55; color: var(--hero-ink-mut); }
.sect__card-stores { display: flex; gap: var(--sp-2); }

/* Only the on-load intro animates these; nothing hides them on scroll, so a JS
   failure leaves the page fully readable. */
[data-reveal] { will-change: transform, opacity; }
.no-motion [data-reveal] { opacity: 1 !important; transform: none !important; }
.no-motion .sect__copy, .no-motion .sect__card { opacity: 1 !important; }

/* ---- Light page below ---- */
.after {
  position: relative;
  z-index: 2;
  min-height: 70vh;
  display: grid;
  place-content: center;
  padding: var(--sp-20) var(--gutter);
  background: var(--bg-2);
  color: var(--text-muted);
  font-size: var(--fs-md);
  text-align: center;
}

/* ---- Tablet ---- */
/* Below 1024 there isn't room for a half-width copy column beside the phone:
   an 8.85vw headline needs the full measure. Every section becomes one column —
   copy on top, phone centred in the space below (Stage centres it too). */
/* Portrait counts as "stacked", however wide the screen is. An iPad Pro 12.9 in
   portrait is 1024x1366 — one pixel past the width line and nowhere near it in
   shape — so it took the two-column desktop hero on a 1024px page: the copy
   column stretched to 100% height, pushing the headline and the body copy to
   opposite ends with a measured 920px hole between them, and the phone centred
   and huge, overlapping the copy by 648px and covering the Download button.
   Must stay in step with isStacked() in src/webgl/viewport.js, which decides
   where the phone is drawn. */
@media (max-width: 1023px), (orientation: portrait) {
  .sect {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto 1fr;
    align-items: start;
    align-content: start;
    padding-bottom: 44svh;
  }
  /* The copy column carries the desktop's 19px step here, which is right on a
     phone and far too tight on a tablet: at 1024x1366 a ~100px headline sat 19px
     off its body text with a metre of empty screen underneath. Scaled to the
     viewport instead, so it opens up on a tall device and collapses back to the
     phone value on a small one. The <=767 block below still overrides it
     outright, so phones are untouched. */
  .sect__copy { gap: clamp(19px, 2.4vh, 40px); }
  /* CENTRED FROM HERE DOWN, not from 767. This is the breakpoint where the
     layout stops being two columns and stacks, and it is also where
     Stage.setPhoneX() starts pinning the phone to the centre (`< 1024`). Left
     aligned copy under a centred phone reads as a mistake, and between 768 and
     1023 — tablets, and any large phone held sideways — that is exactly what
     was on screen: the stack landed at 1023 but the centring did not start
     until 767, leaving a whole band with the two out of agreement.
     The <=767 block repeats these; harmless, and it keeps that block readable
     on its own. */
  .sect--right .sect__copy,
  .sect--left  .sect__copy,
  .sect--hero  .sect__copy {
    grid-column: 1;
    grid-row: 1;
    justify-self: center;
    justify-content: flex-start;
    align-items: center;
    text-align: center;
    height: auto;
    max-width: none;
  }
  .sect__title,
  .sect__body { text-align: center; }
  .sect__body { max-width: 46ch; margin-top: 0; margin-inline: auto; }
  .sect__actions { justify-content: center; }
  .sect__card {
    grid-column: 1;
    grid-row: 2;
    justify-self: center;
    align-self: start;
    width: 100%;
    max-width: 460px;
    margin-top: var(--sp-6);
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-4);
    padding: var(--sp-4);
  }
}

/* ---- Small screens ---- */
@media (max-width: 767px) {
  /* Was 48svh, which reserved ~390px of dead space and pushed the phone far
     below the copy. The phone is drawn in the fixed canvas, so this padding
     only needs to leave it room — not clear its whole height.
     26svh then overcorrected: at 375x667 that is 173px and the phone needs
     ~300px, so it was clipped by the viewport edge at rest on every phone size
     and only ever fully visible while exiting. 34svh seats it without going
     back to the dead space of 48. */
  /* Top padding is `--nav-h + --sp-6` (72 + 24 = 96px) everywhere else, which
     on a small screen leaves the headline sitting almost against the navbar —
     there is no air between the chrome and the copy. --sp-12 instead of --sp-6
     gives 72 + 48 = 120px. The extra 24px comes off the gap under the CTA
     rather than out of the layout, because the phone is anchored near the fold
     (HERO_HANG in webgl/Stage.js), not below the copy. */
  .sect {
    padding-top: calc(var(--nav-h) + var(--sp-12));
    padding-bottom: 34svh;
  }
  .sect__copy { gap: calc(var(--sp-4) * 0.81); }

  /* The reassurance line belongs with the primary CTA in the hero; repeating it
     under every feature section is noise on a small screen. */

  /* Centre the whole copy column. These need the same compound selectors as the
     <1024 rules above, or the `justify-self: start` there wins on specificity. */
  .sect--right .sect__copy,
  .sect--left  .sect__copy,
  .sect--hero  .sect__copy {
    justify-self: center;
    align-items: center;
    text-align: center;
  }
  .sect__title,
  .sect__body { text-align: center; }
  .sect__body { margin-inline: auto; }

  /* Trust line sits centred BELOW the Download button rather than beside it. */
  .sect__actions {
    flex-direction: column;
    align-items: center;
    gap: var(--sp-3);
  }
  .sect__trust { text-align: center; }

  /* The supporting card is redundant on a narrow screen — the same store links
     are already in the navbar. */
  .sect__card { display: none; }
}

/* Card on the dark theme: a faint luminous panel rather than a white one. */
:root[data-theme="dark"] .sect__card {
  /* A real surface, not a wash. The card sits in the brightest part of the beam,
     and a 6%-white fill left its own contents unreadable. No backdrop-filter —
     that re-blurs on every custom-cursor frame (Rev 10). */
  background: rgba(6, 7, 12, 0.74);
  border-color: rgba(244, 247, 255, 0.18);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
:root[data-theme="dark"] .sect__card-stores .icon-btn {
  background: rgba(244, 247, 255, 0.10);
  border-color: rgba(244, 247, 255, 0.22);
}

:root[data-theme="dark"] .navbar::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(var(--nav-h) * 1.9);
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(6, 7, 12, 0.92), rgba(6, 7, 12, 0));
}

/* Legibility over the pillar (CLAUDE.md §10).
   The first attempt used scrim boxes behind each copy column; their edges were
   visible as a dark patch floating over the beam. Text-shadow haloes do the same
   job with no boundary at all — they only darken the few pixels around each
   glyph, so the background stays unbroken. */
:root[data-theme="dark"] .sect__title {
  text-shadow:
    0 0 30px rgba(6, 7, 12, 0.95),
    0 0 70px rgba(6, 7, 12, 0.85),
    0 0 140px rgba(6, 7, 12, 0.7),
    0 1px 2px rgba(6, 7, 12, 0.8);
}
:root[data-theme="dark"] .sect__body {
  text-shadow:
    0 0 16px rgba(6, 7, 12, 0.95),
    0 0 38px rgba(6, 7, 12, 0.8);
}
/* The trust line is small AND muted, sitting right in the core of the beam —
   it needs a tighter, denser halo than the body copy. */
:root[data-theme="dark"] .sect__trust {
  color: rgba(244, 247, 255, 0.82);
  text-shadow:
    0 0 10px rgba(6, 7, 12, 1),
    0 0 22px rgba(6, 7, 12, 0.95),
    0 0 44px rgba(6, 7, 12, 0.8);
}
:root[data-theme="dark"] .navbar__nav a {
  text-shadow: 0 0 14px rgba(6, 7, 12, 0.9), 0 0 30px rgba(6, 7, 12, 0.7);
}
