/* ==========================================================================
   IIRF — Reset, typography, layout primitives and the motion system
   ========================================================================== */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 1rem);
  /* The closed mobile drawer is parked at translateX(100%); clip it so it
     cannot widen the document. `clip` (not `hidden`) keeps position:sticky
     working on the header. */
  overflow-x: clip;
}

body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-normal);
  color: var(--text-primary);
  background: var(--bg-page);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* No overflow-x here on purpose: `overflow-x: hidden` on <body> turns it
     into a scroll container, which stops `position: sticky` on the header
     from sticking. The `overflow-x: clip` on <html> already contains the
     parked mobile drawer. */
}

img, picture, svg, video {
  display: block;
  max-width: 100%;
  height: auto;
}

input, button, textarea, select { font: inherit; color: inherit; }

/* ----- Headings — Bricolage Grotesque, sentence case ----- */

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: var(--lh-snug);
  color: var(--text-heading);
  letter-spacing: -0.02em;
  text-wrap: balance;
}

h1 {
  font-size: var(--fs-3xl);
  font-weight: 800;
  line-height: var(--lh-tight);
  letter-spacing: -0.032em;
  max-width: 20ch;
}
h2 {
  font-size: var(--fs-2xl);
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.1;
  max-width: 24ch;
}
h3 { font-size: var(--fs-xl); letter-spacing: -0.022em; }
h4 { font-size: var(--fs-lg); letter-spacing: -0.018em; }
h5 { font-size: var(--fs-md); }
h6 { font-size: var(--fs-base); }

/* Emphasis inside display headings — the accent word */
h1 em, h2 em, h3 em {
  font-style: normal;
  font-weight: inherit;
  color: var(--green-700);
}
.section--dark h1 em,
.section--dark h2 em,
.section--dark h3 em,
.cta-band h2 em { color: var(--gold-400); }

p, li { text-wrap: pretty; }

p { max-width: var(--measure); }

/* ----- Justified prose -----
   Requested by the client (Changes.txt items 2, 21, 24, 26): "justify the
   paragraph… as in Word, Ctrl+J".

   Applied to wide single-column body prose ONLY. Justifying a narrow column
   forces the browser to stretch the spaces between words to reach the right
   margin, and in a card three or four words wide that produces visible white
   rivers running down the text — the exact opposite of the tidy look being
   asked for. So card copy, list items, role captions, form notes and centred
   section intros stay left-aligned, where ragged-right is the correct and
   more legible setting.

   hyphens: auto is what makes justification work rather than merely happen —
   it lets the browser break a long word instead of stretching a whole line to
   fit it. It needs lang="en" on <html>, which header.html sets.

   TO JUSTIFY SOMETHING ELSE: add p.prose or wrap the block in .prose.
   TO STOP a block being justified: add class="text-left". */
.flow > p,
.flow--lg > p,
.split > div > p,
.founder blockquote p,
.prose p,
p.prose {
  text-align: justify;
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-chars: 8 4 3;
}

.text-left,
.text-left p { text-align: left; hyphens: manual; -webkit-hyphens: manual; }

a {
  color: var(--link);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  transition: color var(--dur) var(--ease), text-decoration-color var(--dur) var(--ease);
}
a:hover {
  color: var(--link-hover);
  text-decoration-color: currentColor;
}

:focus-visible {
  outline: 2px solid var(--green-700);
  outline-offset: 3px;
  border-radius: var(--r-sm);
}
.section--dark :focus-visible,
.hero :focus-visible,
.site-header :focus-visible { outline-color: var(--sage-300); }

ul, ol { padding-left: 1.15em; }
li + li { margin-top: var(--sp-2); }

strong { font-weight: 600; color: var(--ink-900); }
.section--dark strong { color: #fff; }

blockquote {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 500;
  line-height: 1.5;
  letter-spacing: -0.015em;
  color: var(--green-900);
  border-left: 3px solid var(--sage-400);
  padding-left: var(--sp-5);
  margin-block: var(--sp-6);
}

hr {
  border: 0;
  border-top: 1px solid var(--border-strong);
  margin: var(--sp-8) 0;
}

::selection {
  background: var(--mint-200);
  color: var(--green-900);
}

/* ----- Skip link ----- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--green-900);
  color: #fff;
  padding: var(--sp-3) var(--sp-5);
  border-radius: 0 0 var(--r-sm) 0;
  font-weight: 600;
  text-decoration: none;
}
.skip-link:focus {
  left: 0;
  color: #fff;
}

/* ----- Layout primitives ----- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.container--narrow { max-width: var(--container-narrow); }
.container--wide { max-width: var(--container-wide); }

.section {
  padding-block: var(--section-y);
  position: relative;
}
.section--tight { padding-block: clamp(2rem, 3.5vw, 3rem); }

.section--subtle { background: var(--bg-subtle); }
.section--muted  { background: var(--bg-muted); }

.section--dark {
  background: var(--bg-dark);
  color: var(--text-on-dark);
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.section--dark h1,
.section--dark h2,
.section--dark h3,
.section--dark h4,
.section--dark h5,
.section--dark h6 { color: #fff; }
.section--dark p { color: var(--text-on-dark-muted); }
.section--dark a { color: var(--sage-300); }
.section--dark a:hover { color: #fff; }

/* Gradient mesh over dark bands — stops them reading as a flat fill */
.section--dark::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--mesh-band);
  pointer-events: none;
  z-index: -1;
}

/* Leaf watermark on dark bands — the logo silhouette, very quietly */
.section--dark::before {
  content: "";
  position: absolute;
  right: -60px;
  top: -60px;
  width: 320px;
  height: 320px;
  background: rgba(255, 255, 255, 0.028);
  border-radius: var(--r-leaf);
  pointer-events: none;
  z-index: -1;
}

/* Film grain — applied to any surface that opts in */
.has-grain { position: relative; isolation: isolate; }
.has-grain > .grain,
.grain {
  position: absolute;
  inset: 0;
  background-image: var(--noise);
  background-size: 160px 160px;
  opacity: 0.14;
  mix-blend-mode: overlay;
  pointer-events: none;
  z-index: 0;
}

/* Curved divider — the section below rises into the one above.
   Applied to the *following* section so it paints over the band edge. */
.section--curve-top {
  border-top-left-radius: clamp(28px, 5vw, 64px);
  border-top-right-radius: clamp(28px, 5vw, 64px);
  margin-top: calc(-1 * clamp(28px, 5vw, 64px));
  position: relative;
  z-index: 1;
  background: var(--bg-page);
}
.section--curve-top.section--subtle { background: var(--bg-subtle); }
.section--curve-top.section--dark { background: var(--bg-dark); }

/* Grid helpers */

.grid { display: grid; gap: var(--sp-5); }

/* Grid items default to min-width:auto, which lets wide content (e.g. a table
   with a min-width) blow the track out past the viewport. Let them shrink so
   the content's own scroll container handles the overflow instead. */
.grid > * { min-width: 0; }

/* The minimums are tuned so a 1280px container yields exactly 2 / 3 / 4
   columns — auto-fit with a smaller floor packed in an extra cramped column
   and left orphan rows behind. */
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr)); }

.flow > * + * { margin-top: var(--sp-4); }
.flow--lg > * + * { margin-top: var(--sp-6); }

/* ----- Section heading block ----- */

.section-head {
  max-width: var(--container-narrow);
  margin-bottom: clamp(1.5rem, 2.4vw, 2rem);
}
.section-head--center {
  margin-inline: auto;
  text-align: center;
}
.section-head--center h2 { margin-inline: auto; }
.section-head--center p { margin-inline: auto; }
.section-head--center .eyebrow { justify-content: center; }

/* Eyebrow — green uppercase chip with a leaf mark */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green-800);
  background: var(--mint-100);
  padding: 0.42rem 0.95rem;
  border-radius: var(--r-pill);
  margin-bottom: var(--sp-3);
}
.eyebrow::before {
  content: "";
  width: 9px;
  height: 9px;
  background: currentColor;
  border-radius: var(--r-leaf);
  flex: none;
}
.section--dark .eyebrow,
.cta-band .eyebrow {
  color: var(--sage-300);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.10);
}

/* Heading to its own intro paragraph — tightened in revision 2 so the two read
   as one block rather than two (Changes.txt items 6 and 9, SS 4 and SS 9). */
.section-head h2 { margin-bottom: var(--sp-3); }

.section-head p {
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  color: var(--text-secondary);
  max-width: 62ch;
}
.section--dark .section-head p { color: var(--text-on-dark-muted); }

.lead {
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  color: var(--text-secondary);
}

/* ----- Utilities ----- */

.text-center { text-align: center; }
.mt-0 { margin-top: 0; }
.mb-0 { margin-bottom: 0; }
.mt-4 { margin-top: var(--sp-4); }
.mt-5 { margin-top: var(--sp-5); }
.mt-6 { margin-top: var(--sp-6); }
.mt-8 { margin-top: var(--sp-8); }
.measure-none { max-width: none; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   Motion system
   Everything below is scoped to .js so the page is never left invisible when
   scripting is off, and everything is switched off under reduced motion.
   ========================================================================== */

/* ----- Base reveal: rise + soften into place ----- */

.js .reveal {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  filter: blur(6px);
  transition:
    opacity var(--dur-reveal) var(--ease-out),
    transform var(--dur-reveal) var(--ease-out),
    filter var(--dur-reveal) var(--ease-out);
  transition-delay: var(--d, 0ms);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
  filter: none;
}

/* ----- Variant: heading wipe (clip-path reveals left to right) ----- */

.js .reveal--wipe {
  opacity: 1;
  filter: none;
  transform: none;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1100ms var(--ease-out);
  transition-delay: var(--d, 0ms);
}
.js .reveal--wipe.is-visible { clip-path: inset(0 0 0 0); }

/* ----- Variant: slide in from the side ----- */

.js .reveal--left  { transform: translate3d(-40px, 0, 0); }
.js .reveal--right { transform: translate3d(40px, 0, 0); }
.js .reveal--scale { transform: scale(0.94); }

/* ----- Choreography: children of [data-stagger] enter one after another.
   main.js writes --i on each child; the delay is index * --stagger. ----- */

.js [data-stagger] > * {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  filter: blur(5px);
  transition:
    opacity var(--dur-reveal) var(--ease-out),
    transform var(--dur-reveal) var(--ease-out),
    filter var(--dur-reveal) var(--ease-out);
  transition-delay: calc(var(--i, 0) * var(--stagger));
}
.js [data-stagger].is-visible > * {
  opacity: 1;
  transform: none;
  filter: none;
}

/* ----- Page-load choreography for the hero (fires immediately, not on scroll) ----- */

/* Fail-open entrance. The hidden start frame only exists while .is-entering is
   on the hero, and main.js both adds that class and removes it again once the
   entrance window has passed. So the hero ends up visible whether the script
   runs or not, and whether the animation completes or stalls. */
.js .hero.is-entering [data-enter] {
  animation: enter-up 1000ms var(--ease-out) both;
  animation-delay: calc(160ms + var(--i, 0) * 110ms);
}
@keyframes enter-up {
  from { opacity: 0; transform: translate3d(0, 32px, 0); filter: blur(8px); }
  to   { opacity: 1; transform: none; filter: none; }
}

/* ----- Scroll progress bar ----- */

.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 3px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--sage-400), var(--gold-400));
  z-index: 200;
  pointer-events: none;
  will-change: transform;
}

/* ----- Parallax layers ----- */

[data-parallax] { will-change: transform; }

/* ----- Reduced motion: strip all of it ----- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
  }
  /* `animation: none` rather than relying on the collapsed duration above —
     a fill-mode `both` animation can still paint its `from` frame during the
     delay, which would leave the hero blank for a moment. */
  .js .hero.is-entering [data-enter] { animation: none; }
  .js .reveal,
  .js .reveal--wipe,
  .js [data-stagger] > *,
  .js .hero [data-enter] {
    opacity: 1;
    transform: none;
    filter: none;
    clip-path: none;
  }
  .scroll-progress { display: none; }
  [data-parallax] { transform: none !important; }
}

/* ----- Print ----- */

@media print {
  .site-header, .site-footer, .backtotop, .hero__actions,
  .scroll-progress, .hero__media, .hero__drops, .grain { display: none !important; }
  body { font-size: 11pt; color: #000; background: #fff; }
  a::after { content: " (" attr(href) ")"; font-size: 9pt; color: #555; }
}
