/* ==========================================================================
   Base — reset, type roles, colour worlds, layout primitives, motion states
   ========================================================================== */

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

html {
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: 88px;
}
html:not(.lenis) { scroll-behavior: smooth; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  min-height: 100dvh;
  background: var(--cream);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

img, svg, video, iframe, canvas { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: inherit; text-decoration-thickness: .08em; text-underline-offset: .2em; }
ul[role="list"], ol[role="list"] { list-style: none; padding: 0; }
fieldset { border: 0; padding: 0; min-width: 0; }

:focus-visible { outline: 3px solid var(--grape-ink); outline-offset: 3px; border-radius: 8px; }
.on-color :focus-visible { outline-color: var(--yellow); }
::selection { background: var(--yellow); color: var(--ink); }

/* ---- Type roles ---- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: var(--lh-head);
  letter-spacing: -.025em;
  text-wrap: balance;
}
.t-display { font-size: var(--fs-display); line-height: var(--lh-tight); letter-spacing: -.04em; }
.t-h2 { font-size: var(--fs-h2); letter-spacing: -.035em; }
.t-h3 { font-size: var(--fs-h3); font-weight: 700; }
/* No text-wrap: pretty on body text: on a mid-range phone it added ~0.8 s to
   every full layout of the homepage. Headings keep balance (cheap, visible). */
.t-lead { font-size: var(--fs-lead); color: var(--text-2); line-height: 1.55; }

/* White-text surfaces (red-ink, grape-ink, sky-ink…) */
.on-color { color: #fff; }
.on-color .t-lead, .on-color p { color: rgba(255, 255, 255, .9); }

/* Folio label: "01 — About us", a coloured number chip + hairline */
.folio {
  display: flex; align-items: center; gap: var(--s3);
  font-size: var(--fs-label); font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: var(--s5);
}
.folio b {
  display: inline-grid; place-items: center; min-width: 2.3em; height: 2.3em; padding: 0 .5em;
  border-radius: var(--r-pill); background: var(--ink); color: var(--yellow);
  font-family: var(--font-display); font-weight: 800; letter-spacing: 0; font-size: .95rem;
  rotate: -6deg;
}
.folio::after { content: ""; flex: 1; height: 2px; border-radius: 2px; background: var(--rule); max-width: 140px; }
.folio--center { justify-content: center; }
.folio--center::before { content: ""; flex: 1; height: 2px; border-radius: 2px; background: var(--rule); max-width: 140px; }
.on-color .folio { color: #fff; }
.on-color .folio b { background: var(--yellow); color: var(--ink); }
.on-color .folio::after, .on-color .folio::before { background: rgba(255, 255, 255, .3); }

/* ---- Layout primitives ---- */
.container { width: min(100% - 2 * var(--gutter), var(--maxw)); margin-inline: auto; }
.section { padding-block: var(--section); position: relative; }
.center { text-align: center; }
.center .t-lead, .center p { margin-inline: auto; }
.measure { max-width: 60ch; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; left: var(--s4); top: -100px; z-index: calc(var(--z-intro) + 1);
  background: var(--ink); color: #fff; padding: var(--s3) var(--s4);
  border-radius: var(--r-sm); font-weight: 700; text-decoration: none;
}
.skip-link:focus { top: var(--s4); }
[lang="pa"] { font-family: var(--font-pa); letter-spacing: 0; }

/* ---- Colour worlds ----------------------------------------------------
   Without motion each section paints its own ground. With motion (.worlds is
   added by motion.js) sections go transparent and the page background itself
   morphs from world to world as you scroll. */
.facts, .finder, .about, .faq { background: var(--cream); }
.programs { background: var(--leaf-soft); }
.why      { background: var(--bubble-soft); }
.story    { background: var(--yellow); }
.day      { background: var(--sky-soft); }
.reviews  { background: var(--grape-soft); }
.contact  { background: var(--peach-soft); }
.worlds main > section:not(.hero) { background: transparent; }
/* The morphing colour lives on its own fixed, composited layer, so changing it
   repaints one flat fill instead of every word and card on screen. */
.world { display: none; }
.worlds .world {
  display: block; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: var(--cream);
  transform: translateZ(0);
}

/* ---- Motion: pre-states ------------------------------------------------
   Only under .js-motion (JS on, reduced motion off). A failsafe in <head>
   removes the class if motion.js never reports ready, so nothing can stay
   hidden. */
.js-motion [data-reveal] { opacity: 0; }
.js-motion [data-reveal="clip"] { opacity: 1; clip-path: inset(100% 0 0 0); }
.js-motion [data-split]:not(.is-split) { opacity: 0; }
.js-motion .squiggle path { stroke-dashoffset: 1; }
.js-motion [data-split] .w > span { transform: translateY(105%); }
.js-motion [data-split] .mark { opacity: 0; visibility: hidden; }   /* revealed by its headline tween */

/* Looping decoration pauses whenever its section is off-screen (main.js) */
.is-off, .is-off * { animation-play-state: paused !important; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---- Page to page: the photo you tap carries on into the next page ----
   Cross-document View Transitions (CSS only). Unsupported browsers simply
   navigate; reduced motion gets a plain cut. */
@view-transition { navigation: auto; }
::view-transition-group(*) { animation-duration: .28s; animation-timing-function: cubic-bezier(.16, 1, .3, 1); }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ---- First paint: skip laying out what's far below the screen ----
   Until motion.js has set up (one frame after first paint), sections below
   the hero are laid out only when needed. motion.js adds .motion-on, which
   hands each section a .cv-wait class and releases them one per setup slice,
   all before the final ScrollTrigger refresh measures the page. Reduced-motion and
   no-JS visitors never get .js-motion, so this never applies to them. */
.js-motion:not(.motion-on) main > section:not(.hero):not(.ribbons),
.js-motion:not(.motion-on) .footer,
.cv-wait {
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}
