/* ==========================================================================
   IMAGE HOVER ZOOM (site-wide, 2026-08-28 per Arina) — content photo/logo TILES grow
   slightly on hover, EXCEPT: true background images (.closing__bleed/.closing__scrim —
   full-bleed section backdrops, not content), TRUST-BAND's own cards/mini-collage
   (already carry a scroll-driven drift transform, see js/scroll-drift.js and the note
   in reveal.css — a second transform on the same element would silently replace that
   one, since an element only has one `transform` value; trust-band's photos still zoom,
   just via their own dedicated rule further down in the TRUST-BAND section so it can
   compose with --drift-x/--drift-y), and any image that's really acting as a section's
   own BACKDROP with text laid directly on top of it rather than a discrete photo tile —
   .mission1__banner (behind the mission1 eyebrow/body/label) and .proof-band__plate
   (behind the proof-band kicker/heading/body) — explicitly excluded below, same as
   .thought-leaders__photo (behind the quote panel). Zooming a backdrop under fixed
   overlaid text reads as the text swimming over a moving photo, not a nice hover — the
   effect is only right for images that stand alone as their own tile (a swatch, a
   journal card photo).
   Split into two groups:
     - WRAPPED images (a clipped, overflow:hidden frame around the <img>) — the zoom
       targets the <img> child, not the frame, so the photo visibly grows WITHIN its
       fixed frame instead of the frame itself growing and overlapping neighbors.
     - STANDALONE images (certs/GOTS logos, no frame) — the zoom targets the <img>
       itself directly.
   The scroll-triggered appear/disappear animation for these same images lives in
   reveal.css/js (.img-reveal) — that's a separate `transform`, but on the WRAPPER for
   wrapped images (so it never collides with this rule's <img>-level transform) and
   reconciled explicitly below for the one standalone exception (.certs-band__row img)
   that carries both. */
.mission1__swatch img,
.sheet-band__plate img,
.journal__plate img {
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.mission1__swatch:hover img,
.sheet-band__plate:hover img,
.journal__plate:hover img {
  transform: scale(1.08);
}

/* Backdrop images — text sits directly on top of these, so no hover-zoom (see the note
   above): .mission1__banner, .proof-band__plate, .thought-leaders__photo. All three
   still get the scroll-triggered .img-reveal appear/disappear (reveal.js/css) same as
   every other photo here; only the hover-grow is opted out. */

.sheet-band__gots img, .trust-band__mini-collage img {
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.sheet-band__gots:hover img, .trust-band__mini-collage img:hover {
  transform: scale(1.12);
}

/* .certs-band__row img also carries .img-reveal (reveal.css/js) for the scroll
   appear/disappear — both rules set `transform`, so the hover state is spelled out
   combined with .is-visible explicitly (highest specificity here) rather than relying
   on source order between two equally-specific rules. */
.certs-band__row img {
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1);
}
.certs-band__row img.is-visible:hover {
  transform: scale(1.15);
}

/* ==========================================================================
   HERO OVERLAY (node 90:21) — nav + tagline + wordmark, layered on top of
   the WebGL scroll-video stage. Only the Figma banner photo (90:22) is
   replaced by video; everything else here is built verbatim from Figma.
   Figma's frame-level 30% opacity on 90:21 is treated as an editing
   artifact, not intentional — built at full opacity per Arina (else the
   nav is barely legible). Basis: 1440x900 (this page's own hero frame).
   ========================================================================== */

.hero-overlay {
  /* absolute, not fixed: .stage (its parent) is `position: sticky`, which establishes
     a containing block — absolute here means this overlay is pinned to .stage's own
     box exactly as long as .stage itself is stuck, then scrolls away with it once the
     track is scrolled past. `position: fixed` here would (and did) escape .stage
     entirely and stay glued to the viewport forever, permanently overlaying every
     section below the hero. */
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

.hero-overlay__nav {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 77px;
  pointer-events: auto;
}

.hero-overlay__wordmark {
  position: absolute;
  top: 0;
  left: 5.556%;               /* 80px / 1440px */
  width: 9.444%;               /* 136px / 1440px */
  aspect-ratio: 136 / 77;
  background-color: var(--color-cream);
  -webkit-mask-image: url("../assets/webp/wordmark-mask.webp");
  mask-image: url("../assets/webp/wordmark-mask.webp");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

.hero-overlay__links {
  position: absolute;
  top: 50%;
  right: 5.556%;
  transform: translateY(-50%);
  display: flex;
  gap: 2.5vw;                  /* 36px / 1440px */
}

.hero-overlay__link {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(9px, 0.764vw, 11px);
  letter-spacing: 0.164em;
  text-transform: uppercase;
  color: var(--color-cream);
  white-space: nowrap;
}

/* Opening title card (mirrors .hero-overlay__wordmark-bg's centered layout role, reused
   as an opening bookend tied to scene 0 instead of the last scene). The supporting
   tagline that originally sat under this moved to the scene-0 .hero-scene-text block
   instead, per Arina 2026-09-03. */
.hero-hand {
  position: absolute;
  left: 50%;
  top: 12.556vh;
  transform: translateX(-50%);
  width: 92.222%;
  text-align: center;
  pointer-events: none;
}

/* Wordmark logo in place of the typeset title (2026-09-08, per Arina). Same masked-
   background technique every other wordmark on the site uses (.site-header__wordmark,
   .nav__wordmark, .footer__mark) so it stays a single-colour vector-ish shape that can
   be tinted, rather than a baked-in PNG. Sized to roughly the width the old 68px
   "Love Always" setting occupied, so the hero's composition is unchanged. */
.hero-hand__logo {
  position: relative;
  width: min(40vw, 400px);
  margin: 0 auto;
  aspect-ratio: 136 / 77;

  /* Scroll-driven left-to-right wipe (2026-09-08, per Arina) — the logo "draws itself
     in" the way the typeset title used to, which the per-character hand-reveal can't
     do to an image. Two masks are intersected: the wordmark shape (on this element)
     and a hard-edged gradient whose boundary is --wipe (on the .hero-hand__logo-wipe
     child below). Only where BOTH are opaque does the fill show, so sliding --wipe
     from 0% to 110% sweeps the letterforms in from the left. The 10% ramp softens
     the leading edge so it reads as ink arriving rather
     than a sliding rectangle; --wipe overshoots to 110% so the final stroke ends fully
     opaque instead of caught mid-ramp.
     Default is the finished state, so with no JS (or before the first frame) the logo
     is simply fully drawn rather than invisible. js/index.js drives it per frame. */
  --wipe: 110%;

  /* 2026-09-10: the wordmark and the wipe are now masked on SEPARATE elements rather
     than intersected as two layers here via mask-composite. Two composited mask layers
     on one box left a ~1px unmasked fringe at the element's left and right edges, so a
     faint vertical line of this element's own background showed either side of the
     logo (confirmed by setting background-color: red - the lines went red too, and
     collapsing to a single-layer `mask` shorthand made them vanish). Nesting gets the
     same intersection for free: the child is clipped by this element's mask, then
     masked again by its own gradient. No mask-composite involved. */
  -webkit-mask-image: url("../assets/webp/wordmark-mask.webp");
  mask-image: url("../assets/webp/wordmark-mask.webp");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

/* The scroll-driven wipe layer. Carries the paint colour (moved off the parent, which
   must have no background of its own or it would paint in the fringe again) and the
   hard-edged gradient whose boundary is --wipe. --wipe still lives on
   .hero-hand__logo and inherits down to here, so js/index.js keeps writing it to the
   exact same element as before - no JS change was needed for this fix.
   mask-size is 102%, not 100%: sized to exactly 100% the gradient's own first and last
   columns land on the box edge, and on a fractional element width (min(40vw, 400px)
   is rarely an integer) they resample to partial alpha. The 1% overhang each side
   keeps only the gradient's solid interior over the box. */
.hero-hand__logo-wipe {
  position: absolute;
  inset: 0;
  display: block;
  background-color: #fafafa;
  -webkit-mask-image: linear-gradient(90deg, #000 calc(var(--wipe) - 10%), transparent var(--wipe));
  mask-image: linear-gradient(90deg, #000 calc(var(--wipe) - 10%), transparent var(--wipe));
  -webkit-mask-size: 102% 100%;
  mask-size: 102% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

.hero-hand__title {
  font-family: var(--font-display);
  font-weight: 400;
  /* 2026-09-04, per Arina: font-size here was tuned for Parisienne (a script that
     reads visually smaller/thinner than its nominal size); Forum is a much heavier,
     solid serif, so the old clamp(56px, 9vw, 130px) rendered oversized at this same
     value — roughly halved to compensate. */
  font-size: clamp(32px, 4.5vw, 68px);
  color: #fafafa;
  margin: 0;
  line-height: 1;
}

/* Per-scene hero copy — one line per clip, positioned on alternating sides so it can
   slide/fade "into" that edge as its scene dissolves into the next (see
   wireHeroSceneText() in js/index.js). Opacity and translateX are both set inline
   per-frame by JS (translateY(-50%) stays constant in that inline transform, so each
   line still centers on ITS OWN `top` below regardless of which one JS is animating);
   the CSS here only supplies the resting geometry/typography and a pre-JS default
   (opacity: 0) so nothing flashes at full strength before the first scroll-position read.
   `top` is set per data-scene (not one shared value) so the four lines land at different
   heights as they rotate through — reads as more alive than every line stacking on the
   exact same center line, per Arina 2026-08-28. */
.hero-scene-text {
  position: absolute;
  width: 25%;                    /* back to Forum's original width (2026-09-04, per
                                     Arina) — the 32% width was specifically widened for
                                     the handwritten font's longer, connected
                                     letterforms; no longer needed now that this is
                                     Forum again. */
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(22px, 2.3vw, 32px);
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: #f5f5f5;
  opacity: 0;
}

.hero-scene-text--left {
  left: 6.944%;                 /* 100px / 1440px, echoes the nav's own left inset */
}

.hero-scene-text--right {
  right: 6.944%;
  text-align: right;
}

.hero-scene-text[data-scene="0"] { top: 46%; } /* pushed down from 30% — was colliding
                                                   with the big centered "Love Always"
                                                   title above it, per Arina 2026-09-03 */
.hero-scene-text[data-scene="1"] { top: 66%; }
.hero-scene-text[data-scene="2"] { top: 42%; }
.hero-scene-text[data-scene="3"] { top: 58%; }
.hero-scene-text[data-scene="4"] { top: 36%; }

.hero-scene-text p { margin: 0; }
.hero-scene-text p.hero-scene-text__sub {
  margin-top: 0.1em;
  font-size: 0.72em;
  opacity: 0.88;
  /* "Organic. Fair. Beautiful." set in caps (2026-09-08, per Arina). Done here rather
     than by editing the copy so the hand-reveal system still splits the original
     sentence case — it reads textContent, which stays as authored. */
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Handwriting reveal (2026-09-03): every .hand-reveal element's text is split into
   .hand-unit spans by wireHandReveal() in js/index.js (word-by-word or char-by-char per
   data-hand-unit), each one's opacity driven per-frame off that element's own scene
   progress — same "JS sets inline style, CSS transition only smooths a dropped frame"
   split as the rest of this file's scroll-scrubbed elements (see .fallback-stage video
   below). The blur-in on top of the opacity fade is what reads as "settling ink" rather
   than a flat digital fade. */
.hand-unit {
  opacity: 0;
  filter: blur(4px);
  transition: opacity 90ms linear, filter 90ms linear;
}

/* ==========================================================================
   STAT-BAND (node 93:36) — Figma auto-layout flex row, translated literally.
   Basis: 1440x233
   ========================================================================== */

.stat-band {
  position: relative;
  width: 100%;
  height: var(--h-home-stat);
  background: var(--color-cream);
  display: flex;
  align-items: center;
  padding: 0 5.556%;
  box-sizing: border-box;
}

.stat-band__item {
  flex: 1 0 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(24px, 2.778vw, 40px);
  color: var(--color-ink);
}

/* ==========================================================================
   MISSION — 1 (node 90:68) — banner + 3 swatches + heading + label row
   Basis: 1440x624
   ========================================================================== */

.mission1 {
  background: var(--color-cream);
}

.mission1__frame {
  position: relative;
  width: 100%;
  height: var(--h-home-mission-1);
}

.mission1__banner {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 60.5%;                 /* was 58.974% (368px) — grown per Arina, but stops
                                     short of the swatch row's own top (62.660%) so a
                                     real gap stays between them (an earlier pass grew
                                     it to touch the swatches exactly, which was wrong —
                                     "shouldn't touch them, space needs to be there"). */
  border-radius: var(--radius-plate);
  overflow: hidden;
}
/* object-position was "bottom", which crops from the TOP — cutting off the strand's
   upward hook/peak (the most visually dynamic part of the source photo) and leaving
   only the lower sweep visible. "top" keeps the peak and crops the flatter lower
   portion instead. */
.mission1__banner img { width: 100%; height: 100%; object-fit: cover; object-position: top; }

.mission1__swatch {
  position: absolute;
  top: 64.786%;                  /* was 62.660% (391px) — recentered so the gap above
                                     (banner -> swatches) equals the gap below
                                     (swatches -> the rule at the very top of MISSION-2,
                                     which sits right at this section's bottom edge). */
  /* Square in Figma (193x193). `aspect-ratio` alone (deriving height from width) fixed
     the stretch but broke the opposite way: on a short window the section's own height
     shrinks via vh while a width-only size doesn't, so the square box overflowed past
     the section's bottom edge into MISSION-2 below. min() of the width-basis and
     height-basis values keeps it square AND bounded by whichever dimension is tighter
     — 21.444vh = 30.929% of the section's own 69.333vh height, i.e. the same original
     proportion, just expressed against viewport height instead of section height. */
  width: min(13.403vw, 21.444vh);
  height: min(13.403vw, 21.444vh);
  border-radius: var(--radius-plate);
  overflow: hidden;
}
.mission1__swatch img { width: 100%; height: 100%; object-fit: cover; }
.mission1__swatch--1 { left: 1.944%; }   /* 28px */
.mission1__swatch--2 { left: 16.181%; }  /* was 17.569% (253px) — pulled closer to swatch--1 per Arina */
.mission1__swatch--3 { left: 84.028%; }  /* 1210px */

.mission1__heading {
  position: absolute;
  left: 57.5%;                    /* calc(50% + 108px) */
  top: 68.910%;                    /* 430px / 624px */
  transform: translateX(-50%);
  width: 50.139%;                  /* 722px / 1440px */
  text-align: center;
  font-family: var(--font-display);
  font-weight: 400;
  /* clamp() alone only tracks viewport WIDTH — on a short/wide window the section's
     own height (which scales with vh) shrinks faster than a width-only font-size does,
     so the heading no longer fits its box and spills into the section below. min() of
     a vw value and a vh value (7.556vh = 68px / 624px section height, i.e. the same
     proportion expressed against height instead of width) makes it shrink with
     whichever dimension is actually more constrained. */
  font-size: clamp(28px, min(4.722vw, 7.556vh), 68px);
  text-transform: uppercase;
  color: var(--color-ink);
}

.mission1__eyebrow {
  position: absolute;
  left: 13.75%;
  top: 6.410%;                     /* 40px / 624px */
  transform: translateX(-50%);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(9px, 0.764vw, 11px);
  letter-spacing: 0.2em;
  white-space: nowrap;
  color: var(--color-cream);
}

.mission1__body {
  position: absolute;
  left: 50.035%;
  top: 6.410%;
  transform: translateX(-50%);
  width: 16.181%;                   /* 233px / 1440px */
  text-align: center;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(12px, 1.111vw, 16px);
  color: var(--color-cream);
}

.mission1__label {
  position: absolute;
  right: 2.882%;
  top: 6.410%;
  text-align: right;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(9px, 0.764vw, 11px);
  letter-spacing: 0.136em;
  white-space: nowrap;
  color: var(--color-cream);
}

/* MISSION-2's overlay (.mission2-overlay and its .mission2__* children — cotton-branch
   frames, floating 3D tufts, bullet, two body sections) was removed 2026-09-03 per
   Arina, along with the icon-detail callout overlay further below. .trust-band__meta-row
   just below is NOT part of that removal — it was moved here from MISSION-2 earlier and
   stayed, since it's now genuinely part of TRUST-BAND's own collage. */

/* Moved here from MISSION-2 per Arina — it's now literally part of TRUST-BAND's
   collage instead of only appearing once MISSION-2 begins. Positioned in the one gap
   at the top of the collage that's clear of every card (dark ends left+width ~21.5%,
   aerial starts ~62.8%), so the divider + labels read on plain cream, not over a photo. */
/* Full section-width like the original mission2 version — z-index lifts it (and the
   cream chip behind each label) above the photo cards it now crosses, since at scroll
   progress 0 every .trust-band__card sits clustered at the stage's dead center
   (js/scroll-drift.js: drift = -offset * remaining, remaining=1 there), so the middle
   of this row isn't safe from card overlap even outside the two cards' final resting
   spots — the chip is what keeps the labels legible regardless of what's under them. */
.trust-band__meta-row {
  position: absolute;
  z-index: 5;
  top: 3.5%;
  left: 5.556%;
  width: 88.889%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 18px 0 38px;
  box-sizing: border-box;
  border-top: 1px solid var(--color-muted);
}
.trust-band__meta-row span { background: var(--color-cream); }
.trust-band__meta-row span:nth-child(1) { font-family: var(--font-body); font-size: clamp(13px, min(1.2vw, 1.9vh), 18px); letter-spacing: 0.2em; color: var(--color-ink); white-space: nowrap; padding: 4px 12px 4px 0; }
.trust-band__meta-row span:nth-child(2) { font-family: var(--font-body); font-size: clamp(13px, min(1.2vw, 1.9vh), 18px); letter-spacing: 0.136em; color: var(--color-muted); text-align: center; padding: 4px 16px; }
.trust-band__meta-row span:nth-child(3) { font-family: var(--font-display); font-size: clamp(24px, min(2.4vw, 3.8vh), 34px); color: var(--color-muted); padding: 4px 0 4px 12px; }

/* ==========================================================================
   TRUST-BAND (node 107:2) — statement + editorial photo collage
   Basis: 1440x778. Nested sub-degree counter-rotations on individual photos
   (Figma compensates rotated crops with oversized inner images) are
   simplified to a single rotate() on the card + object-fit: cover — visually
   equivalent for these decorative tilted photo cards.
   ========================================================================== */

.trust-band {
  position: relative;
  width: 100%;
  height: var(--h-home-trust);
  background: var(--color-cream);
}

/* Pinned inner stage: stays fixed at the true Figma-proportional height (86.444vh) and
   sticks to the top of the viewport for as long as the taller outer .trust-band spacer
   is scrolling past — same sticky-inside-a-taller-box pattern as the hero's #track/.stage.
   Every card's %-based position/size below resolves against THIS box, not the outer
   section, so changing the outer section's height (for animation timing) never
   re-scales the cards themselves. */
.trust-band__stage {
  position: sticky;
  top: 0;
  width: 100%;
  height: var(--h-home-trust-stage);
  overflow: hidden;
  /* Stage itself had no background of its own — only the outer spacer did — so for the
     brief scroll window right before the sticky pin fully engages, MISSION-1's tail
     (its heading sits close to its own section's bottom edge) could show through the
     gap above the stage's current position. An opaque background here closes that gap
     regardless of exact scroll timing, instead of just adding more clearance below the
     meta-row (which wouldn't touch this — it's a paint-order gap, not a spacing one). */
  background: var(--color-cream);
}

/* Pill + heading + body used to each be independently absolutely-positioned with a
   FIXED vertical gap baked in between them. That only holds up if the heading wraps to
   exactly as many lines as it did at the 1440x900 reference — shrink the window's
   height/aspect and the same font can still need more line-breaks than the fixed gap to
   .trust-band__body assumed, so the heading grows straight into the body text instead of
   pushing it down. Stacking them in real flow (a flex column) makes that structurally
   impossible: whatever height the heading actually renders at, the body starts after it. */
.trust-band__intro {
  position: absolute;
  left: 50%;
  top: 39.820%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.trust-band__pill {
  padding: 6px 0;
  width: 10.556vw;
  margin-bottom: 13px;
  border-radius: 20px;
  background: #d4d0c8;
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--color-ink);
}

.trust-band__heading {
  width: 39.583vw;
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: clamp(18px, min(3.333vw, 5.335vh), 48px);
  letter-spacing: -0.01em;
  color: var(--color-ink);
}

.trust-band__body {
  width: 26.736vw;
  margin: 0;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(11px, min(1.111vw, 1.778vh), 16px);
  line-height: 1.63;
  color: var(--color-ink);
}

.trust-band__proof-tag {
  margin: 4px 0 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(10px, 0.85vw, 12px);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* --drift-x/--drift-y are written by js/scroll-drift.js on scroll — default 0px so the
   card sits at its correct final Figma position with JS disabled/before it runs. */
.trust-band__card { position: absolute; overflow: hidden; transform: translate(var(--drift-x, 0px), var(--drift-y, 0px)); will-change: transform; }
.trust-band__card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Hover-zoom lives here, on the <img>, deliberately not on .trust-band__card above —
     that element's own `transform` is already claimed by --drift-x/--drift-y (see IMAGE
     HOVER ZOOM note at the top of this file); composing on separate elements avoids
     the one-`transform`-per-element collision. */
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}
.trust-band__card:hover img { transform: scale(1.08); }
.trust-band__card-label {
  position: absolute;
  left: 9.174%;
  font-family: var(--font-body);
  letter-spacing: 0.1em;
  white-space: nowrap;
}

.trust-band__card--dark {
  left: 4.665%; top: 11.928%; width: 16.853%; height: 40.862%;
  transform: translate(var(--drift-x, 0px), var(--drift-y, 0px)) rotate(2deg);
  border-radius: var(--radius-plate);
  background: var(--color-ink);
}

.trust-band__card--aerial {
  left: 62.847%; top: 7.815%; width: 14.583%; height: 32.134%;
  border-radius: var(--radius-plate);
  background: #8b8171;
}
.trust-band__card--aerial .trust-band__card-label { top: 88.8%; font-size: 9px; color: var(--color-cream); }

.trust-band__card--light-1 {
  left: 80.556%; top: 32.878%; width: 15.139%; height: 24.936%;
  border-radius: var(--radius-plate);
  background: #edeae1;
}
.trust-band__card--light-1 .trust-band__card-label { top: 86.598%; font-size: 9px; color: var(--color-muted); }

.trust-band__card--light-2 {
  left: 15.139%; top: 73.239%; width: 15.139%; height: 24.936%;
  border-radius: var(--radius-plate);
  background: #edeae1;
}

.trust-band__card--topo {
  left: 8.472%; top: 43.548%; width: 13.274%; height: 23.811%;
  transform: translate(var(--drift-x, 0px), var(--drift-y, 0px)) rotate(1deg);
  border-radius: var(--radius-plate);
  background: #d4d0c8;
}

.trust-band__card--cert {
  left: 78%; top: 13%; width: 14.028%; height: 15.167%;
  border-radius: var(--radius-plate);
  background: #c4bfb5;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8%;
}

/* Shrunk from a tall 31.105% stack down to a square-ish box (2026-09-04, per Arina:
   "add another card ... move logo grs there and other two logos make them side by
   side in the square card") holding just SA8000 + Fairtrade side by side now that GRS
   moved to its own --grs card below. Height matches --cert's own 15.167% so the two
   read as a matched pair of square cards, not one tall and one short. */
.trust-band__card--data {
  left: 70.972%; top: 65.527%; width: 15.417%; height: 15.167%;
  border-radius: 12px;
  background: #d3d5d9;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6%;
}

/* GRS split out into its own card, same square-card treatment and column as --data,
   sitting directly below it (2026-09-04, per Arina). Bottom edge lines up with
   --data's original bottom (65.527% + 31.105%) so the column's overall footprint in
   the collage is unchanged. */
.trust-band__card--grs {
  left: 58%; top: 81.465%; width: 15.417%; height: 15.167%;
  border-radius: 12px;
  background: #d3d5d9;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* All three cards hold certification logos (2026-09-03, per Arina — replaced text
   that repeated content shown elsewhere on the page; expanded 2026-09-04, per Arina:
   "add other certifications ... near smeta and that world stuff" — SMETA/SA8000 used
   to be the only two of the 7 certs not already covered by .trust-band__mini-
   collage's own 3, so this rounds the section out to all 7 without introducing cards
   that would risk colliding with the photo collage around them: cert holds SMETA +
   Bureau Veritas side by side, data holds SA8000 + Fairtrade side by side, grs holds
   GRS alone). Overrides the generic .trust-band__card img rule (width/height 100%,
   object-fit: cover) — a full-bleed crop is right for a photo but would crush/clip a
   logo, so this sizes it down and lets it sit fully visible via object-fit: contain
   instead. Sized down from 78% (2026-09-03, per Arina — was blurry): most of these
   source logos are small raster files (SA8000 is only 109x136px, Fairtrade Intl
   113x132px, GRS 230x113px, Bureau Veritas 256x124px), so scaling any one of them up
   toward the size of its card upscales well past native resolution and reads as
   soft/blurry — sizing for 2 sharing a card keeps each one closer to native size at
   typical viewport widths; grs alone in its card can run bigger. */
.trust-band__card--cert img,
.trust-band__card--data img {
  width: 40%;
  height: 74%;
  object-fit: contain;
}
.trust-band__card--grs img {
  width: 62%;
  height: 62%;
  object-fit: contain;
}

.trust-band__mini-collage {
  position: absolute;
  left: 31.464%; top: 15.548%;
  width: 18.958%; height: 16.581%;
  transform: translate(var(--drift-x, 0px), var(--drift-y, 0px)) rotate(-3.91deg);
  will-change: transform;
  background: #c4bfb5;
  border-radius: var(--radius-plate);
}
.trust-band__mini-collage img { position: absolute; object-fit: cover; border-radius: 4px; }
/* nth-child(1) is a certification logo (GOTS), not a photo — object-fit: cover in this
   tall narrow slot was cropping its circular badge down to an unrecognizable sliver.
   contain keeps the whole badge visible instead, per Arina 2026-09-03. No padding/chip
   background (removed 2026-09-03 per Arina — read as a boxed-in white tile) — the logo
   fills the slot edge to edge instead. */
.trust-band__mini-collage img:nth-child(1) {
  left: 8.791%; top: 18.605%; width: 28.205%; height: 62.791%;
  object-fit: contain;
}
.trust-band__mini-collage img:nth-child(2) { left: 37.363%; top: 18.605%; width: 29.670%; height: 62.791%; }
/* nth-child(3) (Fair Trade Certified) is also a logo badge, not a photo — same
   cover-crops-the-badge problem as nth-child(1) above (2026-09-04, per Arina: "make
   fair trade certificate not cropped on top and bottom"), same fix. */
.trust-band__mini-collage img:nth-child(3) {
  left: 66.667%; top: 19.380%; width: 28.571%; height: 61.240%;
  object-fit: contain;
}

/* ==========================================================================
   VIDEO-TRANSITION (replaces icon-detail 106:38, 2026-08-27 per Arina) — no
   image/text, a scroll-scrubbed WebGL crossfade between two b-roll clips.
   Section height is set by JS (js/index.js, same trackHeightPx() math as the
   hero's #track), not a fixed vh — it needs real scroll distance for 2 scenes
   + 1 transition + a short tail, which no static Figma proportion covers.
   .video-transition__stage is the same sticky-inside-a-taller-box pattern as
   the hero's #track/.stage and TRUST-BAND's .trust-band__stage.
   ========================================================================== */

.video-transition {
  position: relative;
  width: 100%;
}

.video-transition__stage {
  background: var(--color-ink) url('../assets/video/posters/la-fac-m1-mobile.webp') center / cover;
  position: sticky;
  top: 0;
  width: 100%;
  /* 100lvh rather than 100dvh, same reasoning as the hero's .stage (index.html): dvh
     re-sizes this pinned stage every time the mobile URL bar shows/hides, briefly
     leaving it shorter than the screen so the section below shows through underneath. */
  height: 100vh;
  height: 100lvh;
  /* Was `visible` for MISSION-2's 3D tufts, which were positioned to spill past this
     stage's edges on purpose. That content is gone (no .mission2-overlay markup left,
     and js/tuft-3d.js is no longer loaded), so the only thing still escaping was
     .vt-scene-text sliding in from off-screen — which widened the whole document and
     was the last real horizontal-scroll source on this page. Clipped now, matching the
     hero's own .stage. */
  overflow: hidden;
}

.video-transition__stage canvas {
  opacity: 0;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.video-transition__fallback-stage {
  position: absolute;
  inset: 0;
}
.video-transition__fallback-stage video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.video-transition__fallback-stage video.fallback-b,
.video-transition__fallback-stage video.fallback-c {
  opacity: 0;
  /* JS drives opacity directly per rAF tick for scrub-accurate crossfade; this
     transition only smooths out any single dropped frame, not the scrub itself —
     same pattern as the hero's .fallback-stage video.fallback-b/c/d/e above. */
  transition: opacity 40ms linear;
}

/* Flat dark scrim (2026-09-03 per Arina) so .vt-scene-text stays legible over the
   factory footage — bright equipment/lighting in all three clips, unlike the hero's
   darker cotton-field clips which never needed one. Flat rgba rather than a gradient
   since both text lines sit mid-frame (top: 38%/58%), not hugging one edge. */
.video-transition__scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.32);
  pointer-events: none;
}


/* Per-scene copy for VIDEO-TRANSITION's 3-clip sequence (LA-21/22/23) — same visual
   language as the hero's .hero-scene-text (fade + slide-into-the-edge, opacity/transform
   set per-frame by JS), just living on VIDEO-TRANSITION's own stage instead of the
   hero's. Kept as its own class rather than reusing .hero-scene-text directly since it
   resolves against a different stage/basis (this track's 100vh stage, not the hero's
   900px frame) — see wireVtSceneText() in js/index.js. */
.vt-scene-text {
  position: absolute;
  width: 25%;
  transform: translateY(-50%);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(20px, 2.222vw, 32px);
  line-height: 1.35;
  letter-spacing: 0.01em;
  color: #f5f5f5;
  opacity: 0;
  pointer-events: none;
}
/* Different heights (not both on the same center line) since these two show at the
   same time, unlike the hero's lines which rotate one-at-a-time — see .hero-scene-text
   above for the same top-per-element approach. */
.vt-scene-text--left { left: 6.944%; top: 38%; }
.vt-scene-text--right { right: 6.944%; text-align: right; top: 58%; }

/* ==========================================================================
   CERTS (node 361:2) — reuses the 7 cert logos already built for About Us
   Basis: 1440x280
   ========================================================================== */

.certs-band {
  position: relative;
  width: 100%;
  height: var(--h-home-certs);
  background: var(--color-cream);
}
.certs-band__rule { position: absolute; left: 0; width: 100%; height: 1px; background: var(--color-rule); }
.certs-band__rule--top { top: 0; }
.certs-band__rule--bottom { top: 99.643%; }

.certs-band__label {
  position: absolute;
  left: 50%;
  top: 12.857%;
  transform: translateX(-50%);
  width: 88.889%;
  text-align: center;
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.236em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.certs-band__row {
  position: absolute;
  left: 4.167%;
  top: 13.571%;
  width: 91.667%;
  height: 72.857%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* was a fixed "60px 0" — the row's own height scales with viewport height (vh), so
     a fixed-px padding ate a growing share of it on a short window, squeezing every
     logo well below its intended size. 6.667vh = 60px at the 900px reference height,
     but now scales together with the row instead of against it. */
  padding: 6.667vh 0;
  box-sizing: border-box;
}
.certs-band__row img { width: auto; object-fit: contain; }
.certs-band__logo--gots            { height: 100%; }      /* 84px / 84px */
.certs-band__logo--grs             { height: 88.1%; }      /* 74px / 84px */
.certs-band__logo--smeta           { height: 63.1%; }      /* 53px / 84px */
.certs-band__logo--fairtrade-intl  { height: 100%; }
.certs-band__logo--fair-trade-cert { height: 100%; }
.certs-band__logo--sa8000          { height: 100%; }
.certs-band__logo--bureau-veritas  { height: 86.9%; }      /* 73px / 84px */


/* ==========================================================================
   PROOF (node 151:2) — full-bleed field photo with heading + body
   Basis: 1440x693
   ========================================================================== */

.proof-band {
  position: relative;
  width: 100%;
  height: var(--h-home-proof);
  background: var(--color-cream);
}

.proof-band__plate {
  position: absolute;
  left: 0;
  top: 2%;                        /* was 5.051% */
  width: 100%;
  height: 96%;                    /* was 90.187% — taller per Arina */
  border-radius: var(--radius-plate);
  overflow: hidden;
}
.proof-band__plate img { width: 100%; height: 100%; object-fit: cover; display: block; }

.proof-band__kicker {
  position: absolute;
  left: 4.514%;
  top: 6.379%;                    /* bumped up further per Arina */
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.218em;
  text-transform: uppercase;
  color: var(--color-ink);
}
.proof-band__kicker span { display: block; }

.proof-band__index {
  position: absolute;
  right: 4.514%;
  top: 6.379%;                    /* see .proof-band__kicker */
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--color-muted);
}

.proof-band__heading {
  position: absolute;
  left: 25.625%;
  top: 6.379%;                    /* see .proof-band__kicker */
  width: 29.167%;
  font-family: var(--font-display);
  font-size: clamp(28px, 2.917vw, 42px);
  line-height: 1.286;
  text-transform: uppercase;
  color: #fafafa;
}

.proof-band__body {
  position: absolute;
  left: 54.792%;
  top: 7.676%;                    /* see .proof-band__kicker */
  width: 40.208%;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 14px;
  line-height: 1.786;
  color: #fafafa;
}

/* ==========================================================================
   SHEET-INFOGRAPHIC (node 393:2) — annotated sheet-set photo + swatches
   Basis: 1440x961. CONFIRMED EXCEPTION: 106.778vh, exceeds hero.
   ========================================================================== */

.sheet-band {
  position: relative;
  width: 100%;
  height: var(--h-home-sheet);
  background: var(--color-cream);
}

.sheet-band__rule { position: absolute; left: 5.556%; top: 0; width: 88.889%; height: 1px; background: var(--color-rule); }
.sheet-band__kicker { position: absolute; left: 5.556%; top: 4.995%; font-family: var(--font-body); font-size: 11px; letter-spacing: 0.218em; text-transform: uppercase; color: var(--color-ink); }
.sheet-band__figref { position: absolute; left: 5.556%; top: 7.700%; font-family: var(--font-body); font-size: 9px; letter-spacing: 0.133em; text-transform: uppercase; color: var(--color-muted); }
.sheet-band__index { position: absolute; right: 6.944%; top: 4.787%; font-family: var(--font-display); font-size: 16px; color: var(--color-muted); }

.sheet-band__heading {
  position: absolute;
  left: 50%;
  top: 13.319%;
  transform: translateX(-50%);
  width: 47.222%;
  text-align: center;
  font-family: var(--font-display);
  font-size: clamp(24px, 3.056vw, 44px);
  line-height: 1.16;
  white-space: nowrap;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* was width:44.444% + height:58.273% (two independent percentages, one of the
   section's width, one of its height) — since the section's height is vh-based and its
   width is viewport-width-based, those two axes scale at different rates whenever the
   window's aspect ratio isn't exactly Figma's reference, distorting this box away from
   the photo's actual 640x560 proportions. aspect-ratio locks the true shape and derives
   height from width alone, so the box (and everything positioned against it below)
   scales as one consistent unit on any window shape. */
.sheet-band__plate {
  position: absolute;
  left: 27.778%;
  top: 29.969%;
  width: 44.444%;
  aspect-ratio: 640 / 560;
  border-radius: var(--radius-plate);
  overflow: hidden;
}
/* object-position: center 32% (2026-09-04, per Arina: "make image fit better") — the
   photo is portrait (1856x2304, swirling fabric centered ~44% down, floating clear of
   both edges with a shadow beneath) against this box's landscape aspect-ratio
   (640/560), so cover crops vertically regardless. The previous "top" position aligned
   the crop window to the image's top edge, which left a large empty band of background
   above the fabric and clipped the shadow/lower curl below; 32% centers the crop
   window on the actual subject instead. Callout ring/line positions below were tuned
   to an even older folded-stack photo and point at approximate spots on this one —
   flag to Arina if they need retuning once she's seen it live. */
/* 48%, raised from 32% (2026-09-08, per Arina: "bring cotton sheet image up so it's
   not cut out"). The fabric occupies 17%-82% of the source height; at 32% the crop
   window sat over 9%-80% of the image, leaving dead background above and clipping the
   lower sweep. 48% centres the window on the fabric itself (14%-85%), so the whole
   piece is inside the frame with even margins top and bottom. */
.sheet-band__plate img { width: 100%; height: 100%; object-fit: cover; object-position: center 48%; display: block; }

.sheet-band__gots {
  position: absolute;
  left: 23.333%;
  top: 25.911%;
  width: 2.778%;
  aspect-ratio: 1;
}
.sheet-band__gots img { width: 100%; height: 100%; object-fit: contain; }

.sheet-band .callout-line--v { position: absolute; width: 1px; background: rgba(36, 30, 22, 0.35); }
.sheet-band .callout-line--h { position: absolute; height: 1px; background: rgba(36, 30, 22, 0.35); }
.sheet-band .callout-ring { position: absolute; width: 22px; height: 22px; border-radius: 50%; border: 1px solid rgba(36, 30, 22, 0.35); transform: translate(-50%, -50%); }
.sheet-band .callout-ring::after { content: ''; position: absolute; inset: 6px; border-radius: 50%; background: rgba(36, 30, 22, 0.6); }
.sheet-band .callout-label {
  position: absolute;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-ink);
  width: 20.556%;
  white-space: normal;
}

/* Every callout's vertical position (top/height) is now `calc(29.969% + Nvw)`: 29.969%
   is the plate's own top edge (a single vh-based anchor, consistent with the heading
   above it), and the vw term is that callout's offset DOWN INTO the plate, expressed
   against the plate's own aspect-ratio-derived height (44.444vw * 560/640 = 38.889vw)
   — so it scales together with the now-locked-aspect-ratio image instead of drifting
   away from it on a different window shape. Left/width stay plain % since horizontal
   was never vh/vw-mismatched. Ring left/top values are also corrected here: they use
   `transform: translate(-50%, -50%)` to center on the point, which needs the marker's
   CENTER coordinate — the previous values were the marker's top-left box corner
   instead (an 11px/1440 ≈0.764% constant error on every single ring, the reason dots
   never quite met their lines regardless of viewport). */

/* 100% premium cotton */
.sheet-band .c1-line-v { left: 36.111%; top: calc(29.969% + 2.361vw); height: 5.417vw; }
.sheet-band .c1-line-h { left: 27.083%; top: calc(29.969% + 2.361vw); width: 9.028%; }
.sheet-band .c1-ring { left: 36.111%; top: calc(29.969% + 7.778vw); }
.sheet-band .c1-label { left: 6.111%; top: calc(29.969% + 2.361vw); text-align: right; transform: translateY(-50%); }
/* long staple fibers */
.sheet-band .c2-line-v { left: 31.944%; top: calc(29.969% + 17.847vw); height: 4.653vw; }
.sheet-band .c2-line-h { left: 27.083%; top: calc(29.969% + 22.500vw); width: 4.861%; }
.sheet-band .c2-ring { left: 31.944%; top: calc(29.969% + 17.847vw); }
.sheet-band .c2-label { left: 6.111%; top: calc(29.969% + 22.500vw); text-align: right; transform: translateY(-50%); }
/* premium weave and finish */
.sheet-band .c3-line-v { left: 35.069%; top: calc(29.969% + 33.819vw); height: 4.653vw; }
.sheet-band .c3-line-h { left: 27.083%; top: calc(29.969% + 38.472vw); width: 7.986%; }
.sheet-band .c3-ring { left: 35.069%; top: calc(29.969% + 33.819vw); }
.sheet-band .c3-label { left: 6.111%; top: calc(29.969% + 38.472vw); text-align: right; transform: translateY(-50%); }
/* low impact dyes */
.sheet-band .c4-line-v { left: 62.847%; top: calc(29.969% + 2.361vw); height: 5.069vw; }
.sheet-band .c4-line-h { left: 62.847%; top: calc(29.969% + 2.361vw); width: 10.069%; }
.sheet-band .c4-ring { left: 62.847%; top: calc(29.969% + 7.431vw); }
.sheet-band .c4-label { left: 73.889%; top: calc(29.969% + 2.361vw); text-align: left; transform: translateY(-50%); }
/* exceptional softness and durability */
.sheet-band .c5-line-v { left: 66.667%; top: calc(29.969% + 18.889vw); height: 4.306vw; }
.sheet-band .c5-line-h { left: 66.667%; top: calc(29.969% + 23.194vw); width: 6.25%; }
.sheet-band .c5-ring { left: 66.667%; top: calc(29.969% + 18.889vw); }
.sheet-band .c5-label { left: 73.889%; top: calc(29.969% + 23.194vw); text-align: left; transform: translateY(-50%); }

/* 6th callout (was "Easy Care" + its care-note) and the color-swatch dots were removed
   2026-09-03 per Arina — swapped for a single "extensive palette" line below instead of
   the gray placeholder swatches. */
.sheet-band__colors-label {
  position: absolute;
  left: 50%;
  top: calc(29.969% + 40.488vw);  /* was 90.635% — see the c1-c6 comment above */
  transform: translateX(-50%);    /* was left:44.028% (an approximation) — true-centers
                                      regardless of text width, per Arina */
  width: 80%;
  text-align: center;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 13px;
  letter-spacing: 0.1em;
  font-variant: small-caps;
  color: var(--color-ink);
}

/* ==========================================================================
   THOUGHT-LEADERS (node 190:2) — heading/intro + featured quote on photo
   Basis: 1440x1072. CONFIRMED EXCEPTION: 119.111vh, exceeds hero.
   ========================================================================== */

.thought-leaders {
  position: relative;
  width: 100%;
  height: var(--h-home-thought-leaders);
  background: var(--color-cream);
}

.thought-leaders__rule { position: absolute; left: 5.556%; top: 0; width: 88.889%; height: 1px; background: var(--color-rule); }
.thought-leaders__kicker { position: absolute; left: 5.556%; top: 4.478%; width: 20.833%; font-family: var(--font-body); font-size: 11px; letter-spacing: 0.218em; text-transform: uppercase; color: var(--color-ink); }
.thought-leaders__index { position: absolute; right: 6.944%; top: 4.291%; font-family: var(--font-display); font-size: 16px; color: var(--color-muted); }

.thought-leaders__heading {
  position: absolute;
  left: 5.556%;
  top: 9.701%;
  width: 43.681%;
  font-family: var(--font-display);
  font-size: clamp(36px, 3.889vw, 56px);
  line-height: 1.179;
  text-transform: uppercase;
  color: var(--color-ink);
}

.thought-leaders__intro {
  position: absolute;
  left: 65.278%;
  top: 11.754%;
  width: 23.611%;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 14px;
  line-height: 1.714;
  color: var(--color-muted);
}

/* Carousel: 3 slides (Sadhguru / Dave Asprey / Bryan Johnson), autoplay every 5s,
   hover to pause — see js/thought-leaders-carousel.js. .thought-leaders__carousel has
   no position of its own on purpose, so each .thought-leaders__slide's
   `position: absolute` resolves straight against .thought-leaders (already
   position: relative) exactly as the single old .thought-leaders__photo/__panel pair
   did — no position math changes for slide 1, slides just stack on top of each other
   and only the active one is visible. */
.thought-leaders__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.8s ease;
  pointer-events: none;
}
.thought-leaders__slide.is-active {
  opacity: 1;
  pointer-events: auto;
}

/* Arrow buttons — siblings of the slides (see index.html), so they render outside the
   per-slide opacity/pointer-events toggle and stay clickable no matter which slide is
   active. Positioned against the photo plate's own vertical center (35% + 65%/2 =
   67.5%, matching .thought-leaders__photo below) rather than the panel, so they never
   depend on how tall any one slide's quote/bio text happens to run. Sized with clamp()
   instead of a media-query breakpoint — same fluid, viewport-scaled approach as every
   other measurement on this page, no fixed mobile/desktop split. */
.thought-leaders__arrow {
  position: absolute;
  top: 67.5%;
  transform: translateY(-50%);
  z-index: 2;
  width: clamp(34px, 3.472vw, 50px);
  height: clamp(34px, 3.472vw, 50px);
  border-radius: 50%;
  border: 1px solid rgba(250, 250, 250, 0.45);
  background: rgba(36, 30, 22, 0.35);
  color: #fafafa;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease, border-color 0.2s ease;
}
.thought-leaders__arrow:hover {
  background: rgba(36, 30, 22, 0.6);
  border-color: rgba(250, 250, 250, 0.8);
  transform: translateY(-50%) scale(1.08);
}
.thought-leaders__arrow svg { width: 42%; height: 42%; }
.thought-leaders__arrow--prev { left: 3.472%; }   /* 50px / 1440px, matches the arrow's own max width */
.thought-leaders__arrow--next { right: 3.472%; }

.thought-leaders__photo {
  position: absolute;
  left: 0;                        /* was 1.319% + width 99.028% (right edge landed at
                                      100.347%, past the section's own edge) — full
                                      bleed now, touching both sides evenly */
  top: 35%;                       /* was 43.004% */
  width: 100%;
  height: 65%;                    /* was 57% — taller per Arina; bottom now lands
                                      exactly at the section's own bottom edge */
  border-radius: var(--radius-plate);
  overflow: hidden;
}
.thought-leaders__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.thought-leaders__panel {
  position: absolute;
  left: 50%;
  top: 40%;                       /* was 50.746% — raised so slide 2/3's longer content
                                      clears the photo's bottom edge; applied to all 3
                                      slides so every panel sits at the same level */
  width: 43.056%;
}
.thought-leaders__num { font-family: var(--font-display); font-size: 16px; color: #fafafa; margin: 0 0 10px; }
.thought-leaders__num-rule { width: 93.548%; height: 1px; background: #fafafa; margin: 0 0 34px; }
.thought-leaders__quote {
  font-family: var(--font-display);
  font-size: clamp(22px, 2.361vw, 34px);
  line-height: 1.25;              /* was 1.412 — tighter per Arina, text was overflowing */
  color: #fafafa;
  margin: 0 0 16px;
}
.thought-leaders__cite {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #fafafa;
  margin: 0 0 26px;
}
.thought-leaders__bio-head {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.218em;
  text-transform: uppercase;
  color: #fafafa;
  margin: 0 0 12px;
}
.thought-leaders__bio {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 14px;
  line-height: 1.5;                /* was 1.714 — tighter per Arina, text was overflowing */
  color: #fafafa;
  width: 87.097%;
  margin: 0;
}

/* ==========================================================================
   JOURNAL (node 152:2) — "what we offer" 5-card grid
   Basis: 1440x1416. CONFIRMED EXCEPTION: 157.333vh, exceeds hero.
   ========================================================================== */

.journal {
  position: relative;
  width: 100%;
  height: var(--h-home-journal);
  background: var(--color-cream);
}

.journal__rule { position: absolute; left: 5.556%; top: 0; width: 88.889%; height: 1px; background: var(--color-rule); }
.journal__kicker { position: absolute; left: 5.556%; top: 3.390%; font-family: var(--font-body); font-size: 11px; letter-spacing: 0.218em; color: var(--color-ink); }
.journal__index { position: absolute; right: 5.556%; top: 3.249%; font-family: var(--font-display); font-size: 16px; color: var(--color-muted); }
.journal__heading {
  position: absolute;
  left: 5.556%;
  top: 7.345%;
  width: 45%;                   /* wide enough to hold "What we offer" on one line at max font-size */
  font-family: var(--font-display);
  font-size: clamp(48px, 5.417vw, 78px);
  text-transform: uppercase;
  color: var(--color-ink);
  white-space: nowrap;
}
.journal__learn-more {
  position: absolute;
  right: 11.111%;
  top: 8.898%;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 14px;
  color: var(--color-muted);
  text-decoration: underline;
}

.journal__card { position: absolute; }
.journal__plate { border-radius: var(--radius-plate); overflow: hidden; }
.journal__plate img { width: 100%; height: 100%; object-fit: cover; display: block; }
.journal__card-title { font-family: var(--font-display); font-size: 24px; line-height: 1.333; color: var(--color-ink); margin: 24px 0 0; }
.journal__card-title--upper { text-transform: uppercase; }
.journal__card-body { font-family: var(--font-body); font-weight: 300; font-size: 13px; line-height: 1.692; color: var(--color-muted); margin: 12px 0 0; }
.journal__card-body a { text-decoration: underline; color: var(--color-muted); }

.journal__card--1 { left: 5.556%; top: 21.186%; width: 26.389%; }
.journal__card--1 .journal__plate { aspect-ratio: 380 / 490; }
.journal__card--2 { left: 36.806%; top: 16.243%; width: 20.833%; }
.journal__card--2 .journal__plate { aspect-ratio: 300 / 390; }
.journal__card--3 { left: 62.778%; top: 15.678%; width: 31.944%; }
.journal__card--3 .journal__plate { aspect-ratio: 460 / 340; }
.journal__card--4 { left: 62.986%; top: 62.288%; width: 26.667%; }
.journal__card--4 .journal__plate { aspect-ratio: 384 / 230; }
.journal__card--5 { left: 33.194%; top: 61.441%; width: 24.306%; }
.journal__card--5 .journal__plate { aspect-ratio: 350 / 301; }

/* ==========================================================================
   CLOSING (node 153:2) — dark bleed-photo statement + CTA
   Basis: 1440x540
   ========================================================================== */

.closing {
  position: relative;
  width: 100%;
  height: var(--h-home-closing);
  background: var(--color-ink);
  overflow: hidden;
}
.closing__bleed, .closing__scrim { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Flex-centered stack (2026-09-03, per Arina) — replaces individually top%-positioned
   text elements, which overlapped once the heading wrapped to 2 lines (see the HTML
   comment above .closing__content in index.html). Flow spacing (margins on each child)
   means every element pushes the next one down by its own real rendered height,
   whatever that turns out to be, instead of assuming a fixed line count. */
.closing__content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 24px;
}

.closing__kicker {
  width: 62.5%;
  max-width: 500px;
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.236em;
  color: var(--color-ink);
  margin: 0 0 16px;
}

.closing__heading {
  width: 65.417%;
  max-width: 820px;
  font-family: var(--font-display);
  font-size: clamp(32px, 4.028vw, 58px);
  line-height: 1.241;
  text-transform: uppercase;
  color: var(--color-ink);
  margin: 0 0 24px;
}

.closing__body {
  width: 44%;
  min-width: 280px;
  max-width: 560px;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(14px, 1.25vw, 17px);
  line-height: 1.6;
  color: var(--color-ink);
  margin: 0 0 32px;
}

.closing__cta {
  width: 18.889%;
  min-width: 180px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-ink);
  border-radius: var(--radius-plate);
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--color-ink);
}

/* ==========================================================================
   FOOTER (node 153:11) — identical layout/content to About Us footer
   Basis: 1440x420
   ========================================================================== */

.footer {
  position: relative;
  width: 100%;
  height: var(--h-home-footer);
  background: var(--color-ink);
}

.footer__mark {
  position: absolute;
  top: 0;
  left: 5.556%;
  width: 19.895%;
  height: 38.333%;
  background-color: var(--color-cream);
  -webkit-mask-image: url("../assets/webp/wordmark-mask.webp");
  mask-image: url("../assets/webp/wordmark-mask.webp");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: left center;
  mask-position: left center;
}

.footer__tag {
  position: absolute;
  top: 35.714%;
  left: 5.556%;
  width: 23.611%;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(12px, 0.972vw, 14px);
  line-height: 1.7143;
  color: rgba(248, 245, 236, 0.6);
}

.footer__col { position: absolute; top: 20.952%; height: 35.714%; }
.footer__col--learn { left: 51.389%; }
.footer__col--company { left: 66.667%; }
.footer__col--connect { left: 81.944%; }

.footer__col-head {
  position: absolute;
  top: 0;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(9px, 0.764vw, 11px);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: #a89478;
  white-space: nowrap;
}

.footer__link {
  position: absolute;
  font-family: var(--font-body);
  font-weight: 300;
  font-size: clamp(12px, 0.972vw, 14px);
  color: rgba(248, 245, 236, 0.75);
  white-space: nowrap;
}
.footer__link:nth-of-type(1) { top: 25.333%; }
.footer__link:nth-of-type(2) { top: 45.333%; }
.footer__link:nth-of-type(3) { top: 65.333%; }
.footer__link:nth-of-type(4) { top: 85.333%; }

.footer__rule {
  position: absolute;
  top: 76.19%;
  left: 5.556%;
  width: 88.889%;
  height: 1px;
  background: rgba(248, 245, 236, 0.14);
}

.footer__meta {
  position: absolute;
  top: 82.857%;
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(9px, 0.694vw, 10px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(248, 245, 236, 0.45);
  white-space: nowrap;
}
.footer__meta--left { left: 5.556%; }
.footer__meta--right { right: 5.556%; }

/* ============================ MOBILE (2026-09-08) ============================
   First responsive pass on this page — it previously had no @media rules at all.
   Only the pieces that actually forced horizontal scroll on a phone are patched;
   the WebGL hero, TRUST-BAND drift (js/scroll-drift.js) and VIDEO-TRANSITION
   scroll math are deliberately left alone.
   ============================================================================= */
@media (max-width: 640px) {
  /* Seven height-sized logos in one space-between row are wider than the viewport
     and nothing can shrink — wrap them, capping by max-height so the designed
     relative sizing is kept. */
  .certs-band { height: auto; padding: 36px 0 32px; }
  .certs-band__label {
    position: static;
    transform: none;
    width: auto;
    padding: 0 5.556%;
    margin-bottom: 22px;
  }
  .certs-band__row {
    position: static;
    /* Capped so the seven logos break 4 + 3 instead of 5 + 2. Left to the full
       content width they just fit five on the first line, which leaves a stranded
       pair underneath and reads as a wrapping accident rather than a layout. Both
       rows stay centred, so the block is symmetrical either way. */
    width: auto;
    max-width: 292px;
    margin: 0 auto;
    height: auto;
    padding: 0;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 22px 24px;
  }
  .certs-band__row img { height: auto; max-width: 24vw; }
  .certs-band__logo--gots,
  .certs-band__logo--fairtrade-intl,
  .certs-band__logo--fair-trade-cert,
  .certs-band__logo--sa8000          { max-height: 42px; }
  .certs-band__logo--grs             { max-height: 37px; }
  .certs-band__logo--bureau-veritas  { max-height: 36px; }
  .certs-band__logo--smeta           { max-height: 26px; }

  /* nowrap label centered on a 13.75% point — half its own width lands off the
     left edge once the viewport is narrower than the label itself. */
  .mission1__eyebrow { left: 5.556%; transform: none; }

  /* 9px labels on collage cards that are only ~55px wide at this size: unreadable,
     and their nowrap text overhangs the card and the viewport. Hidden rather than
     clipped — the cards' own drift transforms are untouched. */
  .trust-band__card-label { display: none; }

  /* SHEET-INFOGRAPHIC callouts: every other part of this section scales with vw, but
     the labels were a fixed 16px inside 20.556%-wide boxes — on a phone that box is
     ~77px, so a single long word ("Exceptional") is wider than its own container and
     hangs off the right edge. Scale the type with the rest of the section. */
  .sheet-band .callout-label {
    font-size: clamp(8px, 2.6vw, 16px);
    letter-spacing: 0.04em;
    overflow-wrap: break-word;
  }

  /* Height in vw, not the base max(118vh, 64vw) (per Arina: "less space between
     extensive color palette and divider"). Every piece of this section is sized from
     the viewport WIDTH — the plate is 76vw wide at a 3/4 ratio, and the callouts and
     caption are all calc(% + Nvw) offsets from it — but the section's own height was
     viewport-HEIGHT driven, so on a tall phone it ran ~240px past the end of its own
     content. Driving the height off the same axis as the content keeps the tail gap
     constant instead of growing with screen height. */
  .sheet-band { height: 180vw; }

  /* Bigger fabric plate (per Arina: "make image wider and taller"). At the desktop
     44.444% width it is a small tile on a phone, with the section's own height mostly
     empty below it. Widened and given a portrait aspect so it fills the frame — the
     source photo is portrait (1856x2304), so a taller box also crops it far less. */
  .sheet-band__plate {
    left: 12%;
    width: 76%;
    aspect-ratio: 3 / 4;
  }
  /* Caption anchored to the plate's real bottom edge, not a section percentage. The
     plate is 76vw wide at 3/4, so it is 101.333vw tall and its bottom sits at
     calc(29.969% + 101.333vw) — expressing the caption against that same expression
     keeps it under the card at ANY viewport height. (A plain `top: 76%` worked only at
     the height I happened to test: the plate's height scales with viewport WIDTH while
     a percentage top scales with section HEIGHT, so on a shorter phone the caption
     climbed back onto the fabric.) */
  .sheet-band__colors-label { top: calc(29.969% + 101.333vw + 18px); }

  /* Callout markers were laid out for the old 38.889vw-tall plate, so on the enlarged
     101.333vw one they all bunched into the top third with their connector lines
     stopping well short of the fabric below. Every offset is scaled by the same
     101.333 / 38.889 = 2.606 factor, which spreads them down the full height of the
     card and keeps each ring on the same relative part of the image as before
     (per Arina: "arrows throughout the height"). */
  .sheet-band .c1-line-v { top: calc(29.969% + 6.15vw); height: 14.11vw; }
  .sheet-band .c1-line-h,
  .sheet-band .c1-label  { top: calc(29.969% + 6.15vw); }
  .sheet-band .c1-ring   { top: calc(29.969% + 20.27vw); }

  .sheet-band .c2-line-v { top: calc(29.969% + 46.51vw); height: 12.13vw; }
  .sheet-band .c2-ring   { top: calc(29.969% + 46.51vw); }
  .sheet-band .c2-line-h,
  .sheet-band .c2-label  { top: calc(29.969% + 58.64vw); }

  .sheet-band .c3-line-v { top: calc(29.969% + 88.13vw); height: 12.13vw; }
  .sheet-band .c3-ring   { top: calc(29.969% + 88.13vw); }
  .sheet-band .c3-line-h,
  .sheet-band .c3-label  { top: calc(29.969% + 100.26vw); }

  .sheet-band .c4-line-v { top: calc(29.969% + 6.15vw); height: 13.21vw; }
  .sheet-band .c4-line-h,
  .sheet-band .c4-label  { top: calc(29.969% + 6.15vw); }
  .sheet-band .c4-ring   { top: calc(29.969% + 19.36vw); }

  .sheet-band .c5-line-v { top: calc(29.969% + 49.22vw); height: 11.22vw; }
  .sheet-band .c5-ring   { top: calc(29.969% + 49.22vw); }
  .sheet-band .c5-line-h,
  .sheet-band .c5-label  { top: calc(29.969% + 60.44vw); }

  /* 40vw leaves the hero wordmark at ~156px on a phone — too small to carry the
     opening frame the way it does on desktop. */
  .hero-hand__logo { width: 56vw; }

  /* Both scene-text systems are 25% wide — ~94px on a phone, which wraps a short line
     into a tall narrow ribbon. Widen them (they no longer have to share the frame with
     a second column at this size) and keep them clear of the pinned header. */
  .hero-scene-text,
  .vt-scene-text { width: 62%; }
  .hero-scene-text { font-size: clamp(19px, 5.4vw, 32px); }
  .vt-scene-text { font-size: clamp(17px, 4.8vw, 32px); }

  /* Scene 3's line is the longest of the five, so at this width it wraps to five
     lines and its centred block sat higher up the frame than the others read. Dropped
     (per Arina: "lower"). */
  .hero-scene-text[data-scene="3"] { top: 68%; }

  /* VIDEO-TRANSITION's two lines show at the SAME time (unlike the hero's, which
     rotate one at a time), and 38%/58% leaves them bunched near the middle of a tall
     phone frame — they read as one block rather than two. Pushed apart so the upper
     line sits high and the lower line sits low, with the footage between them
     (per Arina: "higher text put higher and lower texts lower"). */
  .vt-scene-text--left { top: 24%; }
  .vt-scene-text--right { top: 76%; }

  /* Display headings held on one line by white-space:nowrap, with clamp() floors
     (48px / 24px) that stop them shrinking any further — so on a narrow phone the
     line is simply wider than the screen. Let them wrap instead. */
  .journal__heading,
  .sheet-band__heading {
    white-space: normal;
    width: 88.889%;
    font-size: clamp(28px, 8.5vw, 48px);
  }
  .sheet-band__heading { width: 83.333%; }

  /* FOOTER — this page keeps its own copy of the footer rules (the other three pages
     share about.css's), so the same mobile treatment is repeated here. Absolutely
     positioned against the 1440x420 desktop frame, the three columns' left:51%/67%/82%
     end up only ~76px apart on a phone and overlap each other. Flex-wrap instead: the
     wordmark, tagline, rule and meta lines are each full-width so they take their own
     rows, leaving the three link columns sharing one row as equal thirds — three
     columns on mobile too, per Arina (2026-09-08), just narrower. */
  .footer {
    height: auto;
    padding: 48px 5.556% 32px;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    column-gap: 10px;
  }
  .footer__mark {
    position: static;
    flex: 0 0 auto;
    width: 140px;
    height: auto;
    aspect-ratio: 136 / 77;
    margin: 0 0 28px;
  }
  .footer__tag {
    position: static;
    width: 100%;
    /* no max-width — see the note on this rule in about.css: a cap lets the three link
       columns squeeze into the leftover strip beside the tagline instead of wrapping */
    max-width: none;
    margin: 0 0 36px;
  }
  .footer__col {
    position: static;
    flex: 1 1 30%;
    min-width: 84px;
    height: auto;
    margin: 0 0 32px;
  }
  .footer__col-head {
    position: static;
    margin: 0 0 16px;
  }
  .footer__link {
    position: static;
    display: block;
    margin: 0 0 13px;
    white-space: normal;
    font-size: 12px;
  }
  .footer__link:nth-of-type(1),
  .footer__link:nth-of-type(2),
  .footer__link:nth-of-type(3),
  .footer__link:nth-of-type(4) {
    top: auto;
  }
  .footer__rule {
    position: static;
    width: 100%;
    margin: 8px 0 24px;
  }
  .footer__meta {
    position: static;
    display: block;
    width: 100%;
    margin: 0 0 8px;
    white-space: normal;
  }
  .footer__meta--left,
  .footer__meta--right {
    left: auto;
    right: auto;
  }

  /* ------------------------------------------------------------------------
     Sections still laid out as % of the 1440px desktop frame. Same failure as
     about.html's: the boxes don't grow with the text, so at phone width these
     were 60-115px wide columns of wrapped copy, some spilling past their own
     section into the next one. Widened / put back into flow.
     The TRUST-BAND card drift (js/scroll-drift.js) and the THOUGHT-LEADERS
     carousel (js/thought-leaders-carousel.js) are deliberately left working —
     only the text boxes around them change.
     ------------------------------------------------------------------------ */

  /* MISSION-1 — the eyebrow, body and label all share top:6.410% and are separated
     only HORIZONTALLY on desktop (left 13.75% / 50% / right 2.882%), so widening them
     for mobile makes all three land on top of each other. They're cream-coloured
     because they sit on the banner photo, so they can't simply be moved below it
     either. Stagger them down the banner instead, then put the swatch row and the
     heading below it, on a taller frame that fits the stack. */
  .mission1__frame { height: 580px; }
  .mission1__banner { height: 55%; }

  .mission1__eyebrow {
    left: 5.556%;
    top: 4%;
    transform: none;
    width: 88.889%;
    white-space: normal;
  }
  .mission1__body {
    left: 5.556%;
    top: 12%;
    transform: none;
    width: 88.889%;
    text-align: left;
  }
  .mission1__label {
    left: 5.556%;
    right: auto;
    /* Dropped from 34% (per Arina). Kept above 55%, which is where the banner photo
       ends — this text is cream, so below that line it would be invisible on cream. */
    top: 46%;
    text-align: left;
  }

  /* evenly spaced across the row rather than 2-left/1-far-right */
  .mission1__swatch {
    top: 58%;
    width: 26vw;
    height: 26vw;
  }
  .mission1__swatch--1 { left: 5.556%; }
  .mission1__swatch--2 { left: 37%; }
  .mission1__swatch--3 { left: 68.444%; }

  /* Anchored to the BOTTOM, not top:78% (2026-09-09, per Arina: "less space on the
     bottom"). A percentage top leaves whatever is left over below the heading — 85px
     of dead cream here — and that leftover grows or shrinks with the frame height
     rather than staying a deliberate margin. bottom pins the trailing gap at 30px
     regardless, so shortening the frame closes the hole instead of moving it. */
  .mission1__heading {
    left: 5.556%;
    top: auto;
    bottom: 30px;
    transform: none;
    width: 88.889%;
    text-align: center;
    font-size: clamp(24px, 7vw, 34px);
  }

  /* TRUST-BAND — text block only; the drifting cards are untouched */
  /* 80vw, not 84 — at 84 the copy ran edge-to-edge with the repositioned cards and
     the last word sat flush against one. This leaves a couple of percent of air. */
  .trust-band__heading { width: 80vw; }
  .trust-band__body { width: 80vw; }
  .trust-band__pill { width: auto; padding: 6px 18px; }

  /* The cards' Figma resting positions scatter them across the middle of the stage.
     That works at desktop width, where the centre copy is a narrow column with clear
     margins either side — but on a phone the copy runs nearly edge to edge, so the
     cards land straight on top of it and the text can't be read (per Arina).
     Re-placed smaller and out at the edges, several deliberately past the stage bounds
     so .trust-band__stage's overflow:hidden clips them — they drift out of frame as
     the animation completes, leaving the centre clear.
     Only the resting positions change: js/scroll-drift.js measures these at runtime
     and pulls each card to centre at progress 0, so the cluster-to-spread animation
     still works exactly as before, just with a wider spread. */
  /* These four sat across 1%-26%, which is exactly where the meta row ("100% Certified
     Organic / Seed to Bedding / 01") lives — 3% to 17% — so the row's text was landing
     on top of them. Dropped into the clear band between that row and the centre copy,
     which starts at 39.82%. */
  .trust-band__mini-collage      { left: 21%;  top: 19%;  width: 22%; height: 12%; }
  .trust-band__card--cert        { left: 60%;  top: 19%;  width: 21%; height: 11%; }
  .trust-band__card--dark        { left: -8%;  top: 20%;  width: 24%; height: 18%; }
  .trust-band__card--aerial      { left: 84%;  top: 20%;  width: 24%; height: 17%; }
  /* topo / light-1 / data sit level with the centre copy, and at 84vw that copy runs
     from 8% to 92% — so at left:-7% and left:86% these three still cut ~6% into it
     and the text read through the cards (per Arina: "cards block text"). Pushed out
     until their inner edges clear the copy entirely; the stage clips the remainder. */
  .trust-band__card--topo        { left: -14%; top: 30%;  width: 21%; height: 17%; }
  .trust-band__card--light-1     { left: 92%;  top: 34%;  width: 22%; height: 18%; }
  .trust-band__card--light-2     { left: -8%;  top: 72%;  width: 22%; height: 18%; }
  .trust-band__card--data        { left: 92%;  top: 64%;  width: 22%; height: 12%; }
  .trust-band__card--grs         { left: 28%;  top: 87%;  width: 22%; height: 12%; }

  /* CLOSING — "Let's create something beautiful together." was breaking over four
     lines: the heading keeps its desktop 65.417% width, which is only ~255px on a
     phone, while its font-size can't drop below the 32px clamp floor. Widened and
     scaled down together so it sets in two, plus more headroom above (per Arina). */
  .closing__content { padding: 64px 20px 44px; }
  .closing__heading {
    width: 88%;
    font-size: clamp(21px, 7.1vw, 34px);
  }
  .closing__kicker { width: 88%; }

  /* PROOF-BAND — kicker / heading / body are again three columns sharing one top,
     laid over a full-bleed photo. Stagger them down the plate rather than widening
     them into each other; they stay on the photo so their light colour still reads. */
  .proof-band__kicker { left: 5.556%; top: 4%; }
  .proof-band__index { right: 5.556%; top: 4%; }
  .proof-band__heading {
    left: 5.556%;
    top: 11%;
    width: 88.889%;
    font-size: clamp(24px, 6.6vw, 34px);
  }
  .proof-band__body {
    left: 5.556%;
    top: 70%;
    width: 88.889%;
  }

  /* THOUGHT-LEADERS — the three slides stay stacked (that IS the crossfade), but
     as grid cells sharing one cell instead of absolute fills, so the section can
     size itself to the tallest slide rather than clipping the longest bio. */
  .thought-leaders { height: auto; padding: 34px 0 44px; }
  .thought-leaders__rule { position: static; margin: 0 0 24px; }
  .thought-leaders__kicker,
  .thought-leaders__heading,
  .thought-leaders__intro {
    position: static;
    width: auto;
    margin: 0 5.556% 18px;
  }
  .thought-leaders__heading { font-size: clamp(28px, 8vw, 44px); }
  .thought-leaders__index { top: 34px; right: 5.556%; }
  .thought-leaders__carousel { position: relative; display: grid; }
  .thought-leaders__slide {
    position: relative;
    inset: auto;
    grid-area: 1 / 1;
  }
  /* Quote sits ON the portrait, and only the quote (2026-09-09, per Arina: "move only
     big text to the cards and remove small texts"). The supporting matter — slide
     number, rule, "Who He Is" label and the long bio — is hidden at this width: it was
     the bulk of the section's height and the reason each slide ran to ~750px.
     Because the type is back over the photo it returns to #fafafa, with a bottom-up
     scrim behind it so it stays legible over whichever portrait is showing. */
  .thought-leaders__photo {
    position: relative;
    /* top:35% carries over from the desktop rule, and on a RELATIVE element a
       percentage top still offsets it — by 35% of the slide's height, i.e. ~147px
       down — which pushed the photo out the bottom of the carousel box and left a
       gap under the intro. Reset explicitly. */
    top: auto;
    left: 0;
    width: 100%;
    /* Tall enough to give the portrait presence while the bottom-anchored quote still
       sits clear of the subject's face. */
    height: 460px;
  }
  /* All three portraits are wide 2.33:1 frames with the subject in the left ~20% and
     empty studio backdrop filling the right. Cover-fitting them into this tall box
     crops to the horizontal centre, which is pure background — the faces were gone
     entirely. Anchor the crop to where the subjects actually are. */
  .thought-leaders__photo img { object-position: 20% center; }
  .thought-leaders__photo::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(36, 30, 22, 0.78) 0%, rgba(36, 30, 22, 0.3) 46%, rgba(36, 30, 22, 0) 78%);
    pointer-events: none;
  }
  .thought-leaders__panel {
    position: absolute;
    left: 6%;
    right: 6%;
    /* top:auto matters. The desktop rule sets top:40%, and an absolutely positioned
       box given BOTH top and bottom is stretched between them instead of sizing to its
       content — so the panel was 278px tall for ~95px of text, which pinned the quote
       to the 40% line no matter how much taller the card got. With top released it
       hugs the bottom, putting the text in the lower half on every slide. */
    top: auto;
    bottom: 22px;
    width: auto;
    margin: 0;
  }
  .thought-leaders__num,
  .thought-leaders__num-rule,
  .thought-leaders__bio-head,
  .thought-leaders__bio { display: none; }
  .thought-leaders__quote {
    font-size: clamp(18px, 4.9vw, 24px);
    color: #fafafa;
    margin: 0 0 10px;
  }
  .thought-leaders__cite { color: rgba(250, 250, 250, 0.86); }
  /* The arrows sit at top:67.5% of the slide, which on desktop is clear of the panel
     but here lands exactly on the attribution line. Centred on the card instead —
     still clear of the quote, which starts lower down. */
  .thought-leaders__arrow { top: 50%; }
  .thought-leaders__arrow--prev { left: 5%; }
  .thought-leaders__arrow--next { right: 5%; }

  /* JOURNAL — five absolutely-placed cards become one column */
  .journal { height: auto; padding: 30px 0 44px; }
  .journal__rule { position: static; width: 88.889%; margin: 0 auto 22px; }
  .journal__kicker { position: static; display: block; margin: 0 5.556% 16px; }
  .journal__index { top: 30px; right: 5.556%; }
  .journal__heading {
    position: static;
    width: auto;
    margin: 0 5.556% 20px;
  }
  .journal__learn-more {
    position: static;
    display: inline-block;
    margin: 0 5.556% 26px;
  }
  .journal__card {
    position: static;
    width: auto;
    margin: 0 5.556% 34px;
  }
  .journal__card--1,
  .journal__card--2,
  .journal__card--3,
  .journal__card--4,
  .journal__card--5 { left: auto; top: auto; width: auto; }
  .journal__card-title { font-size: 21px; margin-top: 18px; }
}

/* Decorative video layers must never capture a swipe on iOS. */
.fallback-stage, .video-transition__fallback-stage, #gl, #vtGl {
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  #video-transition { height: 100svh !important; }
}

