/* Apex Growth Corp — reading experience: motion, then typography.

   PART 1 — READ-FIRST MOTION.
   ======================================================================
   Loaded last, on every page, at every width.

   THE PROBLEM THIS SOLVES

   The site had ~17 scroll-reveal blocks per page. Each one started invisible
   and 40-50px below its final position, then faded and slid into place over a
   full second. Grids staggered on top of that, up to 0.61s for the eighth item.
   Eyebrow labels animated their LETTER-SPACING from 7px to 3px over 1.2s —
   text physically stretching while you look at it.

   That is built for skimming. For someone actually reading, it means arriving
   at a paragraph that is not there yet, then watching it travel under your eye
   before it settles. "The text gets cut off and goes to another place" is an
   exact description of a 50px translateY.

   WHAT IT DOES NOW

   Content still fades in, so the page feels alive when you scroll — but:
     · nothing TRAVELS. No translateY, no translateX, no scale, no
       letter-spacing animation. Text stays where it lands.
     · the fade is 0.34s rather than 1s.
     · staggers are near-instant, so a list does not unroll under you.
     · the trigger fires as content enters the viewport (see agc-gsap.js), so
       the fade is finished long before the text reaches a reading position.

   The per-page stylesheets on index, founders-pack and the roofer pilot each
   declare their own reveal rules. Rather than edit thirty-five rules across
   three files and risk missing one, this neutralises travel in one reviewable
   place. */

.reveal,
.reveal.in,
.reveal-x,
.reveal-x.in,
.reveal-x.left,
.reveal-img,
.reveal-img.in,
.reveal-stagger > *,
.reveal-stagger.in > *,
.reveal-stagger.pop > *,
.reveal-stagger.pop.in > *,
.reveal .testimonial,
.reveal.in .testimonial,
.reveal .pain-card,
.reveal-stagger.in .pain-card {
  transform: none !important;
}

.reveal,
.reveal-x,
.reveal-img,
.reveal-stagger > *,
.reveal .testimonial {
  transition-property: opacity !important;
  transition-duration: .34s !important;
}

/* Eyebrow labels were animating letter-spacing, which stretches the word while
   it is being read. Fade only. */
.reveal .h-eyebrow,
.reveal.in .h-eyebrow {
  letter-spacing: 3px !important;
  transition: opacity .34s var(--ease, cubic-bezier(.16,1,.3,1)) !important;
}

/* Staggers: enough to feel sequenced, not enough to wait for. */
.reveal-stagger.in > *:nth-child(1){transition-delay:.02s!important}
.reveal-stagger.in > *:nth-child(2){transition-delay:.04s!important}
.reveal-stagger.in > *:nth-child(3){transition-delay:.06s!important}
.reveal-stagger.in > *:nth-child(4){transition-delay:.08s!important}
.reveal-stagger.in > *:nth-child(5){transition-delay:.10s!important}
.reveal-stagger.in > *:nth-child(6){transition-delay:.12s!important}
.reveal-stagger.in > *:nth-child(7){transition-delay:.14s!important}
.reveal-stagger.in > *:nth-child(8){transition-delay:.16s!important}
.reveal.in .testimonial:nth-child(1){transition-delay:.02s!important}
.reveal.in .testimonial:nth-child(2){transition-delay:.05s!important}
.reveal.in .testimonial:nth-child(3){transition-delay:.08s!important}
.reveal.in .testimonial:nth-child(4){transition-delay:.11s!important}
.reveal.in .testimonial:nth-child(5){transition-delay:.14s!important}
.reveal.in .testimonial:nth-child(6){transition-delay:.17s!important}

/* Word-rise headings clip each word inside overflow:hidden until it rises into
   place — literally text cut off mid-render. Only the journal cards use it. */
.gw { overflow: visible !important; }
.gwi { transform: none !important; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-x, .reveal-img, .reveal-stagger > * { opacity: 1 !important; }
}


/* ══════════════════════════════════════════════════════════════════════════
   PART 2 — READING TYPOGRAPHY
   ══════════════════════════════════════════════════════════════════════════

   Measured before writing this: 35 headings and paragraphs on desktop (23 on a
   phone) ended with a single stranded word on its own line — a last line under
   18% of the measure. "P&L impact." alone under a full-width heading reads as
   text that got cut off and went somewhere else, because visually that is
   exactly what it is.

   text-wrap:balance evens out the lines of a heading so no word is stranded.
   text-wrap:pretty asks the browser to avoid orphans in body copy. Both are
   progressive enhancement — an older browser simply wraps as it did before,
   which is the current behaviour, so there is nothing to fall back from. */

h1, h2, h3, h4,
.hero h1, .svc-hero h1,
.section-head h2, .svc-section h2,
.post-card h2, .rel-list a, .faq-q span, .sfaq-q span {
  text-wrap: balance;
}

p, li, dd, figcaption, .lead, blockquote, .q-answer, .p-body {
  text-wrap: pretty;
}

/* Never break a word across lines. A hyphenated split mid-word is the most
   literal version of "the text gets cut off and goes to another place". */
h1, h2, h3, h4, p, li, td, th, a, .lead {
  hyphens: none;
  -webkit-hyphens: none;
}

/* Long unbroken tokens (a URL, an email) should wrap rather than force a
   horizontal scrollbar — but only those, not ordinary prose. */
p a[href^="mailto"], p a[href^="http"], td, .fact td, .cmp td {
  overflow-wrap: anywhere;
}

/* Reading measure. Anything past roughly 80 characters gets tiring to track
   back from at the end of a line. Only applied where the page has not already
   set its own max-width. */
main p:not([class]), main li:not([class]) { max-width: 72ch; }

/* A comfortable minimum leading for body copy; several pages set 1.5 or less,
   which is tight for long-form reading on a dark background. */
main p, main li { line-height: 1.7; }
main .lead, main .q-answer, main .p-body { line-height: 1.7; }
