/* ── Base: document, container, section rhythm, reveal, utilities ───────── */

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px); /* anchor targets clear the sticky nav */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* hidden first for older Safari; clip is stricter on iOS (3D children can
     still expand the scrollable overflow area under overflow-x:hidden alone). */
  overflow-x: hidden;
  overflow-x: clip;
  max-width: 100%;
}
body {
  background: var(--bg);
  color: #fff;
  font-family: var(--font);
  font-size: var(--text-2);
  line-height: 1.55;
  overflow-x: hidden;
  overflow-x: clip;
  max-width: 100%;
  position: relative;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}
/* Do NOT set overflow-x on .section / main: if overflow-x ≠ visible, CSS
   forces overflow-y to compute to auto/clip as well, which trims card top
   shines (inset highlights) and can clip reveal transforms. Page-level clip
   on html/body is the guardrail; carousels break out of container padding. */
main {
  max-width: 100%;
}

img, svg, canvas { display: block; max-width: 100%; }
a { color: inherit; }

/* Content width. --page-pad is the gutter; container caps the line length. */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--page-pad);
}
.container--narrow { max-width: var(--container-narrow); }

/* Every marketing section shares the same vertical rhythm. Sections pay a full
   gap top and bottom, but adjacent sections would then double it — so a section
   that directly follows another drops its top padding, leaving a single, even
   gap between every pair (and above the first section / below the last). */
.section { padding-block: var(--section-gap); }
.section + .section { padding-top: 0; }
/* Wider beats between the three middle sections only (steps → communities →
   self-assembled). Each gap is paid by the section above it, so bumping these
   two bottoms leaves the gaps above #how and below #why untouched. */
#how, #communities { padding-bottom: calc(var(--section-gap) * 1.35); }
/* Phones: the airy desktop rhythm (the clamp floors) leaves a near-screenful of
   emptiness before each section's content on a small viewport. Tighten the
   between-section gap and the header→content gap so a section reads as one unit. */
@media (max-width: 640px) {
  :root { --section-gap: clamp(84px, 24vw, 128px); }
  #how, #communities { padding-bottom: calc(var(--section-gap) * 1.15); }
}

/* Shared section header: heading + optional sub. */
.section-head { max-width: 720px; margin-bottom: clamp(var(--space-20), 8vw, 120px); }
/* Phone ramp caps at the desktop floor (12vw = 76.8px at 640 ≈ the 80px floor
   above), so the header→content gap shrinks continuously — no snap at 640. */
@media (max-width: 640px) { .section-head { margin-bottom: clamp(var(--space-10), 12vw, var(--space-20)); } }
.section-head.center { margin-inline: auto; text-align: center; }
h2 {
  font-size: var(--fs-title);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.022em;
  color: var(--heading);
  text-wrap: balance;
}
.section-sub {
  margin-top: var(--space-4);
  font-size: var(--fs-reading);
  line-height: 1.5;
  color: var(--text-secondary);
  /* Wide enough for the longest sub to sit on a single line wherever it fits;
     it only wraps once the viewport gets too narrow. text-wrap:balance then
     splits it into two even rows rather than a long line + orphan. */
  max-width: 56ch;
  text-wrap: balance;
}
.section-head.center .section-sub { margin-inline: auto; }
/* Only near mobile do we tighten the measure so the forced two-line wrap lands
   as even rows (28ch keeps ~50-char subs to two lines, not three). */
@media (max-width: 520px) {
  .section-sub { max-width: 28ch; }
}

/* Scroll-reveal — ui.js adds .is-visible when the element enters view. */
.reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--i, 0) * 80ms);
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal { opacity: 1; transform: none; transition: none; }
}
