/* ============================================================
   SECTIONS — Terminal-style structure, Recykal.Market skin
   Light #fafafa canvas · dark #16160f bands · black CTAs
   ============================================================ */

/* ---------- 1. HERO — single still, single headline ---------- */
/* Was 400vh: four viewports of scroll track for the sticky panel to scrub the
   367-frame sequence and swap three headlines through. Both are paused, so that
   track became ~3 viewports of scrolling with nothing changing on screen.
   100vh makes the hero exactly one screen and hands straight off to the next
   section. Restore 400vh alongside the frame sequence and the extra beats. */
.hero { position: relative; height: 100vh; background: var(--band); }
.hero__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.hero__bg { position: absolute; inset: 0; }
/* Canvas draws its own crop-to-fill in JS (drawHeroFrame in main.js), so it
   only needs to occupy the box here — display:block drops the few px of
   inline-baseline gap a <canvas> has by default. The source frames render
   flat/dull straight out of the renderer, so punch up brightness/contrast
   here rather than baking it into every one of the 367 images. */
.hero__bg canvas { display: block; width: 100%; height: 100%; filter: brightness(1.18) contrast(1.14) saturate(1.08); }
.hero__backdrop { position: absolute; inset: 0; background: rgba(10, 10, 10, .35); }
/* No `position` here on purpose: .hero__titles only ever holds absolutely
   positioned .beat elements, so as a positioned container itself it would
   collapse to 0 height and every .beat's `top: %` would resolve against
   that 0px box (always landing at 0) instead of the hero's real height.
   Leaving it static makes the sticky hero panel the containing block for
   the beats' percentages instead. */
.hero__titles { z-index: 2; text-align: center; padding: 0 var(--grid-margin); width: 100%; }
/* Both the kicker and the scrolling headline now sit low: the static
   eyebrow rides on top of the headline, which in turn sits just above
   the CTA row. The beats are bottom-anchored so multi-line copy grows
   upward toward the eyebrow instead of down into the CTAs. */
.hero .hero-eyebrow {
  position: absolute;
  /* Offset splits into two parts: 3px reclaims the baseline lost when the
     eyebrow dropped to 13px (the box is bottom-anchored, so a shorter line
     box pushes the text down), plus 12px of deliberate breathing room over
     the 58px headline. Only the wide layout needs the extra 12px -- below
     640px the headline shrinks and the gap opens up on its own. */
  bottom: calc(16.5rem + 15px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  white-space: nowrap;
}
.hero .beat {
  position: absolute;
  left: 50%;
  bottom: 8rem;
  width: min(92vw, 1100px);
  transform: translateX(-50%) translateY(28px);
  /* Own typography, decoupled from .title-hero/--fs-hero (that token now
     drives the smaller, fixed-size Display/H1 role used elsewhere, e.g.
     the final-CTA heading) — matches recykal.market/plastic's actual live
     hero exactly: weight 500, up to 58px, -0.03em tracking, 1.2 leading.
     The mobile clamp below already matched live and is untouched. */
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.375rem, 5.2vw, 58px);
  letter-spacing: -0.03em;
  line-height: 1.2;
  color: var(--white);
  opacity: 0;
  transition: opacity .5s var(--ease), transform .5s var(--ease);
  text-wrap: balance;
}
.hero .beat.is-active { opacity: 1; transform: translateX(-50%) translateY(0); }
.hero .beat.is-past { opacity: 0; transform: translateX(-50%) translateY(-28px); }
.hero .beat em { font-style: normal; color: var(--mint); }
.hero__ctas {
  position: absolute;
  bottom: 3.5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  gap: .75rem;
}
.hero__scroll-hint {
  position: absolute;
  bottom: 1.75rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  color: var(--white-56);
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: .1em;
  text-transform: uppercase;
  animation: hint-bob 2.2s var(--ease) infinite;
  transition: opacity var(--dur-fast);
}
@keyframes hint-bob { 0%, 100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, 8px); } }

/* Short viewports (landscape phones): the beat title sits at a fixed 50%
   and the CTAs at a fixed distance from the bottom, so on a ~375px-tall
   screen the two collide. Shift the title up, pull the CTAs in, and drop
   the scroll hint to give both room. */
/* Narrow screens: the headline wraps to more lines (the longest beat hits
   4 lines), so lift the static eyebrow to keep it clear of the tallest
   headline instead of overlapping it. */
@media (max-width: 640px) {
  .hero .hero-eyebrow { bottom: calc(14rem + 3px); }
  /* smaller headline on phones so it sits comfortably over the full-screen truck */
  .hero .beat { font-size: clamp(1.5rem, 7vw, 2rem); line-height: 1.18; }
}

@media (max-height: 560px) {
  .hero .hero-eyebrow { bottom: calc(8rem + 3px); }
  .hero .beat { bottom: 4rem; }
  .hero__ctas { bottom: 1.5rem; }
  .hero__scroll-hint { display: none; }
}

/* ---------- 3. FEATURED IN (light) ---------- */
.press { background: var(--bg); padding: 0 0 2rem; }
.press__intro { text-align: center; margin-bottom: 48px; padding: 0 var(--grid-margin); } /* 0.5in gap before logo grid */
.press__intro .eyebrow-wide { display: block; margin-bottom: 1rem; }
.press__intro h2 { color: #000; }

/* ---------- 2. CATEGORIES (light, centered) ---------- */
.statement {
  min-height: 60svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 0 var(--grid-margin);
  background: var(--bg);
}
.statement .eyebrow { margin-bottom: 1.5rem; }
.statement h2 { max-width: 24ch; color: #000; font-size: var(--fs-h2); }
.statement h2 em { font-style: normal; color: #000; }
.statement .sub { margin-top: 1.75rem; max-width: 46rem; color: var(--ink-56); }
.statement .chips { display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center; margin-top: 2.25rem; }
/* Catalogue variant: content-height, extra top/bottom room for the card grid */
.statement--catalog { min-height: auto; padding-top: .5rem; padding-bottom: 1rem; }

/* ---------- 3. FEATURE SCRUB (light background, 01–06 + finale) ---------- */
.feature-scrub { position: relative; height: 900vh; background: var(--bg); } /* 8 steps ≈ same per-step pacing as the old 6×700vh */
.feature-scrub__sticky {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  padding: 0 var(--grid-margin);
  background: var(--bg);
}
@media (min-width: 1024px) {
  .feature-scrub__sticky { grid-template-columns: 1fr 1fr; column-gap: clamp(2rem, 4vw, 5rem); }
}
.feature-scrub__copy { position: relative; z-index: 2; }
.feature-scrub__copy .eyebrow { display: block; margin-bottom: 2rem; }
/* Rolling odometer counter — each column shows one digit of a 0–9 stack */
.scrub-odometer {
  display: none;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: clamp(2.625rem, 6vw, 5.625rem);
  line-height: 1;
  color: var(--mint);
  margin-bottom: 1.75rem;
}
.odo-col { display: block; height: 1em; overflow: hidden; }
.odo-stack { display: block; transition: transform .6s var(--ease); will-change: transform; }
.odo-digit { display: block; height: 1em; line-height: 1; }
.odo-total { color: var(--white-20); margin-left: .08em; }

/* Mobile step markers (01–06) — mono numerals, active one lit; hidden on
   desktop where the full item list plays that role */
.scrub-steps { display: none; gap: 1.4rem; margin-bottom: 1.1rem; }
.scrub-steps button {
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: .04em;
  color: var(--ink-warm);
  opacity: .3;
  padding: .25rem 0;
  transition: opacity .3s var(--ease);
}
.scrub-steps button.is-active { opacity: 1; }

/* Item list — one USP at a time: every item occupies the same grid cell
   (container height = tallest item, so no layout jump between steps) and
   inactive ones are fully hidden, not dimmed. The sticky grid's
   align-items: center then keeps the compact copy column vertically
   centered against the media panel. */
.scrub-items { display: flex; gap: 1.5rem; }
.scrub-items-list { display: grid; flex: 1; min-width: 0; }
.scrub-item {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(16px);
  /* visibility flips to hidden INSTANTLY when an item goes inactive (no
     delayed-hide) so the outgoing USP disappears the moment the next one
     takes over — otherwise both stay painted in the same stacked grid
     cell for .45s and the overlapping text reads as a duplicated USP.
     Only the incoming item animates (fade + slide up). */
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.scrub-item.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.scrub-item__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: -.02em;
  text-transform: uppercase;
  color: var(--green);
  margin-bottom: .25rem;
  opacity: 0;
  transition: opacity .4s var(--ease);
}
.scrub-item.is-active .scrub-item__label { opacity: 1; }
.scrub-item__title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.5rem, 2.5vw, 2.2rem);
  letter-spacing: var(--ls-display);
  line-height: 1.25;
  color: var(--ink-warm);
}
/* chars sit dim by default; going active sweeps them to full opacity
   left-to-right via per-char --v-delay set in JS */
.scrub-item__title .chw { display: inline-block; white-space: nowrap; }
.scrub-item__title .ch {
  display: inline-block;
  opacity: .4;
  transition: opacity .3s var(--ease);
  transition-delay: 0s;
}
.scrub-item.is-active .scrub-item__title .ch { opacity: 1; transition-delay: var(--v-delay, 0s); }
.scrub-item__desc {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  margin-top: 0;
  color: var(--ink-56);
  font-size: var(--fs-small);
  max-width: 30rem;
  transition: max-height .5s var(--ease), opacity .4s var(--ease), margin-top .5s var(--ease);
}
.scrub-item.is-active .scrub-item__desc { max-height: 9em; opacity: 1; margin-top: .4rem; }

/* Vertical progress scrollbar beside the list */
.scrub-scrollbar { width: 2px; border-radius: 2px; background: var(--line); align-self: stretch; }
.scrub-scrollbar__fill { width: 100%; height: 0%; border-radius: 2px; background: var(--green); transition: height .3s var(--ease); }

/* Media panel — clipped with a bottom-left notch tab holding prev/next */
/* Portrait ratio (3/4) matches the portrait phone screenshots. The panel
   is a grid item in an auto-sized row, so a plain `max-height: 100%`
   never resolves (percentage heights need a definite-height containing
   block) — it silently did nothing, letting the panel grow past 100svh
   on wide screens where the column got wide, and get clipped by the
   sticky panel's overflow:hidden. Cap via max-width instead, converting
   the height budget through the ratio, so the box shrinks uniformly
   (never distorts) and never exceeds the sticky viewport on any width. */
/* Matches the USP videos' own 1336×1548 shape exactly — the previous 3:4
   box was close but not exact, so `cover` had to scale enough to crop the
   videos' left/right edges to fill the extra width. */
.feature-scrub__media { position: relative; z-index: 1; display: none; aspect-ratio: 1336 / 1548; width: 100%; max-width: calc(76svh * 1336 / 1548); }
@media (min-width: 1024px) { .feature-scrub__media { display: block; } }
.scrub-media__clip {
  position: absolute;
  inset: 0;
  border-radius: 16px;
  overflow: hidden;
  /* bottom notch tab, beveled. Inline polygon instead of an SVG url()
     reference: iOS/macOS Safari fails url() clip-paths on HTML elements
     and renders the whole element invisible. */
  clip-path: polygon(0 0, 100% 0, 100% 95.2%, 54.5% 95.2%, 39.6% 100%, 14.8% 100%, 0 95.2%);
}
.feature-scrub__media .media-frame { position: absolute; inset: 0; height: 100%; opacity: 0; transition: opacity .45s var(--ease); border-radius: 16px; overflow: hidden; }
.feature-scrub__media .media-frame.is-active { opacity: 1; }
.scrub-media__buttons {
  position: absolute;
  left: 16%;
  bottom: 0;
  z-index: 4;
  display: flex;
  gap: .5rem;
}
.scrub-media__buttons button {
  width: 42px;
  height: 32px;
  display: grid;
  place-items: center;
  color: var(--ink-warm);
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(250, 250, 250, .8);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: color .15s ease, border-color .15s ease, opacity .15s ease;
}
.scrub-media__buttons button:hover:not(:disabled) { color: var(--green); border-color: var(--green); }
.scrub-media__buttons button:disabled { opacity: .3; cursor: default; }

/* Below 1024px — Terminal-style mobile carousel: full-bleed video panel
   on top (notch clip + arrows kept, arrows enlarged and moved to the
   right edge), mono step numbers under it, the active title as a wide
   card with the next one peeking in from the right, and a horizontal
   progress bar. Arrows and step taps drive it — no scroll-jack. */
@media (max-width: 1023px) {
  .feature-scrub { height: auto; }
  .feature-scrub__sticky {
    position: relative;
    height: auto;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 0 0 3.5rem;
  }
  .feature-scrub__media {
    display: block;
    order: -1;
    aspect-ratio: auto;
    height: min(66svh, 620px);
    background: var(--band);
  }
  .scrub-media__clip, .feature-scrub__media .media-frame { border-radius: 0; }
  .feature-scrub__media video { width: 100%; height: 100%; object-fit: cover; }
  .scrub-media__buttons {
    left: auto;
    right: var(--grid-margin);
    bottom: calc(4.8% + 1rem);
    gap: .75rem;
  }
  .scrub-media__buttons button {
    width: 56px;
    height: 48px;
    border-radius: 12px;
    background: rgba(250, 250, 250, .92);
  }

  .feature-scrub__copy { padding: 2.25rem var(--grid-margin) 0; }
  .feature-scrub__copy .eyebrow { margin-bottom: 1.5rem; }
  .scrub-steps { display: flex; }

  /* horizontal card track — one step per card, next title peeks in dimmed */
  .scrub-items { display: block; overflow: hidden; }
  .scrub-items-list {
    display: flex;
    gap: 0;
    transform: translateX(calc(var(--scrub-idx, 0) * -86%));
    transition: transform .55s var(--ease);
  }
  /* carousel cards stay in normal flow (flex row), so undo the desktop
     stack-and-hide: peeking neighbours are dimmed, never hidden. Plain
     opacity transition only — the base rule's delayed visibility flip
     must not apply here or a desktop→mobile resize strands cards hidden. */
  .scrub-item {
    flex: 0 0 86%;
    min-width: 0;
    padding-right: 1.5rem;
    opacity: .22;
    visibility: visible;
    transform: none;
    transition: opacity .4s var(--ease);
  }
  .scrub-item.is-active { opacity: 1; }
  .scrub-item__title { font-size: clamp(1.6rem, 6.4vw, 2.1rem); }
  .scrub-item.is-active .scrub-item__desc { max-height: 14em; }

  /* progress bar goes horizontal under the track */
  .scrub-scrollbar { width: 100%; height: 2px; align-self: auto; margin-top: 1.75rem; }
  .scrub-scrollbar__fill { height: 100%; width: 0%; transition: width .45s var(--ease); }
}

/* ---------- 5. AUDIENCES (For Sellers / Buyers blocks, light) ---------- */
.audiences { background: var(--bg); padding: 0; }
.audiences__intro { text-align: center; padding: 0 var(--grid-margin) 2.5rem; }
.audiences__intro .eyebrow { display: block; margin-bottom: 1.25rem; }
.audiences__intro h2 { color: #000; max-width: 24ch; margin: 0 auto; }
.audiences__intro .sub { margin-top: 1.25rem; color: var(--ink-56); max-width: 40rem; margin-left: auto; margin-right: auto; }
.audience {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  padding: 3rem var(--grid-margin);
  border-top: 1px solid var(--line);
  align-items: stretch;
}
/* Mobile/tablet: DOM order alone puts the dashboard visual between the
   intro copy and the detailed feature cards — image first, specs after,
   instead of forcing readers through four cards before they see anything. */
.audience .feature-list { margin-top: 1.75rem; }
@media (min-width: 1024px) {
  /* Desktop: back to the original 2-column layout — intro copy and the
     feature cards stack in the left column, the visual anchors the right
     column across both rows (media-natural's own align-self:center keeps
     it from looking stranded beside the taller text column). */
  .audience {
    grid-template-columns: 5fr 7fr;
    grid-template-rows: auto 1fr;
    grid-template-areas: "intro media" "details media";
  }
  .audience .aud-intro { grid-area: intro; }
  .audience .aud-details { grid-area: details; }
  .audience .media-natural { grid-area: media; }
}
/* The mockup renders at its own true aspect ratio (width:100%/height:auto,
   the base .media-natural img rule) instead of being stretched/cropped to
   match the text column's height — the whole screenshot is always fully
   visible, on every device, never cropped. Centered vertically so it
   doesn't look stranded beside the taller text column. */
.audience .media-natural { align-self: center; }
.audience .aud-label { display: block; margin-bottom: 1rem; }
/* mockup image settles from a gentle zoom as the audience block reveals */
.audience .media-natural img { transform: scale(1.04); transition: transform 1.1s var(--ease); }
.audience.is-in .media-natural img { transform: none; }
@media (prefers-reduced-motion: reduce) { .audience .media-natural img { transform: none; transition: none; } }
.audience h3 { font-family: var(--font-display); font-weight: 600; color: var(--ink-warm); font-size: var(--fs-h3); line-height: var(--lh-h3); }
.audience h3 em { font-style: normal; color: #000; }
.audience .aud-sub { margin-top: 1rem; color: var(--ink-56); max-width: 30rem; }
.audience .aud-cta { margin-top: 1.75rem; }
/* USP cards — numbered bento tiles: mono index chip, hairline card,
   top accent line that draws in on hover, gentle lift */
.feature-list { display: grid; gap: .8rem; margin-top: .5rem; }
@media (min-width: 768px) { .feature-list { grid-template-columns: 1fr 1fr; } }
.feature-list .f {
  position: relative;
  padding: 1.25rem 1.25rem 1.4rem;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 12px 28px -22px rgba(22, 22, 15, .28);
  transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.feature-list .f::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, var(--green), #b9f0c9);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .45s var(--ease);
}
.feature-list .f:hover {
  border-color: rgba(27, 139, 58, .35);
  transform: translateY(-3px);
  box-shadow: 0 18px 32px -24px rgba(22, 22, 15, .35);
}
.feature-list .f:hover::before { transform: scaleX(1); }
.f__idx {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1;
  color: var(--ink-warm);
  background: var(--paper-3);
  border: 1px solid transparent;
  border-radius: 999px;
  padding: .3rem .55rem;
  margin-bottom: .8rem;
  transition: background-color .3s var(--ease), color .3s var(--ease);
}
.feature-list .f:hover .f__idx { background: var(--green); color: var(--white); }
.feature-list .f h4 { font-family: var(--font-display); font-weight: 500; font-size: 18px; letter-spacing: var(--ls-display); color: var(--ink-2); }
.feature-list .f p { margin-top: .4rem; color: var(--ink-56); font-size: var(--fs-small); }
@media (prefers-reduced-motion: reduce) {
  .feature-list .f, .feature-list .f::before, .f__idx { transition: none; }
}
.audience .media-frame { grid-column: 1 / -1; }
@media (min-width: 1024px) { .audience .media-frame { grid-column: 2; } }

/* ---------- 6. VOICES (dark band, testimonial cards) ---------- */
/* Unlike the light folds (which sit flush and let the light connector
   supply the gap), this is a distinct dark container — it needs its own
   internal vertical padding so the heading and cards aren't flush against
   the band edges. The 1.5in fold gap still comes from the connectors
   above/below; this padding lives INSIDE the band. */
.voices { padding: 4.5rem 0; }
.voices .voices__intro { text-align: center; padding: 0 var(--grid-margin) 2.5rem; }
.voices .voices__intro .eyebrow { display: block; margin-bottom: 1.25rem; }
.voices .voices__intro h2 { color: var(--white); }
.voices .voices__intro .sub { margin-top: 1rem; color: var(--white-56); max-width: 38rem; margin-left: auto; margin-right: auto; }
.testimonials { display: grid; grid-template-columns: 1fr; gap: 2rem; padding: 0 var(--grid-margin); max-width: 100%; margin: 0 auto; }
@media (min-width: 768px) { .testimonials { grid-template-columns: repeat(3, 1fr); } }
.testimonials--grid { position: relative; width: 100%; }
figure.testimonial-card {
  background: rgb(31, 31, 31);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 24px;
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  transition: background .35s var(--ease), border-color .35s var(--ease), transform .35s var(--ease);
  margin: 0;
}
figure.testimonial-card:hover { background: rgb(41, 41, 41); border-color: rgba(255, 255, 255, .2); transform: translateY(-4px); }
.testimonial-card__header { display: flex; align-items: center; }
figure.testimonial-card .tag { color: var(--mint); font-family: var(--font-mono); font-size: 13px; text-transform: uppercase; letter-spacing: -.02em; }
figure.testimonial-card .quote { color: var(--white); font-size: 15px; line-height: 1.6; flex: 1; }
figure.testimonial-card blockquote { margin: 0; }
figure.testimonial-card .quote::before { content: '"'; font-size: 2rem; color: var(--mint); line-height: 0; vertical-align: -0.4em; margin-right: 0.25rem; }
figure.testimonial-card .attribution { display: flex; flex-direction: column; gap: .25rem; margin-top: auto; border-top: 1px solid rgba(255, 255, 255, .12); padding-top: 1.5rem; }
figure.testimonial-card .attribution .name { color: var(--white); font-weight: 500; font-size: 15px; }
figure.testimonial-card .attribution .role { color: var(--white-56); font-size: var(--fs-small); }

/* ---------- 7. REACH (light — video centered) ---------- */
.reach { background: var(--paper-2); padding: 96px 0 0; } /* 1in top space so "Reach" clears the fold edge */
/* Mobile/tablet: the fold-clearance math above is desktop-scaled — on
   shorter, narrower sections that same 96px reads as a dead gap before the
   heading even starts. Roughly half the breathing room. */
@media (max-width: 1023px) { .reach { padding-top: 44px; } }
.reach__intro { text-align: center; padding: 0 var(--grid-margin) 2.5rem; }
.reach__intro .eyebrow { display: block; margin-bottom: 1.25rem; }
.reach__intro h2 { color: #000; }
.reach__intro .sub { margin-top: 1rem; color: var(--ink-56); max-width: 38rem; margin-left: auto; margin-right: auto; }
.reach__grid {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 2rem;
  padding: 192px var(--grid-margin); /* 2 inches top and bottom */
}
/* the map video breaks out of the grid margins: edge-to-edge, no radius */
.reach__video-wrap { padding: 0; height: 688px; overflow: hidden; } /* 400px + 3in (288px) */
.reach__video-wrap video { width: 100%; height: 100%; display: block; object-fit: cover; }
/* the map illustration carries content right up to its top and bottom edges
   (India's northern tip, the shipping lanes), so a fixed-height cover crop
   clips it — it keeps its natural ratio at full width instead */
.reach__map { height: auto; }
.reach__map img { width: 100%; height: auto; display: block; }
/* Mobile/tablet: the map is wide, so a fixed-height cover crops its sides.
   Let the video show at its natural ratio (full width, auto height) — no crop. */
@media (max-width: 1023px) {
  .reach__video-wrap { height: auto; }
  .reach__video-wrap video { height: auto; object-fit: contain; }
}
@media (min-width: 1024px) { .reach__grid { grid-template-columns: 1fr 1fr; } }
.reach-card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 2.25rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  transition: border-color .3s var(--ease), transform .3s var(--ease);
}
.reach-card:hover { border-color: var(--green-deep); transform: translateY(-4px); }
.reach-card h3 { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h3); line-height: var(--lh-h3); color: var(--ink-warm); }
.reach-card h3 em { font-style: normal; color: var(--green-deep); }
.reach-card p { color: var(--ink-56); }
.reach-card .tags { display: flex; flex-wrap: wrap; gap: .4rem; }
.reach-card .tags span {
  font-size: 13px; font-weight: 500;
  padding: .35rem .75rem;
  border-radius: 100px;
  background: var(--green-tint);
  color: var(--green-deep);
}
.reach-card .media-frame { margin-top: .5rem; }
.reach-card .btn { align-self: flex-start; margin-top: auto; }

/* ---------- 8. IMPACT (light, count-up metrics) ---------- */
.impact { background: var(--bg); padding: 0 var(--grid-margin); text-align: center; }
.impact .eyebrow-wide { display: block; margin-bottom: 1rem; }
.impact h2 { color: #000; }
.impact .sub { margin-top: 1rem; color: var(--muted); }
.impact__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
  max-width: 72rem;
  margin: 3.5rem auto 0;
}
@media (min-width: 900px) { .impact__grid { grid-template-columns: repeat(4, 1fr); } }
.impact .stat {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 1.75rem 1.5rem;
  box-shadow: 0 12px 28px -22px rgba(22, 22, 15, .28);
}
.stat-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--paper-3);
  color: var(--ink-warm);
  margin-bottom: 1.25rem;
}
.stat-icon svg { width: 20px; height: 20px; }
.stat-icon--lg svg { width: 24px; height: 24px; }

/* ---------- 10. FINAL CTA — facility photo bleeds straight into the footer below ---------- */
.final-cta {
  position: relative;
  background-image: url("../assets/img/footer-facility.webp");
  background-size: cover;
  background-position: center;
  /* Match the box to the photo's own ratio (1296x645 ≈ 2:1) so "cover" shows
     the WHOLE image with no crop on desktop/tablet — the trucks parked at the
     far left/right edges stay fully in frame. */
  aspect-ratio: 1296 / 645;
  /* Floor only — aspect-ratio already wins above ~1029px wide (natural
     height > 32rem there), so this only kicks in across the tablet/small-
     laptop range (roughly 768–1024px), where the pure-ratio box is too
     short for the heading/sub/button to fit inside the 35% sky band. */
  min-height: 35rem;
}
/* The photo's own bottom edge (wet concrete yard) is mid-grey, not dark, so
   it cut straight into the solid-black footer with a visible seam. Fading
   the photo's own last third to black — matching recykal.market's real
   footer treatment — makes it flow into the footer with no seam, on every
   viewport (this pseudo tracks the image regardless of how it's
   positioned/cropped per breakpoint below). */
.final-cta::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 34%;
  background: linear-gradient(180deg, rgba(2, 2, 2, 0) 0%, rgba(2, 2, 2, .55) 45%, rgba(2, 2, 2, .92) 80%, #020202 100%);
  pointer-events: none;
}
/* Soft light-to-photo fade at the TOP, matching recykal.market's own
   treatment — the page's light background eases into the photo instead of
   cutting to it hard. Sits behind the heading/sub/button (::before paints
   before real children), so the text stays crisp on top of it. */
.final-cta::before {
  content: "";
  position: absolute;
  /* Extends 2px above the box's own top edge — cover-fit + aspect-ratio
     rounding can leave a sub-pixel sliver of the raw photo peeking out
     right at the boundary, which reads as a hairline seam against the
     page background above. A couple px of overlap kills that for good. */
  inset: -2px 0 auto 0;
  height: 20%;
  /* Starts at fully opaque #fafafa — an exact match to the .impact/
     .green-dot-separator background directly above — so there's zero seam at
     the boundary; a partial-opacity start (as before) left a ~10%
     brightness mismatch right at that edge, which read as a hard line. */
  background: linear-gradient(180deg, #fafafa 0%, rgba(250, 250, 250, .75) 35%, rgba(250, 250, 250, .28) 70%, rgba(250, 250, 250, 0) 100%);
  pointer-events: none;
}
/* The heading/sub/button sit centered — both axes — inside the photo's own
   sky band (measured directly off the source photo: the roofline sits at
   ~35% of the frame at the horizontal centre, where this text lives).
   Because `cover` always preserves an image's OWN internal proportions
   vertically (it only ever crops left/right when the box is more portrait
   than the photo), this 35% band lands on the sky at every breakpoint,
   including the shorter/taller mobile box below — no more disconnected
   "light band" floating above the photo. */
.final-cta__content {
  position: absolute;
  inset: 0 0 auto 0;
  height: 35%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  text-align: center;
  padding: 0 var(--grid-margin);
}
.final-cta h1 { color: #000; max-width: 22ch; }
.final-cta h1 em { font-style: normal; color: var(--green-deep); }
/* Solid ink, not the usual 56%-opacity secondary-copy color — this sub
   sits directly on the sky photo, and the washed-out grey was hard to read
   against it on every device. Matches the heading's solid black. */
.final-cta .sub { color: var(--ink); max-width: 40rem; }
.final-cta .cta-row { display: flex; flex-wrap: wrap; gap: .75rem; justify-content: center; }

/* Mobile: the sky band above is only ~35% of a very short box at this width
   (aspect-ratio alone gives too little room for the heading/sub/button), so
   give the box a bit more height. `cover` preserves the sky's proportion
   regardless (see note above) — the trade-off is a moderate left/right crop
   of the photo's edges (the trucks), which keeps the text correctly seated
   on the sky instead of floating disconnected from the image. */
@media (max-width: 767px) {
  .final-cta {
    aspect-ratio: auto;
    min-height: 27rem;
  }
  .final-cta__content { gap: .5rem; padding: 0 1.5rem; }
  .final-cta h1 { font-size: clamp(1.4rem, 5.5vw, 1.7rem); line-height: 1.15; }
  .final-cta .sub { font-size: 13px; line-height: 1.35; }
}

/* ---------- 11. FOOTER — the facility photo above fades to black via its
   own ::after (see .final-cta::after); this section is the solid-black
   strip that fade lands on. Matches recykal.market's own footer: a
   left-aligned tagline, a row of site links, then a compact legal line. ---------- */
.site-footer {
  position: relative;
  color: var(--white);
  background: #020202;
}
.footer-content {
  min-height: 22vh;
  display: flex;
  align-items: flex-end;
  padding: 2.5rem var(--grid-margin) 2rem;
}
.footer-tagline {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--fs-h2);
  letter-spacing: var(--ls-display);
  line-height: 1.25;
  color: var(--white);
  text-align: left;
}
.footer-tagline .muted { color: var(--white-56); }
/* site/category links — sits between the tagline and the legal line */
.footer-links {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .85rem;
  padding: 1.75rem var(--grid-margin);
}
.footer-links a {
  color: var(--white-56);
  font-size: 14px;
  font-weight: 500;
  text-decoration: none;
  transition: color var(--dur-fast);
}
.footer-links a:hover { color: var(--white); }
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1.5rem;
  justify-content: flex-start;
  padding: 0 var(--grid-margin) 1.5rem;
  color: var(--white-56);
  font-size: 13px;
  text-align: left;
}
.footer-legal a { color: var(--white-56); text-decoration: underline; text-underline-offset: 2px; transition: color var(--dur-fast); }
.footer-legal a:hover { color: var(--green-deep); }
/* copyright/terms sit left, social icons right (space-between above); on
   narrow screens the row wraps and this group re-centers on its own line */
.footer-legal__text { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; }
.footer-social { display: flex; align-items: center; gap: 1rem; order: -1; }
.footer-social a { color: var(--white-56); line-height: 0; transition: color var(--dur-fast); }
.footer-social a:hover { color: var(--white); }
.footer-social svg { width: 18px; height: 18px; display: block; }
@media (max-width: 640px) {
  .footer-links { gap: 1.25rem 1.5rem; }
}

/* ============================================================
   GLOBAL EXCHANGE FOLD (metal.html, .globex) — a light, centered
   fold: cross-border capabilities (4 in a row), then a network of
   clickable "market nodes" (flags → companies modal, 6 per row) on
   a faint coordinate grid, then a register CTA. White background.
   ============================================================ */
.globex {
  position: relative;
  overflow: hidden;
  background: var(--white);
  padding: clamp(3.5rem, 7vw, 6rem) 0;
}
.globex__gridbg { display: none; }   /* plain white background — no grid, no glow */
.globex__inner {
  position: relative;
  width: min(80rem, 100%);
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 3.5vw, 3.5rem);   /* a touch tighter than the page margin so 6 full-size cards fit one row */
}
.globex__head { max-width: 48rem; margin: 0 auto; text-align: center; }
.globex__head .eyebrow { display: block; margin-bottom: 1rem; }
.globex__head .title-h2 { color: var(--ink-warm); }   /* match global.html page-section headings */
.globex__lede { margin: 1.1rem auto 0; color: var(--ink-56); font-size: var(--fs-body-lg); max-width: 40rem; }

/* ---- capabilities: light cards, mono keyword tag (not a sequence), 4 in a row ---- */
.globex__caps {
  list-style: none;
  margin: clamp(2rem, 4vw, 3rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--grid-gutter);
}
@media (min-width: 560px) { .globex__caps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 960px) { .globex__caps { grid-template-columns: repeat(4, 1fr); } }
.cap {
  position: relative;
  padding: 1.4rem 1.4rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--white);
  box-shadow: 0 12px 28px -22px rgba(22, 22, 15, .28);
  transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.cap:hover { transform: translateY(-4px); border-color: rgba(27, 139, 58, .35); box-shadow: 0 18px 34px -24px rgba(22, 22, 15, .4); }
.cap__tag {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--green-deep);
  margin-bottom: .9rem;
}
.cap__title { font-family: var(--font-display); font-weight: 500; font-size: 19px; letter-spacing: var(--ls-display); color: var(--ink-2); }
.cap__desc { margin-top: .5rem; color: var(--ink-56); font-size: var(--fs-small); line-height: 1.55; }

.globex__rule { height: 1px; background: var(--line); margin: clamp(2.5rem, 5vw, 3.5rem) 0; }

/* ---- market nodes: flag + name + live player count (mono), 6 per row ---- */
.globex__markets-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: .4rem;
  margin-bottom: 1.75rem;
}
.globex__label { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h3); line-height: var(--lh-h3); color: var(--ink-warm); }
.globex__hint { font-family: var(--font-mono); font-size: 13px; color: var(--green-deep); letter-spacing: -.01em; }

.node-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: .75rem;
}
@media (min-width: 600px) { .node-grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 992px) { .node-grid { grid-template-columns: repeat(6, 1fr); } }
.node {
  display: flex;
  align-items: center;
  gap: .95rem;
  width: 100%;
  text-align: left;
  padding: 1.15rem 1.25rem;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--white);
  color: inherit;
  font: inherit;
  cursor: pointer;
  transition: border-color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.node:hover { transform: translateY(-3px); border-color: var(--green-deep); box-shadow: 0 10px 24px rgba(0, 0, 0, .06); }
.node:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--green); }
.node__flag { flex: 0 0 auto; display: block; }
.node__flag img { width: 32px; height: 24px; object-fit: cover; display: block; border-radius: 3px; border: 1px solid var(--line); }
.node__meta { display: flex; flex-direction: column; min-width: 0; }
.node__name { font-family: var(--font-display); font-weight: 500; font-size: 16px; letter-spacing: var(--ls-display); color: var(--ink-2); }
.node__count { display: inline-flex; align-items: center; gap: .4rem; font-family: var(--font-mono); font-size: 14px; color: var(--green); margin-top: .2rem; }
.node__pulse { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px var(--green-tint); flex: 0 0 auto; }

/* ---- register CTA (inside the fold, centered) ---- */
.globex__cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 1.25rem;
  padding: clamp(1.75rem, 3.5vw, 2.5rem);
  border: 1px solid var(--line);
  border-radius: 22px;
  background: linear-gradient(120deg, var(--green-tint), var(--paper-1));
}
.globex__cta-title { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h3); line-height: var(--lh-h3); color: var(--ink); }
.globex__cta-copy p { margin-top: .4rem; color: var(--ink-56); font-size: var(--fs-small); }

/* ---- companies modal content (verified players list, on white modal) ---- */
.companies-list { display: grid; gap: .5rem; margin-top: .25rem; }
.company-item {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  padding: .8rem 1rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper-1);
}
.company-item::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }

@media (prefers-reduced-motion: reduce) {
  .cap, .node { transition: none; }
  .cap:hover, .node:hover { transform: none; }
}

/* Sellers/Buyers: on desktop, CTA sits ABOVE the cards and the card grid fills
   the column so the bottom row aligns with the bottom of the media card. */
@media (min-width: 1024px){
  .audience .aud-details{display:flex;flex-direction:column;height:100%}
  .audience .aud-details .aud-cta{order:-1;margin:0 0 1.5rem}
  .audience .aud-details .feature-list{flex:1 1 auto;margin-top:0;grid-template-rows:1fr 1fr}
}
@media (min-width: 1024px){ .audience .media-natural{align-self:end} }

/* ===== Desktop (PC) peek-carousel for "Why Recykal.Market" features =====
   Replaces the 900vh scroll-jack with a horizontal card track: the focused
   card sits at the left, the next card peeks in, scroll/‹ › to glide.
   Mobile (<=1023px) is untouched (its own rules live above). */
@media (min-width: 1024px){
  .feature-scrub{ height: auto; }
  .feature-scrub__sticky{ position: static; height: auto; min-height: 0; overflow: visible;
    padding-top: clamp(4rem,7vw,7rem); padding-bottom: clamp(4rem,7vw,7rem); align-items: center; }
  .feature-scrub__copy{ min-width: 0; }
  .scrub-items{ display: block; }
  .scrub-scrollbar{ display: none; }
  .scrub-items-list{
    display: flex; grid-template-columns: none; gap: 1.25rem;
    overflow-x: auto; overflow-y: visible;
    scroll-snap-type: x mandatory; scroll-behavior: smooth;
    padding: .35rem .35rem 1.25rem; margin: 0 -.35rem;
    scrollbar-width: none;
  }
  .scrub-items-list::-webkit-scrollbar{ display: none; }
  .scrub-item{
    grid-area: auto; position: relative;
    flex: 0 0 auto; width: clamp(19rem, 78%, 30rem);
    scroll-snap-align: start;
    opacity: 1; visibility: visible; transform: none;
    background: #fff; border: 1px solid var(--line); border-radius: 16px;
    padding: 1.6rem 1.7rem; min-height: 14rem;
    transition: opacity .35s var(--ease), border-color .35s var(--ease), box-shadow .35s var(--ease);
  }
  .scrub-item:not(.is-active){ opacity: .5; }
  .scrub-item.is-active{ opacity: 1; border-color: var(--ink-2, #111); box-shadow: 0 18px 40px rgba(0,0,0,.08); }
  .scrub-item__title .ch{ opacity: 1 !important; }
  .scrub-item__label{ opacity: 1; }
  .scrub-item__desc{ max-height: none; opacity: 1; margin-top: .6rem; overflow: visible; }
}

/* ===== Feature blocks — image-on-top cards. Desktop: 4-up, arrow pages by 4.
   Mobile: one-by-one slide (swipe/arrow). Replaces the old scroll-scrub. ===== */
.feature-scrub { height: auto; background: var(--bg); padding: 32px 0 24px; }
.feature-blocks { padding: 0 var(--grid-margin); }
.feature-blocks__head { text-align: center; margin-bottom: 2.25rem; }
.feature-blocks__title { margin: 0; color: var(--ink-warm); }
.feature-blocks__nav { display: flex; gap: .6rem; flex: 0 0 auto; }
.feature-blocks__arrow { width: 46px; height: 46px; border-radius: 50%; border: 1px solid var(--line); background: var(--white); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: color .15s ease, border-color .15s ease, opacity .15s ease; }
.feature-blocks__arrow:hover:not(:disabled) { color: var(--green); border-color: var(--green); }
.feature-blocks__arrow:disabled { opacity: .3; cursor: default; }
.feature-blocks__viewport { overflow: hidden; }
.feature-blocks__track { display: flex; gap: 1.25rem; position: relative; transition: transform .55s var(--ease); will-change: transform; }
.feature-block { flex: 0 0 auto; width: calc((100% - 3.75rem) / 4); background: #fff; border: 1px solid var(--line); border-radius: 16px; overflow: hidden; display: flex; flex-direction: column; }
.feature-block__media { position: relative; aspect-ratio: 1959 / 2267; background: #eeeeea; }
.feature-block__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.feature-block__body { padding: 1.15rem 1.2rem 1.4rem; display: flex; flex-direction: column; gap: .3rem; }
.feature-block__idx { font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em; color: var(--green); }
.feature-block__title { font-family: var(--font-display); font-weight: 500; font-size: 1.15rem; line-height: 1.22; letter-spacing: var(--ls-display); color: var(--ink-warm); margin: .1rem 0 .15rem; }
.feature-block__desc { color: var(--ink-56); font-size: var(--fs-small); line-height: 1.5; }
@media (max-width: 1023px) {
  .feature-block { width: 86%; }
  .feature-blocks__track { gap: 1rem; }
  .feature-blocks__arrow { width: 42px; height: 42px; }
}
@media (prefers-reduced-motion: reduce) { .feature-blocks__track { transition: none; } }
/* Arrows flank the block row: prev at left, next at right, vertically centered */
.feature-blocks__body { position: relative; }
.feature-blocks__arrow--prev, .feature-blocks__arrow--next { position: absolute; top: 50%; transform: translateY(-50%); z-index: 5; background: var(--white); box-shadow: 0 6px 20px rgba(0,0,0,.14); }
.feature-blocks__arrow--prev { left: 10px; }
.feature-blocks__arrow--next { right: 10px; }
/* Mobile: match the category slider — native swipe scroll, NO arrows */
@media (max-width: 1023px) {
  .feature-blocks__arrow--prev, .feature-blocks__arrow--next { display: none; }
  .feature-blocks__viewport { overflow-x: auto; overflow-y: visible; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .feature-blocks__viewport::-webkit-scrollbar { display: none; }
  .feature-blocks__track { transform: none !important; }
  .feature-block { scroll-snap-align: start; }
}
