/* ============================================================
   Bouwteam Boost — stylesheet
   Huisstijl: "Bold structure" — geel, donker, crème + fasekleuren
   ============================================================ */

/* ---------- Fonts (self-hosted, AVG-proof) ---------- */
@font-face {
  font-family: 'Manrope';
  src: url('../fonts/Manrope-Variable.ttf') format('truetype-variations');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

/* Geomanist voor de koppen (klantwens). Drie losse gewichten, geen variabel bestand —
   elk gewicht krijgt een bereik zodat font-weight: 800 (overal in de koppen) automatisch
   de Bold-face pakt; Geomanist zelf heeft geen 800-snit. */
@font-face {
  font-family: 'Geomanist';
  src: url('../fonts/Geomanist-Book.woff2') format('woff2');
  font-weight: 200 399;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Geomanist';
  src: url('../fonts/Geomanist-Regular.woff2') format('woff2');
  font-weight: 400 599;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Geomanist';
  src: url('../fonts/Geomanist-Bold.woff2') format('woff2');
  font-weight: 600 800;
  font-style: normal;
  font-display: swap;
}

/* ---------- Design tokens ---------- */
:root {
  --color-primary: #FBCF0A;
  --color-dark: #2C292B;
  --color-cream: #F5EDE2;
  --color-text: #1a1a1a;
  --color-text-light: #5b5651;
  --color-white: #ffffff;

  /* Eén bron voor de headerhoogte: de header zelf, de hero-hoogte en alles wat eronder
     moet uitkomen rekenen hiermee. Anders lopen die getallen bij de eerste wijziging
     uit elkaar. */
  --header-inhoud: 5.5rem;
  --header-hoogte: calc(var(--header-inhoud) + 1px); /* + de onderlijn */

  --phase-1: #866452;
  --phase-2: #966170;
  --phase-3: #6E7852;
  --phase-4: #AD9844;

  --spacing-xs: 0.5rem;
  --spacing-sm: 1rem;
  --spacing-md: 1.5rem;
  --spacing-lg: 3rem;
  --spacing-xl: 6rem;

  --font-body: 'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-heading: 'Geomanist', 'Manrope', system-ui, sans-serif;
  --font-size-base: 1.0625rem;

  --radius: 0.875rem;
  --radius-lg: 1.5rem;
  /* Afronding van hele secties. Groter dan --radius-lg: op volle schermbreedte leest 24px
     als een slordigheidje in plaats van een vorm. */
  --radius-sectie: 2.5rem;
  /* Breedte van de donkere randen die de hero doortrekken (zie .herken__randen).
     Geen vast getal, want de tekst mag er nooit op landen. De inhoud begint op
     (venster - container) / 2 + padding; is het venster smaller dan de container, dan is
     dat gat 0 en blijft er maar 0,5rem over. Vandaar de min(): hij groeit mee tot 2,5rem
     zodra er ruimte naast de container is, en krimpt vanzelf als die er niet is.
     Met een vaste 2,5rem stond de kop tussen 769 en ~1290px op het donker. */
  --rand-breedte: min(2.5rem, calc(max(0px, (100vw - var(--maxw)) / 2) + 0.5rem));
  /* Hoe ver de randen de sectie "herken" in lopen — van boven de hero, van onder de gele
     grunge. Precies de helft van die sectie, zodat ze elkaar in het midden raken en de
     sectie een gesloten kaart wordt. Dat halve getal kent CSS niet, dus main.js meet het
     en zet deze variabele. Deze 15rem is alleen de terugval zonder JS: dan raken ze elkaar
     niet, maar blijft het beeld heel. */
  --rand-hoogte: 15rem;
  --maxw: 75rem;
  --shadow: 0 0.625rem 1.875rem rgba(44, 41, 43, 0.10);
  --shadow-lg: 0 1.375rem 3.125rem rgba(44, 41, 43, 0.18);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

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

/* DE SCHAALHEFBOOM VAN DE HELE PAGINA.
   Alle maten staan in rem, dus dit ene getal schaalt tekst, ruimte, kaarten én de
   container tegelijk. Onder ~1935px is 0.827vw kleiner dan 1rem en gebeurt er niets:
   daar blijft alles exact zoals ontworpen. Daarboven groeit de pagina mee tot 1,83x,
   waarna de bovengrens hem stopt (anders zou hij op een 5K-scherm doorgroeien).
   Waarom rem en niet px als ondergrens: zo blijft de browserinstelling van de bezoeker
   leidend. Iemand die zijn letters op 20px heeft staan, houdt dat.
   Breekpunten staan bewust in px: die horen fysiek te zijn, niet geschaald. */
html {
  font-size: clamp(1rem, 0.827vw, 1.833rem);
  scroll-behavior: smooth;
}
body {
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  line-height: 1.6;
  color: var(--color-text);
  background: var(--color-cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; padding: 0; }
button { font-family: inherit; cursor: pointer; border: none; background: none; }
h1, h2, h3, h4 { font-family: var(--font-heading); font-weight: 800; line-height: 1.12; letter-spacing: -0.02em; }

.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--spacing-md); }
.section { padding-block: var(--spacing-xl); }
.section--dark   { background: var(--color-dark);  color: var(--color-white); }
.section--accent { background: var(--color-primary); color: var(--color-dark); }

/* ---------- Typografische helpers ---------- */
/* Blijven in de HTML voor SEO/screenreaders, maar zijn visueel verborgen */
.kicker, .step__tag {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.kicker--light { color: var(--color-primary); }
/* Houdt een eigennaam of getal bij elkaar op een regel */
.nowrap { white-space: nowrap; }
.section__head { max-width: 47.5rem; margin-bottom: var(--spacing-lg); }
.section__head--center { max-width: 51.25rem; margin-inline: auto; text-align: center; }
.section__title { font-size: clamp(1.9rem, 4.5vw, 3rem); }
.section--dark .section__title, .section--dark .kicker { color: var(--color-white); }
.section--dark .kicker--light { color: var(--color-primary); }
.section__intro { margin-top: var(--spacing-md); font-size: 1.15rem; color: var(--color-text-light); max-width: 62ch; }
.section__intro--center { margin-inline: auto; }
/* Iets ruimer alleen hier: op 62ch viel "projecten" als los woord op een 4e regel.
   66ch trekt het naar de regel erboven (3 regels), nog binnen de leesregel-norm. */
.methode-intro .section__intro { max-width: 66ch; }
.section--dark .section__intro { color: var(--color-white); }
.hl { color: var(--color-primary); }

/* ---------- Knoppen ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-xs);
  padding: 0.875rem 1.625rem; border-radius: 999px; font-weight: 700; font-size: 0.98rem; line-height: 1.15;
  text-align: center;
  transition: transform 0.3s var(--ease), background-color 0.3s var(--ease), box-shadow 0.3s var(--ease), color 0.3s var(--ease);
  will-change: transform;
}
.btn--primary { background: var(--color-primary); color: var(--color-dark); }
.btn--primary:hover { transform: scale(1.02); box-shadow: 0 0.5rem 1.375rem rgba(251, 207, 10, 0.4); }
.btn--ghost { color: var(--color-white); border: 2px solid rgba(255, 255, 255, 0.45); }
.btn--ghost:hover { border-color: var(--color-primary); color: var(--color-primary); transform: scale(1.02); }
.btn:focus-visible { outline: 3px solid var(--color-dark); outline-offset: 3px; }

/* ============================================================
   HEADER
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--color-dark);
  border-bottom: 1px solid rgba(245, 237, 226, 0.08);
}
.header__inner {
  display: flex; align-items: center; justify-content: space-between; min-height: var(--header-inhoud); gap: var(--spacing-md);
}
.header__logo { display: flex; }
.header__logo img { height: 3.5rem; width: auto; }
.nav { display: flex; align-items: center; gap: var(--spacing-lg); }
.nav__list { display: flex; gap: var(--spacing-md); }
.nav__link { color: var(--color-white); font-weight: 600; font-size: 0.95rem; padding: 0.375rem 0.125rem; position: relative; }
.nav__link::after { content: ''; position: absolute; left: 0; bottom: 0; width: 0; height: 0.125rem; background: var(--color-primary); transition: width 0.3s var(--ease); }
.nav__link:hover::after { width: 100%; }
.nav__cta { padding: 0.6875rem 1.25rem; font-size: 0.9rem; }
.nav-toggle { display: none; flex-direction: column; gap: 0.3125rem; padding: 0.5rem; }
.nav-toggle span { width: 1.625rem; height: 0.125rem; background: var(--color-white); border-radius: 2px; transition: transform 0.3s var(--ease), opacity 0.3s var(--ease); }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(0.4375rem) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-0.4375rem) rotate(-45deg); }

/* ============================================================
   1. HERO
   ============================================================ */
/* ---- Afgeronde secties ----
   Alleen waar een gekleurd blok de crème raakt: dan zie je de vorige achtergrond in de
   hoeken doorlopen. Tussen twee donkere secties (waarom -> methode) doet het niets, dus
   staat het daar niet. De crème komt van de body, niet van de sectie ernaast — die is
   doorzichtig. */
/* Op een breed scherm loopt de hero kaarsrecht door in "herken", waar twee donkere randen
   hem voortzetten; de bocht zit dan daar (zie .herken__randen). Gestapeld is daar geen
   ruimte voor — daar houdt de hero gewoon zijn eigen afgeronde onderkant. */
.hero {
  position: relative; background: var(--color-dark); color: var(--color-white); overflow: hidden;
  border-radius: 0 0 var(--radius-sectie) var(--radius-sectie);
}
@media (min-width: 769px) { .hero { border-radius: 0; } }
.hero::before {
  content: ''; position: absolute; inset: 0;
  background: url('../images/texture-grunge.webp') center/cover no-repeat;
  opacity: 0.22; mix-blend-mode: luminosity;
}
.hero::after {
  content: ''; position: absolute; right: -10%; top: 10%; width: 60%; height: 120%;
  background: radial-gradient(closest-side, rgba(251,207,10,0.14), transparent 70%); pointer-events: none;
}
/* Geen eigen schaalmachinerie meer: de root-lettergrootte doet dit nu voor de hele
   pagina. Alles hieronder staat in rem en schaalt daar vanzelf mee. */
.hero__inner {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1.1fr 0.9fr; align-items: center; gap: var(--spacing-lg);
  /* Header + hero vullen samen precies het scherm. De hoogte hoort bij het VENSTER, niet
     bij de schaal — vandaar dvh. Was min(88vh, 780px): die 88vh negeerde de header
     erboven, en de 780px kapte het sowieso af zodra het scherm hoger was dan ~886px.
     dvh i.p.v. vh zodat een verdwijnende adresbalk op tablet geen sprong geeft. */
  min-height: calc(100dvh - var(--header-hoogte));
  padding-block: var(--spacing-lg);
}
.hero__title {
  font-size: clamp(3rem, 8vw, 5.5rem);
  margin-block: var(--spacing-xs) var(--spacing-md);
}
.hero__subtitle { font-size: 1.3rem; font-weight: 700; color: var(--color-white); max-width: 30ch; }
/* max-width in ch schaalt mee met de fontgrootte, dus de regellengte blijft gelijk */
.hero__text { margin-top: var(--spacing-md); font-size: 1.05rem; color: var(--color-white); max-width: 46ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--spacing-sm); margin-top: var(--spacing-lg); }
.hero__trust { margin-top: var(--spacing-lg); font-weight: 700; letter-spacing: 0.01em; color: var(--color-white); }
.hero__media { justify-self: center; align-self: center; width: 100%; }

/* Kaart uit slide 1 — kleuren exact uit het slidedeck (#393538 / #4d494c) */
.hero-card {
  position: relative;
  overflow: hidden;
  background: #393538;
  /* radius en padding komen uit de herschaalde tokens van .hero__inner en groeien dus mee */
  border-radius: var(--radius);
  padding: clamp(var(--spacing-md), 4vw, var(--spacing-lg));
  min-height: 21.25rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  box-shadow: 0 1.5rem 3.125rem rgba(0, 0, 0, 0.45);
  will-change: opacity, transform;
}
/* Halve cirkel: cirkel diagonaal afgesneden, bolling naar linksonder */
.hero-card__shape {
  position: absolute;
  left: -4%;
  top: 6%;
  width: 62%;
  aspect-ratio: 1;
  background: #4d494c;
  border-radius: 50%;
  clip-path: polygon(0 0, 100% 100%, 0 100%);
  pointer-events: none;
}
.hero-card__text {
  position: relative;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: var(--color-white);
}
.hero-card__logo {
  position: relative;
  width: clamp(6.875rem, 20%, 9.375rem);
  height: auto;
  margin-top: var(--spacing-lg);
  align-self: flex-end;
}

/* --- Kaart ÍS de hero: vult het hele scherm, draagt de h1 --- */
.hero--kaart .hero__inner {
  grid-template-columns: 1fr;
  max-width: none;                 /* container-begrenzing opheffen: schermbreed */
  padding: 0;
  min-height: calc(100dvh - var(--header-hoogte));
}
.hero-card--groot {
  width: 100%;
  max-width: none;
  min-height: calc(100dvh - var(--header-hoogte));
  border-radius: 0;                /* full-bleed, geen zwevende kaart meer */
  box-shadow: none;
  /* de elementen 'opgeknipt' over het vlak: tekst gecentreerd-links, logo rechtsonder,
     de halve cirkel als groot accent linksonder */
  padding: clamp(var(--spacing-lg), 6vw, 7rem);
  justify-content: center;
  align-items: flex-start;
}
.hero-card--groot .hero-card__text {
  margin: 0;
  max-width: 19ch;                 /* korte, krachtige regels — schaalt mee in ch */
  font-size: clamp(2.2rem, 6.2vw, 5rem);
  line-height: 1.06;
  text-align: left;
}
.hero-card--groot .hero-card__logo {
  position: absolute;
  right: clamp(var(--spacing-md), 6vw, 6rem);
  bottom: clamp(var(--spacing-md), 6vw, 5rem);
  width: clamp(8.5rem, 13vw, 15rem);
  margin: 0;
}
.hero-card--groot .hero-card__shape {
  width: clamp(16rem, 42%, 40rem);
  left: -6%; top: auto; bottom: -14%;
}

/* --- Sectie 2: het oude hero-introblok, nu onder de kaart-hero --- */
.hero-intro {
  position: relative; overflow: hidden;
  background: var(--color-dark); color: var(--color-white);
  padding-block: var(--spacing-xl);
}
.hero-intro::before {
  content: ''; position: absolute; inset: 0;
  background: url('../images/texture-grunge.webp') center/cover no-repeat;
  opacity: 0.22; mix-blend-mode: luminosity;
}
.hero-intro__inner { position: relative; z-index: 1; text-align: center; }
.hero-intro .hero__title { font-size: clamp(2.4rem, 6vw, 4rem); }
.hero-intro .hero__text, .hero-intro .hero__actions { margin-inline: auto; }
.hero-intro .hero__actions { justify-content: center; }

/* ============================================================
   2. HERKEN JE DIT — signaalkaarten + statement
   ============================================================ */
/* Alleen als symbool-drager voor de pijl — mag nooit ruimte innemen */
.is-hidden { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- De hero die doorloopt en abrupt afbreekt ----
   Het donker van de hero zet zich hier voort als twee randen langs links en rechts, tot
   halverwege deze sectie, en houdt daar recht op. De bocht van de hero is dus mee naar
   beneden verhuisd: die zit nu in de uitsparing hieronder, niet aan de onderkant van de
   hero zelf.
   Eén element met een uitsparing i.p.v. twee losse strookjes: zo is de bocht gegarandeerd
   even breed als de randen en kan er geen naad tussen vallen. */
/* z-index 1: "Techniek en contracten" schuift met een negatieve marge deze sectie in en
   zou de statement-regel afdekken. De inhoud hier gaat er dus overheen staan i.p.v. dat
   we hem met padding wegduwen — dat gaf een dood gat onderin en juist dat gat sloopte het
   insluitende effect. */
.herken { position: relative; z-index: 1; }
.herken__randen { display: none; }
@media (min-width: 769px) { .herken__randen { display: block; } }
.herken__randen {
  position: absolute; top: 0; left: 0; right: 0; height: var(--rand-hoogte);
  background: var(--color-dark);
  pointer-events: none;
}
/* Dezelfde grunge als in de hero, met exact dezelfde declaratie — en dat is precies wat
   het naadloos maakt. De textuur is 1280px breed en beide elementen zijn schermbreed, dus
   'cover' schaalt hier én daar op de breedte: de korrel wordt vanzelf even groot (gemeten
   1,113x in allebei). Zou de textuur op de hoogte schalen, dan liep dit mis. */
.herken__randen::before {
  content: ''; position: absolute; inset: 0;
  background: url('../images/texture-grunge.webp') center/cover no-repeat;
  opacity: 0.22; mix-blend-mode: luminosity;
}
.herken__randen::after {
  content: ''; position: absolute; inset: 0 var(--rand-breedte);
  background: var(--color-cream);
  border-radius: var(--radius-sectie) var(--radius-sectie) 0 0;
}
/* De inhoud eroverheen; de randen blijven achtergrond */
.herken > .container { position: relative; z-index: 1; }

/* Regelafbreking exact zoals het slidedeck. Smaller dan 900px laten we de tekst
   vrij lopen, anders steken de vaste regels buiten hun kolom. */
.br-deck { display: none; }
@media (min-width: 900px) { .br-deck { display: inline; } }

/* ---------- Marquee ---------- */
/* Twee identieke sporen naast elkaar die allebei één spoorbreedte naar links schuiven:
   op het eindpunt staat spoor 2 exact waar spoor 1 begon, dus de sprong terug is
   onzichtbaar. min-width 100% garandeert dat een spoor nooit smaller is dan het scherm —
   anders valt er een gat op het moment van terugspringen. */
.marquee { display: flex; overflow: hidden; background: var(--color-dark); padding-block: 0.875rem; }
.marquee__spoor {
  display: flex; flex-shrink: 0; min-width: 100%; justify-content: space-around;
  align-items: center; gap: var(--spacing-lg); margin: 0; padding: 0 var(--spacing-lg) 0 0;
  list-style: none;
  /* linear is hier juist wél goed: een lopende band mag niet versnellen of afremmen.
     Deze duur is alleen de terugval zonder JS; main.js leidt hem af uit de spoorlengte
     zodat elke band 43 px/s loopt, ook als er tekst bij komt. */
  animation: marquee-lus 50s linear infinite;
}
.marquee__spoor li {
  display: flex; align-items: center; gap: var(--spacing-lg);
  font-family: var(--font-heading); font-weight: 800; font-size: 1.05rem;
  color: var(--color-white); white-space: nowrap;
}
.marquee__spoor li::after {
  content: '//'; flex-shrink: 0; color: var(--color-primary); letter-spacing: -0.04em;
}
@keyframes marquee-lus { to { transform: translateX(-100%); } }

/* Witte band tussen de twee helften van een aanbodkaart: zelfde component, omgekeerd in
   kleur en compacter. De terugvalduur is korter dan bij Jasper omdat dit spoor een
   fractie van die lengte heeft; met JS rekent main.js hem alsnog exact uit. */
.marquee--wit { background: var(--color-white); padding-block: 0.4rem; }
.marquee--wit .marquee__spoor {
  gap: var(--spacing-md); padding-right: var(--spacing-md);
  animation-duration: 13s;
}
.marquee--wit .marquee__spoor li {
  gap: var(--spacing-md); color: var(--color-dark);
  font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.08em;
}
/* De // donker en niet geel: geel op wit haalt 1,7:1 en leest als een drukfout.
   Bij Jasper staan ze wél geel — daar liggen ze op donker. */
.marquee--wit .marquee__spoor li::after { color: var(--color-dark); }

/* Kolom-voor-kolom vullen zoals slide 2: 1-2-3 links, 4-5-6 rechts */
.signals {
  display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(3, auto);
  grid-auto-flow: column; gap: var(--spacing-md);
}
.signal {
  display: flex; align-items: center; gap: var(--spacing-md);
  background: var(--color-white); border-radius: var(--radius);
  padding: var(--spacing-md) var(--spacing-lg);
  box-shadow: var(--shadow);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.signal:hover { transform: translateY(-0.25rem); box-shadow: var(--shadow-lg); }
.signal p { font-size: 1.05rem; color: var(--color-dark); }

/* Cirkel-icoon uit het slidedeck: dezelfde cirkel, ander symbool erin. Pijl op slide 2/4/8,
   vinkje op slide 5. Daarom één set maten en kleuren voor allebei. */
.pijl, .vink {
  flex-shrink: 0; display: grid; place-items: center; border-radius: 50%;
  width: 2.375rem; height: 2.375rem;
}
.pijl svg, .vink svg { width: 1.25rem; height: 1.25rem; }
.pijl--donker, .vink--donker { background: var(--color-dark); color: var(--color-primary); }
.pijl--geel,   .vink--geel   { background: var(--color-primary); color: var(--color-dark); }
/* Bullet-formaat; margin-top lijnt de cirkel uit op de eerste tekstregel */
.pijl--klein, .vink--klein { width: 1.25rem; height: 1.25rem; margin-top: 0.125rem; }
.pijl--klein svg, .vink--klein svg { width: 0.6875rem; height: 0.6875rem; }

/* Hover per regel: pijl en tekst schuiven een klein stukje uit elkaar.
   (hover: hover) sluit touch uit — daar blijft een hover-staat na een tik hangen.
   De tekst zit in een eigen span omdat je losse tekst niet kunt transformeren. */
@media (hover: hover) and (min-width: 769px) and (prefers-reduced-motion: no-preference) {
  .ticklist li .pijl, .ticklist li .bullet__tekst,
  .pillars li .pijl,  .pillars li .bullet__tekst {
    transition: transform 0.3s var(--ease);
  }
  .ticklist li:hover .pijl,
  .pillars li:hover .pijl { transform: translateX(-0.25rem); }
  .ticklist li:hover .bullet__tekst,
  .pillars li:hover .bullet__tekst { transform: translateX(0.25rem); }
}
/* Slide 2: geen kader, tweekleurig, rechts uitgelijnd onder de kaarten */
.statement {
  margin-top: var(--spacing-lg); text-align: right;
  font-family: var(--font-heading); font-weight: 800;
  font-size: clamp(1.4rem, 3.4vw, 2.1rem); line-height: 1.2; letter-spacing: -0.01em;
  color: var(--color-dark);
}
.statement__hl { color: var(--color-primary); }

/* ============================================================
   3. TECHNIEK NIET GENOEG — wit paneel op gele textuur
   ============================================================ */
/* Bovenhoeken rond: hierboven ligt "herken", en die is crème */
/* Spiegelbeeld van de hero-randen, maar naar bóven: deze sectie schuift met een negatieve
   marge de vorige in, en een crème uitsparing laat er links en rechts een strook van staan.
   Bovenaan wordt hij recht afgesneden. Samen met de randen van de hero sluiten ze
   "Herken je dit?" in.
   Waarom de sectie zélf uitrekken i.p.v. een los strookje ernaast (zoals bij de hero):
   de gele grunge is 1600x992 en zou in een lage strook op de breedte schalen terwijl hij
   in deze hoge sectie op de hoogte schaalt — op ~1000px scheelt dat 60% in korrelgrootte
   en dat zie je als een naad. Eén element kan per definitie geen naad hebben. */
.waarom {
  position: relative;
  background: var(--color-dark);
  background-image: url('../images/texture-grunge-geel.avif');
  background-size: cover; background-position: center;
}
@media (min-width: 769px) {
  .waarom {
    margin-top: calc(var(--rand-hoogte) * -1);
    padding-top: calc(var(--spacing-xl) + var(--rand-hoogte));
  }
  /* De uitsparing: crème tussen de twee randen, met de bocht onderaan */
  .waarom::before {
    content: ''; position: absolute;
    top: 0; left: var(--rand-breedte); right: var(--rand-breedte);
    height: var(--rand-hoogte);
    background: var(--color-cream);
    border-radius: 0 0 var(--radius-sectie) var(--radius-sectie);
    pointer-events: none;
  }
  .waarom > .container { position: relative; z-index: 1; }
}
/* Gestapeld bestaan de randen niet; dan gewoon een afgeronde bovenkant, zoals de hero. */
@media (max-width: 768.98px) {
  .waarom { border-radius: var(--radius-sectie) var(--radius-sectie) 0 0; }
}
.panel {
  background: var(--color-white); border-radius: var(--radius-lg);
  /* Padding stopt op 64px: het paneel groeit niet mee boven 1040px, dus daarboven
     zou meer padding de kolommen alleen maar smaller maken. */
  padding: clamp(var(--spacing-lg), 5vw, 4rem);
  box-shadow: var(--shadow-lg); max-width: 65rem; margin-inline: auto;
}
.panel__head { margin-bottom: var(--spacing-lg); }
/* Gele streep onder de kop, even breed als de onderste kopregel.
   JS zet --streep-breedte; 72px is de terugval als JS uitstaat. */
.panel__head::after {
  content: ''; display: block; height: 0.3125rem; border-radius: 999px;
  width: var(--streep-breedte, 4.5rem); max-width: 100%;
  margin-top: var(--spacing-md); background: var(--color-primary);
}
/* Quote-kolom iets ruimer: die draagt de vaste regelafbrekingen uit het slidedeck.
   Twee kolommen op één rij: links de tekst, rechts de quote onderin uitgelijnd. */
.panel__body { display: grid; grid-template-columns: 1fr 1.1fr; gap: var(--spacing-lg); align-items: stretch; }
.panel__text { color: var(--color-text-light); margin-bottom: var(--spacing-md); }
.panel__lead { font-weight: 700; margin-bottom: var(--spacing-md); }
.pillars { display: grid; gap: var(--spacing-sm); }
.pillars li { display: flex; align-items: center; gap: var(--spacing-sm); font-size: 1.05rem; }
/* Slide 4: quote rechts uitgelijnd onderin, tweekleurig, zonder kader */
.panel__quote {
  grid-column: 2;
  align-self: end; text-align: right;
  font-family: var(--font-heading); font-weight: 800;
  font-size: clamp(1.25rem, 2.4vw, 1.8rem); line-height: 1.25; letter-spacing: -0.01em;
  color: var(--color-dark);
}
.panel__quote-hl { color: var(--color-primary); }
/* Dichter in de rechteronderhoek van het paneel, zoals slide 4. */
@media (min-width: 900px) {
  .panel__quote { margin-right: calc(var(--spacing-md) * -1); margin-bottom: calc(var(--spacing-md) * -1); }
}

/* ============================================================
   4. METHODE-BLOK — bewegende lichtbundels achter intro + stappen
   ============================================================ */
/* Het blok draagt nu het donker; de twee secties erin worden doorzichtig, anders
   zouden hun eigen achtergrond het canvas afdekken. Zo blijft het zonder JS (of op
   een smal scherm, waar de bundels niet laden) exact het donkere blok van hiervoor. */
/* De onderste padding compenseert de overlap van "meerwaarde" hieronder: die schuift met
   een negatieve marge over dit blok heen om zijn afgeronde bovenhoeken op het donker te
   laten vallen. Zonder deze ruimte eet die overlap de laatste stapkaart aan (gemeten: 6px
   op een telefoon, waar de sectiepadding kleiner is). */
/* Het blok schuift met een afgeronde bovenkant over .waarom heen, zodat de bewegende beams
   tot aan de ronding zichtbaar blijven en in de hoeken de gele sectie erboven doorschijnt.
   clip-path (niet overflow) rondt achtergrond + canvas + waas in één keer af zonder de
   sticky beams en sticky stapkaarten te breken. padding-top compenseert de negatieve marge,
   zodat de inhoud precies op z'n plek blijft. */
.methode-blok {
  position: relative; background: var(--color-dark);
  margin-top: calc(var(--radius-sectie) * -1);
  padding-top: var(--radius-sectie);
  padding-bottom: var(--radius-sectie);
  clip-path: inset(0 round var(--radius-sectie) var(--radius-sectie) 0 0);
}
.methode-blok > .section--dark { background: transparent; position: relative; z-index: 1; }

/* Het canvas plakt aan de bovenkant terwijl het blok eronder doorscrollt. De
   omhulling is absoluut zodat de sticky niets uit de stroom duwt, en heeft géén
   overflow: dat zou de sticky stapkaarten in .steps breken (zie de opmerking daar). */
.methode-blok__beams { position: absolute; inset: 0; pointer-events: none; }
.methode-blok__beams canvas {
  position: sticky; top: 0; display: block;
  width: 100%; height: 100dvh;
}
/* Waas over de bundels. Nodig, en dat is gemeten: de felste bundel komt uit op
   rgb(151,122,0), waar witte tekst 4,1:1 haalt — net onder de norm. Op 0,3 wordt dat
   6,6:1 en blijven de bundels goed zichtbaar. Hoger dempt alleen maar zonder winst:
   4,5:1 is de eis, niet 10:1. */
.methode-blok__beams::after {
  content: ''; position: absolute; inset: 0;
  background: rgba(20, 18, 19, 0.3);
  pointer-events: none;
}

/* ============================================================
   4b. METHODE-INTRO — steps-nav
   ============================================================ */
.methode-intro__sub { margin-top: var(--spacing-sm); font-size: 1.2rem; font-weight: 700; color: var(--color-primary); }
/* clip (niet hidden) houdt de kaarten binnen beeld terwijl ze van opzij inschuiven,
   zonder een scrollcontainer te maken die de sticky header zou breken */
.steps-nav {
  display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 1fr;
  gap: var(--spacing-md); margin: var(--spacing-lg) 0 0; padding: 0; list-style: none;
  overflow-x: clip;
}
/* Grunge-structuur per fase, in de kleur van die fase — door de ontwerper aangeleverd.
   Deze paden staan hier en niet in een style-attribuut: een url() in een custom property
   wordt opgelost vanaf het CSS-bestand, dus inline zou het /css/images/ worden (404).

   --phase-neon is dezelfde tint als de fasekleur, maar op volle verzadiging — dus
   herkenbaar dezelfde kleur, alleen dan opgedraaid. Handmatig vastgelegd omdat CSS
   verzadiging niet kan ophogen; wit erdoor mengen maakt juist pasteller. */
.fase-1 { --phase-textuur: url('../images/texture-fase-1.avif'); --phase-neon: #FF7329; }
.fase-2 { --phase-textuur: url('../images/texture-fase-2.avif'); --phase-neon: #C7FF29; }
.fase-3 { --phase-textuur: url('../images/texture-fase-3.avif'); --phase-neon: #FF5283; }
.fase-4 { --phase-textuur: url('../images/texture-fase-4.avif'); --phase-neon: #FFD429; }

/* Stapkaart: link naar de uitgewerkte stap; height 100% vult de rastercel. */
.steps-nav__item {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; text-align: center; gap: 0.375rem;
  height: 100%; padding: var(--spacing-md); border-radius: var(--radius);
  /* Grunge-structuur op volle sterkte — geen witwas, die maakte de kaart flets. De
     leesbaarheid komt niet van de achtergrond maar van de gloed om icoon en label.
     De lichte waas dempt alleen de felste plekken in de structuur. */
  background: linear-gradient(rgba(44, 41, 43, 0.12), rgba(44, 41, 43, 0.12)),
    var(--phase-textuur) center / cover,
    var(--color-dark);
  box-shadow: var(--shadow);
  /* Rand staat er altijd al, alleen doorzichtig — anders springt de kaart bij hover */
  border: 2px solid transparent;
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease), border-color 0.3s var(--ease);
}
.steps-nav__item:hover {
  transform: translateY(-0.25rem);
  /* Halverwege de doffe fasekleur en het volle neon — zo blijft "half" ook echt half,
     zonder dat er een vierde set kleuren bijkomt om bij te houden. */
  border-color: color-mix(in srgb, var(--phase-neon) 50%, var(--phase-color));
  /* Gloed mee gehalveerd: 18px/55% -> 9px/28% */
  box-shadow: var(--shadow-lg), 0 0 0.5625rem color-mix(in srgb, var(--phase-neon) 28%, transparent);
}
.steps-nav__item:focus-visible { outline: 3px solid var(--color-primary); outline-offset: 3px; }
.steps-nav__item img { width: 5.25rem; height: 5.25rem; object-fit: contain; }
.steps-nav__label {
  font-weight: 700; color: var(--color-white); min-height: 2.5em;
  display: flex; align-items: center; justify-content: center;
}

/* ============================================================
   5. STAPPEN uitgewerkt
   ============================================================ */
.steps { padding-top: 0; }
.step {
  display: grid; grid-template-columns: 18.75rem 1fr;
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-lg);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
  /* Doelwit van de stapkaarten hierboven; houdt de stap vrij van de sticky header (88px) */
  scroll-margin-top: 6.5rem;
}
/* Raster i.p.v. losse marges: zo kunnen alle vier de kaarten even hoog worden.
   Alleen vanaf tablet — op mobiel zou de langste kaart de andere drie enorme
   lege vlakken geven. Dit is ook de weergave als JS uitstaat. */
.steps .container { display: grid; gap: var(--spacing-lg); }
@media (min-width: 769px) { .steps .container { grid-auto-rows: 1fr; } }
.step:hover { transform: translateY(-0.25rem); box-shadow: 0 1.625rem 3.375rem color-mix(in srgb, var(--phase-color) 34%, transparent); }

/* ---- Stapelmodus: kaarten schuiven bij scrollen over elkaar heen ----
   JS zet .steps--stapel aan (alleen groot scherm, geen prefers-reduced-motion), dus
   zonder JS blijft de gewone kaartenlijst hierboven staan.
   Blokstroom i.p.v. grid is een harde eis: een sticky grid-item is opgesloten in zijn
   eigen rij en zou geen millimeter bewegen. Daarom regelt JS hier de gelijke hoogtes. */
@media (min-width: 769px) {
  /* De kaarten beginnen een volledige schermbreedte opzij; clip houdt ze binnenboord.
     clip en niet hidden: hidden maakt een scrollcontainer en dan werkt sticky niet meer. */
  .steps--stapel { overflow-x: clip; }
  .steps--stapel .container { display: block; }
  .steps--stapel .step { position: sticky; top: 6.5rem; }
  /* JS schrijft de transform rechtstreeks; een transition zou achterlopen op het scrollen
     en de hover-lift zou ertegenin werken. */
  .steps--stapel .reveal,
  .steps--stapel .reveal.is-visible { opacity: 1; transform: none; transition: none; }
  .steps--stapel .step:hover { transform: none; }
}

/* Zelfde opmaak als de stapkaarten bovenaan: volle Grunge-structuur in de fasekleur */
.step__aside {
  display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  /* Smallere zijkant-padding: geeft de titel breedte zodat hij groter mag zonder te breken */
  padding: var(--spacing-lg) var(--spacing-md); color: var(--color-white); overflow: hidden;
  background: linear-gradient(rgba(44, 41, 43, 0.12), rgba(44, 41, 43, 0.12)),
    var(--phase-textuur) center / cover,
    var(--color-dark);
}
/* Geen cirkel meer: de iconen zijn hoog en smal, dus binnen een rondje bleven ze klein
   en oogden ze afgesneden. De witte omtrek doet nu hetzelfde werk als bij de stapkaarten. */
.step__icon { width: 6.5rem; height: 6.5rem; object-fit: contain; margin-bottom: var(--spacing-md); }
/* Groter en meevullend. Grens is de langste titel ("Constructie opzetten"): bij de smalste
   aside (220px in de 769-1024 range) moet het langste woord nog op één regel passen. */
.step__title { font-size: clamp(1.6rem, 2.7vw, 2.5rem); color: var(--color-white); margin-top: 0.25rem; }

/* ---- Gedeeld door de stapkaarten bovenaan en de gekleurde vakken hieronder ---- */
/* Witte omtrek om het icoon: maakt de vormen los van de structuur eronder én vult de
   transparante scheidingslijnen ín het icoon weer met wit. */
.steps-nav__item img, .step__icon, .boost__icon { filter: drop-shadow(0 0 0.4375rem #fff) drop-shadow(0 0 0.4375rem #fff); }
/* Donkere halo achter witte tekst: op de lichtste strepen van de olijfstructuur haalt
   wit anders maar 2,6 — dit lost dat lokaal op zonder de kaart flets te maken. */
.steps-nav__label, .step__title,
.boost__title, .boost__for,
.target__title, .target p { text-shadow: 0 1px 0.25rem rgba(0, 0, 0, 0.7), 0 0 0.625rem rgba(0, 0, 0, 0.5); }

/* Lichte zand-kaart met de inhoud */
.step__cols {
  background: var(--color-cream); color: var(--color-text);
  padding: clamp(var(--spacing-md), 3vw, var(--spacing-lg));
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-lg); align-content: start;
}
.step__block--goal { grid-column: 1 / -1; }
.step__block h4 {
  font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.1em; margin-bottom: var(--spacing-sm);
  color: color-mix(in srgb, var(--phase-color) 74%, black); font-weight: 800;
}
.step__block--goal p { font-size: 1.25rem; font-weight: 700; color: var(--color-dark); }
/* Slide 8: hier de branding-pijl i.p.v. het blokje. Zelfde component als bij "Herken je
   dit" en de drie pilaren, alleen kleiner — geen derde variant van dezelfde vorm. */
.step .ticklist li { color: var(--color-text-light); }
.step .ticklist li,
.oplevert .ticklist li,
.boost .ticklist li {
  display: flex; align-items: flex-start; gap: 0.625rem; padding-left: 0;
}
.step .ticklist li::before,
.oplevert .ticklist li::before,
.boost .ticklist li::before { content: none; }

/* Tick-lijsten (gedeeld) */
.ticklist li { position: relative; padding-left: 1.625rem; margin-bottom: 0.5rem; color: var(--color-white); font-size: 0.98rem; }
.ticklist li::before { content: ''; position: absolute; left: 0.25rem; top: 0.5625rem; width: 0.5rem; height: 0.5rem; border-radius: 2px; background: var(--phase-color, var(--color-primary)); }
.ticklist--light li { color: var(--color-white); }

/* ============================================================
   6. MEERWAARDE — figuur + 4 punten op gele textuur
   ============================================================ */
/* Rond aan alle vier de hoeken. Onderaan valt dat op crème ("oplevert"), bovenaan op het
   donkere methode-blok — maar alleen omdat hij daar met een negatieve marge overheen
   schuift. Zonder die overlap zouden de bovenhoeken de crème van de body laten zien: twee
   lichte kerven tussen het donker en het geel, en dat leest als een gat. De 40px eet in de
   onderpadding van het methode-blok, niet in de inhoud. */
.meerwaarde {
  position: relative;
  margin-top: calc(var(--radius-sectie) * -1);
  border-radius: var(--radius-sectie);
  background: var(--color-primary);
  background-image: linear-gradient(rgba(251,207,10,0.55), rgba(251,207,10,0.55)), url('../images/texture-steigerplank.avif');
  background-size: cover; background-position: center; color: var(--color-dark);
}
.meerwaarde .section__title { color: var(--color-dark); }
/* Kop van deze sectie mag de volle container gebruiken: hij heeft 900px nodig voor één
   regel en er staat geen introtekst onder die baat heeft bij de 820px-leesgrens. */
.oplevert .section__head { max-width: none; }
.meerwaarde__stage { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--spacing-lg); margin-top: var(--spacing-lg); }
.meerwaarde__col { display: flex; flex-direction: column; gap: var(--spacing-md); }
/* align-items laat de punten krimpen tot hun tekstbreedte, zodat de streep precies
   even lang wordt als de tekst eronder. Zonder dit rekt een punt op tot de volle kolom. */
.meerwaarde__col--left  { align-items: flex-end; text-align: right; }
.meerwaarde__col--right { align-items: flex-start; text-align: left; }
.meerwaarde__figure { justify-self: center; }
.meerwaarde__figure img { max-height: 27.5rem; width: auto; filter: drop-shadow(0 1.25rem 2.125rem rgba(44,41,43,0.35)); }
/* Slide 6: geen kaartje, maar cijfer → streep → tekst los op de gele structuur.
   Beide kolommen wijzen naar Jasper toe: links rechts-uitgelijnd, rechts links. */
.value-point { display: flex; flex-direction: column; }
.meerwaarde__col--left .value-point  { align-items: flex-end; text-align: right; }
.meerwaarde__col--right .value-point { align-items: flex-start; text-align: left; }
.value-point__num {
  flex-shrink: 0; display: grid; place-items: center; width: 2.75rem; height: 2.75rem; border-radius: 50%;
  background: var(--color-dark); color: var(--color-white); font-weight: 800; font-size: 1.05rem;
}
/* Eén strakke lijn i.p.v. de stippellijn uit de deck — dezelfde keuze als bij de kop
   van "Techniek en contracten": stippels lezen als PowerPoint, niet als web. */
.value-point p {
  width: 100%; margin-top: var(--spacing-sm); padding-top: var(--spacing-sm);
  border-top: 2px solid var(--color-dark);
  font-family: var(--font-heading); font-weight: 800;
  font-size: clamp(1.05rem, 1.5vw, 1.25rem); line-height: 1.2; letter-spacing: -0.01em;
  color: var(--color-dark);
}
.meerwaarde__note { max-width: 72ch; margin: var(--spacing-lg) auto 0; text-align: center; font-size: 1.1rem; font-weight: 500; }

/* ============================================================
   7. WAT JE KRIJGT / WAT JE MERKT
   ============================================================ */
/* Achtergrondmarkeringen zoals Post 15: grote merkvormen tint-op-tint die van de rand
   aflopen. Geen losse plaatjes — dezelfde halve-cirkel-techniek als de hero-kaart, dus
   de kleur blijft uit de variabelen komen. */
.oplevert { position: relative; overflow: hidden; }
/* De zachte vormen in Post 15 zijn #E6D7D0: dat is geen neutraal grijs maar het paars
   op ~12% over de crème. De kleur komt dus uit de fasekleuren, niet uit --color-dark. */
.oplevert__mark { position: absolute; pointer-events: none; }
/* De vormen in Post 15 zijn de methode-iconen enorm uitvergroot — niet zomaar cirkels.
   Het icoon dient als masker, dus de kleur blijft uit de variabelen komen én de
   transparante snede ín het icoon laat de crème erdoorheen schijnen: precies het effect
   uit de post, zonder er een plaatje van te maken.
   Ze lopen alleen ZIJWAARTS van het scherm af: een vorm die op de sectiegrens stopt leest
   als een fout, want daaronder ligt dezelfde crème achtergrond. */
.oplevert__mark--boog {
  left: -7.5rem; top: 1.875rem; height: 36.25rem; aspect-ratio: 360 / 573;
  background: color-mix(in srgb, var(--phase-2) 14%, transparent);
  -webkit-mask: url('../images/methode-3.webp') no-repeat center / contain;
  mask: url('../images/methode-3.webp') no-repeat center / contain;
}
/* Kleuraccent rechts, zoals de paarse vorm in de post */
.oplevert__mark--accent {
  right: -4.375rem; bottom: 2.5rem; height: 18.75rem; aspect-ratio: 360 / 588;
  background: color-mix(in srgb, var(--phase-2) 18%, transparent);
  -webkit-mask: url('../images/methode-1.webp') no-repeat center / contain;
  mask: url('../images/methode-1.webp') no-repeat center / contain;
}
.oplevert .container { position: relative; z-index: 1; }
.oplevert__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-md); }
.oplevert__card { border-radius: var(--radius-lg); padding: clamp(var(--spacing-md), 4vw, var(--spacing-lg)); }
.oplevert__card h3 { font-size: 1.5rem; margin-bottom: var(--spacing-md); }
.oplevert__card--dark { background: var(--color-dark); color: var(--color-white); position: relative; overflow: hidden; }
/* Half rondje tegen de rechterrand: de cirkel staat half buiten de kaart en wordt door
   overflow afgeknipt, dus de platte kant valt exact op de rand. 10% wit is dezelfde
   verhouding die de hero-kaart tussen vorm en ondergrond gebruikt. */
.oplevert__card--dark::before {
  content: ''; position: absolute; top: 50%; right: 0;
  width: 42%; aspect-ratio: 1; border-radius: 50%;
  transform: translate(50%, -50%);
  background: color-mix(in srgb, var(--color-white) 10%, transparent);
  pointer-events: none;
}
/* Inhoud boven de vorm houden */
.oplevert__card--dark > * { position: relative; }
.oplevert__card--dark h3 { color: var(--color-white); }
.oplevert__card--light { background: var(--color-white); box-shadow: var(--shadow); }
.oplevert__card--light .ticklist li { color: var(--color-text-light); }
.oplevert__card--light .ticklist li::before { background: var(--color-primary); }
.oplevert__card--dark .ticklist li::before { background: var(--color-primary); }

/* ============================================================
   8. IK BEN JASPER
   ============================================================ */
/* Slide 5: wit paneel met een gele rand eromheen. De rand is daar egaal geel, geen
   structuur — nagemeten in de slide, dus hier ook geen textuur.
   Het geel zit op __vlak en niet op de sectie: zo staat er geen gele strook boven de
   marquee, én is de rand simpelweg de padding van dit vlak — dus overal even breed,
   op elke schermbreedte. */
/* Rand groeit mee met het scherm. De vaste 1,6% uit slide 5 bleef op grote schermen te
   dun; deze formule loopt steiler op (de -12px drukt hem op kleine schermen terug), dus
   hij blijft bescheiden op tablet en wordt fors op een breed scherm. Ondergrens houdt
   hem zichtbaar op smalle telefoons. */
.jasper__vlak { background: var(--color-primary); padding: max(0.75rem, 3.4vw - 0.75rem); }
.jasper .panel { max-width: none; }
/* Kolomverhouding uit slide 5: foto ~27% van het paneel, tekst ~58% */
.jasper__inner { display: grid; grid-template-columns: 0.46fr 1fr; gap: var(--spacing-xl); align-items: start; }
/* De kaart groeit met het scherm mee, maar de leesregel mag niet meegroeien: boven de
   ~940px zou die richting 130 tekens gaan. Kop en inhoud krijgen dezelfde begrenzing,
   anders staat de titel links terwijl de tekst eronder gecentreerd staat. */
.jasper .panel__head,
.jasper .jasper__inner { max-width: 58.75rem; margin-inline: auto; }
.jasper__media img { border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); width: 100%; object-fit: cover; }
/* Bijschriften onder de foto, zoals de vinkjes in slide 5 */
.jasper__labels { display: grid; gap: var(--spacing-sm); margin-top: var(--spacing-md); }
.jasper__labels li { display: flex; align-items: center; gap: var(--spacing-sm); font-weight: 700; font-size: 0.95rem; }
.jasper__labels .vink { width: 1.625rem; height: 1.625rem; }
.jasper__labels .vink svg { width: 0.875rem; height: 0.875rem; }
.jasper__blok { margin-bottom: var(--spacing-lg); }
.jasper__cta { margin-top: var(--spacing-md); }
.jasper__blok h3 { font-size: 1.15rem; margin-bottom: 0.375rem; }
.jasper__blok p { color: var(--color-text-light); }

/* ============================================================
   9. AANBOD — boost-kaarten (donker)
   ============================================================ */
/* Metaalplaat-structuur op 35% (het metaal is van zichzelf donker).
   Alleen de onderhoeken rond: hieronder ligt "voor wie" (crème). Bovenaan grenst hij aan
   het gele vlak van Jasper — daar zou afronding crème kerven tussen geel en donker. */
.aanbod {
  border-radius: 0 0 var(--radius-sectie) var(--radius-sectie);
  background-color: var(--color-dark);
  background-image: linear-gradient(rgba(44, 41, 43, 0.65), rgba(44, 41, 43, 0.65)),
    url('../images/texture-metaalplaat.avif');
  background-size: cover; background-position: center;
}
.cards { display: grid; gap: var(--spacing-md); }
.cards--3 { grid-template-columns: repeat(3, 1fr); align-items: stretch; }
/* Tussen tablet en klein laptop passen 3 kaarten niet: de kolom wordt smaller dan
   de kaart zelf nodig heeft en duwt de pagina zijwaarts. Daar dus 2 kolommen. */
@media (min-width: 769px) and (max-width: 1000px) {
  .cards--3 { grid-template-columns: repeat(2, 1fr); }
}
/* Zelfde recept als de stapkaarten: de structuur van de fase op volle sterkte, met de
   leesbaarheid uit de gloed om icoon en tekst. Was een doorzichtige kaart, maar die liet
   de metaalplaat van de sectie erdoorheen zien — daardoor stonden er drie grijze kaarten
   waarvan alleen de rand nog kleur had. */
/* De kaart zelf heeft geen achtergrond: alleen deel 1 draagt de structuur, deel 2 laat
   de metaalplaat van de sectie doorschemeren. Zo staat de fasestructuur niet onder het
   zwart mee te kleuren. Vandaar ook padding 0 — elke helft regelt zijn eigen ruimte.
   Rand en band zijn wit en niet geel: geel is op deze pagina de knop. Stond het hier ook
   in de rand en de band, dan wees het nergens meer naar. */
.boost {
  display: flex; flex-direction: column;
  border: 2px solid var(--color-white);
  border-radius: var(--radius); padding: 0; overflow: hidden;
  box-shadow: var(--shadow);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
/* Deel 1: de structuur van de fase, inhoud gecentreerd.
   De structuur loopt onderaan licht aan, zodat de band eruit opkomt in plaats van erbovenop
   te knallen. Let op de richting: een dónkere rand vlak voor een lichte band vergroot de
   sprong juist (gemeten 6,3:1 -> 10,3:1). Je moet naar de band toe lopen, niet ervanaf. */
.boost__kop {
  padding: var(--spacing-lg) var(--spacing-md) var(--spacing-md);
  background: linear-gradient(to bottom, transparent 65%, rgba(255, 255, 255, 0.3)),
    linear-gradient(rgba(44, 41, 43, 0.12), rgba(44, 41, 43, 0.12)),
    var(--phase-textuur) center / cover,
    var(--color-dark);
}
/* Deel 2: zwart vlak waar de sectie-achtergrond doorheen schemert — vandaar 0.78 en
   geen dekkend zwart. flex-1 duwt de knop naar de onderrand, ook als de ene kaart een
   regel meer heeft dan de andere. */
.boost__body {
  flex: 1; display: flex; flex-direction: column;
  padding: var(--spacing-md) var(--spacing-md) var(--spacing-lg);
  background: rgba(18, 16, 17, 0.7);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
}
/* De rand is al wit; "oplichten" doet de gloed eromheen, niet een tweede wit. */
.boost:hover {
  transform: translateY(-0.375rem);
  box-shadow: var(--shadow-lg), 0 0 1.125rem rgba(255, 255, 255, 0.45);
}
/* Nu alle kaarten dezelfde rand hebben, kan de uitgelichte niet meer aan zijn rand te
   herkennen zijn: die staat permanent zwak aan, alsof hij al hover heeft. */
.boost--featured { box-shadow: var(--shadow), 0 0 0.75rem rgba(255, 255, 255, 0.3); }
/* Kop van de kaart gecentreerd, net als bij de stapkaarten. De opsomming eronder blijft
   links uitgelijnd: die leest als lijst, niet als kop. */
.boost__icon {
  width: 4.75rem; height: 4.75rem; object-fit: contain;
  margin-bottom: var(--spacing-sm); margin-inline: auto;
}
.boost__title { font-size: 1.5rem; color: var(--color-white); text-align: center; }
/* Twee regels hoog, ook als de tekst er maar één nodig heeft: anders begint het zwarte
   vlak bij de ene kaart hoger dan bij de andere en loopt de scheidingslijn niet door.
   Zelfde truc als bij .steps-nav__label. */
.boost__for {
  color: var(--color-white); margin-block: var(--spacing-xs) var(--spacing-md);
  font-weight: 600; text-align: center;
  min-height: 2lh; display: flex; align-items: center; justify-content: center;
}
.boost .ticklist { flex: 1; margin-bottom: var(--spacing-md); }
.boost__cta { width: 100%; font-size: 0.9rem; padding: 0.75rem 1.125rem; }

/* ============================================================
   10. VOOR WIE — doelgroepkaarten
   ============================================================ */
/* Donkere kaart met de metaalplaat van de aanbod-sectie, maar doorzichtig: de crème
   sectie schemert erdoorheen. De sectie zelf blijft licht — die is de ademhaling tussen
   aanbod en contact, twee donkere secties.
   De structuur kan hier NIET in de background-shorthand: een foto is dekkend en zou elke
   doorzichtigheid ongedaan maken. Vandaar een eigen laag met opacity hieronder. */
.target {
  position: relative; overflow: hidden;
  background-color: var(--color-dark);
  background-image: linear-gradient(rgba(44, 41, 43, 0.65), rgba(44, 41, 43, 0.65)),
    url('../images/texture-metaalplaat.avif');
  background-size: cover; background-position: center;
  border-radius: var(--radius); padding: var(--spacing-lg);
  box-shadow: var(--shadow);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
/* De gele halve cirkel rechtsonder komt van slide 13: het merk zet op een witte kaart
   precies deze vorm achter de inhoud. Beton en niet Grunge: Grunge is van zichzelf
   donker en wordt op dit formaat een zwarte klodder i.p.v. een gele vorm.
   Metaalplaat viel om dezelfde reden af (bijna zwart). */
.target::after {
  content: ''; position: absolute; right: -2rem; bottom: -2.5rem;
  width: 9rem; aspect-ratio: 1; border-radius: 50%;
  background: url('../images/texture-beton-geel.avif') center / cover, var(--color-primary);
  pointer-events: none;
}
/* Gestapeld is de kaart breed maar laag, dus staat de cirkel relatief hoger en loopt de
   tekst er alsnog overheen. Kleinere cirkel i.p.v. kortere tekst: de tekst is hier de
   inhoud, de cirkel de versiering.
   768.98 en niet 768: op een gebroken vensterbreedte (Windows-schaling, browserzoom) is
   het venster bijv. 768,5 breed. Dan matcht max-width 768 níét en min-width 769 óók niet,
   en valt de pagina terug op de bureaubladregels. Gemeten: op exact 768 sprong de footer
   naar drie kolommen. De .98 dicht dat gaatje. */
@media (max-width: 768.98px) {
  .target::after { width: 6.5rem; }
}
/* De inhoud eroverheen; de vorm blijft achtergrond */
.target > * { position: relative; z-index: 1; }
.target:hover { transform: translateY(-0.25rem); box-shadow: var(--shadow-lg); }
/* De partijnaam draagt het blok: die moet je lezen voor je de regel eronder leest.
   fit-content is hier de hele truc: daardoor is de kop precies zo breed als het woord en
   loopt de streep eronder exact even ver. Zonder dat zou de streep de kaart doorsnijden.
   Geen JS-meting nodig zoals bij .panel__head, want dit is altijd één woord. */
.target__title {
  font-size: clamp(1.5rem, 2.4vw, 1.9rem); color: var(--color-white);
  width: fit-content; margin-bottom: var(--spacing-sm);
}
/* ---- Achtergrondvormen, paginadekkend ----
   Zelfde device als bij .oplevert (Post 15): de methode-iconen enorm uitvergroot, met het
   icoon als masker zodat de kleur uit de variabelen blijft komen. Hier vier vormen in vier
   fasekleuren i.p.v. twee in één kleur — vandaar de spreiding over de hoeken.
   Alle percentages liggen tussen 7 en 11: hoger en het wordt een vlak, lager en het is
   niet meer te zien. Ze mogen achter de kaarten door lopen; die zijn dekkend.
   overflow: hidden op de sectie houdt ze binnenboord — anders duwen ze de pagina zijwaarts. */
.voorwie { position: relative; overflow: hidden; }
.voorwie__mark { position: absolute; pointer-events: none; }
.voorwie .container { position: relative; z-index: 1; }

/* Vlakke cirkels uit slide 3/12: die snijden daar de sectie in vanaf de rand */
.voorwie__mark--cirkel-groot {
  left: -11rem; top: -7rem; width: 32rem; aspect-ratio: 1; border-radius: 50%;
  background: color-mix(in srgb, var(--phase-1) 9%, transparent);
}
.voorwie__mark--cirkel-klein {
  right: -5rem; bottom: -6rem; width: 20rem; aspect-ratio: 1; border-radius: 50%;
  background: color-mix(in srgb, var(--phase-2) 8%, transparent);
}
/* De gemaskerde iconen, zoals in Post 15 */
.voorwie__mark--boog {
  right: 4rem; top: -3rem; height: 26rem; aspect-ratio: 360 / 563;
  background: color-mix(in srgb, var(--phase-4) 11%, transparent);
  -webkit-mask: url('../images/methode-4.webp') no-repeat center / contain;
  mask: url('../images/methode-4.webp') no-repeat center / contain;
}
.voorwie__mark--blok {
  left: 6rem; bottom: -5rem; height: 18rem; aspect-ratio: 360 / 360;
  background: color-mix(in srgb, var(--phase-3) 10%, transparent);
  -webkit-mask: url('../images/methode-2.webp') no-repeat center / contain;
  mask: url('../images/methode-2.webp') no-repeat center / contain;
}

/* Zelfde streep als onder de sectiekoppen (zelfde hoogte, zelfde ronding), maar met
   dezelfde betonstructuur als de cirkel rechtsonder. cover geeft hier ongeveer dezelfde
   vergroting als bij de cirkel (~0,25x), dus de korrel is even grof in beide vormen. */
.target__title::after {
  content: ''; display: block; height: 0.3125rem; border-radius: 999px;
  margin-top: var(--spacing-xs);
  background: url('../images/texture-beton-geel.avif') center / cover, var(--color-primary);
}
/* De regel houdt de linkerkolom vrij, zoals slide 13: tekst links, vorm rechts. Zonder
   deze grens loopt de laatste regel over de gele cirkel en zakt het contrast naar 3,5:1. */
.target p { font-size: 1.1rem; color: var(--color-white); max-width: 20ch; }

/* ============================================================
   11. CONTACT + FORM
   ============================================================ */
/* Beton-structuur op 12% (het beton is van zichzelf licht, dus subtiel).
   Bovenhoeken rond: hierboven ligt "voor wie" (crème). Onderaan komt de footer, die zijn
   eigen afronding eroverheen legt — vandaar de extra ruimte onderin. */
.contact {
  border-radius: var(--radius-sectie) var(--radius-sectie) 0 0;
  padding-bottom: calc(var(--spacing-xl) + var(--radius-sectie));
  background-color: var(--color-dark);
  background-image: linear-gradient(rgba(44, 41, 43, 0.88), rgba(44, 41, 43, 0.88)),
    url('../images/texture-beton.avif');
  background-size: cover; background-position: center;
}
.contact__inner { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: var(--spacing-xl); align-items: start; }
.contact__details { margin-top: var(--spacing-md); font-size: 1.15rem; font-weight: 700; }
.contact__details li { margin-bottom: var(--spacing-xs); }
.contact__name { color: var(--color-white); }
.contact__details a { color: var(--color-primary); transition: opacity 0.3s var(--ease); }
.contact__details a:hover { opacity: 0.75; }
.form { background: rgba(245, 237, 226, 0.05); border: 1px solid rgba(245, 237, 226, 0.12); padding: var(--spacing-lg); border-radius: var(--radius-lg); }
.form__hp { position: absolute; left: -624.9375rem; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-md); }
.form__field { display: block; margin-bottom: var(--spacing-md); }
.form__field > span { display: block; font-weight: 600; font-size: 0.9rem; margin-bottom: 0.375rem; color: var(--color-white); }
.form__field em { color: var(--color-white); font-style: normal; }
.form input, .form textarea {
  /* min-width: 0 overrulet de ingebouwde minimumbreedte van formuliervelden;
     zonder dit duwen ze de kolom breder dan het scherm op smalle telefoons. */
  width: 100%; min-width: 0; padding: 0.75rem 0.875rem; background: rgba(245, 237, 226, 0.95);
  border: 2px solid transparent; border-radius: 10px; font-family: inherit; font-size: 1rem; color: var(--color-text);
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.form input:focus, .form textarea:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 0.1875rem rgba(251, 207, 10, 0.25); }
.form textarea { resize: vertical; }
.form__submit { margin-top: var(--spacing-xs); width: 100%; }

/* ============================================================
   FOOTER
   ============================================================ */
/* De footer schuift met zijn eigen radius over de contactsectie heen. Dat is de hele
   truc: zonder die overlap zouden de afgeronde hoeken de crème van de body laten zien —
   twee kerven tussen twee donkere blokken, wat als een fout leest. Nu onthullen ze het
   beton van de contactsectie. De contactsectie heeft hierboven extra padding gekregen,
   zodat de overlap zijn inhoud niet raakt. */
.footer {
  position: relative;
  margin-top: calc(var(--radius-sectie) * -1);
  border-radius: var(--radius-sectie) var(--radius-sectie) 0 0;
  background: #211f20; color: var(--color-white);
  padding-block: var(--spacing-lg);
}
/* De merkkolom is breder dan eerst: de baseline hoort op één regel te passen. De
   navigatie schuift daardoor naar rechts, wat mag. */
.footer__inner { display: grid; grid-template-columns: 1.8fr 0.8fr 1.1fr; gap: var(--spacing-lg); align-items: start; }
.footer__logo { display: inline-block; transition: transform 0.3s var(--ease); }
.footer__logo:hover { transform: scale(1.02); }
.footer__brand img { width: 10rem; height: auto; margin-bottom: var(--spacing-sm); display: block; }
/* Geen max-width in ch meer: die kapte de baseline af op twee regels. Hij telt 49
   tekens en blijft dus ruim binnen een leesbare regellengte. */
.footer__brand p { font-size: 0.95rem; }
.footer__nav { display: flex; flex-direction: column; gap: var(--spacing-xs); }
.footer__nav a { transition: color 0.3s var(--ease); }
.footer__nav a:hover { color: var(--color-primary); }
.footer__meta { font-size: 0.9rem; line-height: 1.8; }

/* Drie ronde contactknoppen. Zelfde vorm en kleur als de merk-pijl elders op de pagina:
   geel rondje, donker teken. Geel betekent hier "klik", en dat klopt — dit zijn knoppen.
   De maat is 2.875rem (46px) en niet 2.75rem: dat laatste komt door de clamp op de root
   uit op 43,99px — net onder de 44px die een vingerdoel hoort te halen. */
.footer__contact {
  list-style: none; margin: 0; padding: 0;
  display: flex; gap: var(--spacing-sm);
}
.footer__contact a {
  display: grid; place-items: center;
  width: 2.875rem; height: 2.875rem; border-radius: 50%;
  background: var(--color-primary); color: var(--color-dark);
  transition: transform 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.footer__contact svg { width: 1.375rem; height: 1.375rem; }
.footer__contact a:hover {
  transform: scale(1.02) translateY(-0.125rem);
  box-shadow: 0 0.5rem 1.375rem rgba(251, 207, 10, 0.4);
}
.footer__contact a:focus-visible { outline: 3px solid var(--color-white); outline-offset: 3px; }

.footer__credit { margin-top: var(--spacing-md); color: var(--color-white); line-height: 1.5; }
/* Dezelfde krappe zone waar .cards--3 naar twee kolommen gaat: in drie kolommen houdt de
   meta-kolom hier maar 182px over en breekt "Website door HansumDigital" (188px nodig).
   Het merk pakt de hele bovenrij, navigatie en contact staan eronder naast elkaar.
   Deze regel staat bewust ná .footer__inner hierboven: eerder in het bestand verliest hij
   de cascade van de basisregel. */
@media (min-width: 769px) and (max-width: 1000px) {
  .footer__inner { grid-template-columns: 1fr 1fr; }
  .footer__brand { grid-column: 1 / -1; }
}
/* Onderstreept, want een link in een lopende regel moet je kunnen zien zonder hover */
.footer__credit a { text-decoration: underline; text-underline-offset: 2px; transition: color 0.3s var(--ease); }
.footer__credit a:hover { color: var(--color-primary); }

/* ============================================================
   SCROLL-ANIMATIES (fade-up)
   ============================================================ */
.reveal { opacity: 0; transform: translateY(1.875rem); transition: opacity 0.6s var(--ease), transform 0.6s var(--ease); }
.reveal.is-visible { opacity: 1; transform: none; }
.signals .reveal:nth-child(2), .cards .reveal:nth-child(2), .steps-nav .reveal:nth-child(2) { transition-delay: 0.08s; }
.signals .reveal:nth-child(3), .cards .reveal:nth-child(3), .steps-nav .reveal:nth-child(3) { transition-delay: 0.16s; }
.signals .reveal:nth-child(4), .steps-nav .reveal:nth-child(4) { transition-delay: 0.24s; }
.signals .reveal:nth-child(5) { transition-delay: 0.32s; }
.signals .reveal:nth-child(6) { transition-delay: 0.40s; }

/* Methodevormen: scroll-assemblage — schuiven om-en-om in de rij en vallen op hun plek.
   Alleen op desktop (horizontaal); op mobiel gewone fade-up zodat de kaarten altijd gecentreerd staan. */
.steps-nav .reveal:nth-child(1) { transition-delay: 0s; }
.steps-nav .reveal:nth-child(2) { transition-delay: 0.14s; }
.steps-nav .reveal:nth-child(3) { transition-delay: 0.28s; }
.steps-nav .reveal:nth-child(4) { transition-delay: 0.42s; }
@media (min-width: 769px) {
  .steps-nav .reveal { opacity: 0; transform: translateX(-4.5rem) scale(0.9); }
  .steps-nav .reveal:nth-child(even) { transform: translateX(4.5rem) scale(0.9); }
  .steps-nav .reveal.is-visible { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .steps-nav .reveal, .steps-nav .reveal.is-visible { opacity: 1; transform: none; }
  html { scroll-behavior: auto; }
  .btn, .signal, .step, .boost, .target, .card, .steps-nav__item { transition: none; }
  /* Marquee stopt volledig; het tweede spoor is dan alleen een dubbeling */
  .marquee__spoor { animation: none; }
  .marquee__spoor + .marquee__spoor { display: none; }
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 1024px) {
  .step { grid-template-columns: 13.75rem 1fr; }
  .contact__inner { gap: var(--spacing-lg); }
}

@media (max-width: 768.98px) {
  :root { --spacing-xl: 4rem; }

  /* Mobiele navigatie */
  .nav {
    position: fixed; inset: 5.5rem 0 auto 0; flex-direction: column; align-items: stretch; gap: 0;
    background: var(--color-dark); padding: var(--spacing-md); border-bottom: 1px solid rgba(245, 237, 226, 0.1);
    transform: translateY(-120%); transition: transform 0.4s var(--ease); box-shadow: var(--shadow-lg);
  }
  .nav.is-open { transform: translateY(0); }
  .nav__list { flex-direction: column; gap: 0; }
  .nav__link { display: block; padding: 0.875rem 0.25rem; border-bottom: 1px solid rgba(245, 237, 226, 0.08); }
  .nav__cta { margin-top: var(--spacing-sm); }
  .nav-toggle { display: flex; }

  /* Kaart-hero blijft schermvullend; alleen de padding krimpt op smalle schermen */
  .hero-card--groot { padding: var(--spacing-lg) var(--spacing-md); }
  .hero-card--groot .hero-card__logo { right: var(--spacing-md); bottom: var(--spacing-md); }

  /* Eén kolom: terug naar gewone volgorde, anders ontstaan er extra kolommen */
  .signals { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; }

  /* Eén kolom: de vaste kolomplaatsing los, anders maakt grid-column: 2 een
     fantoomkolom naast de pagina. */
  .panel__body { grid-template-columns: 1fr; gap: var(--spacing-lg); }
  .panel__left, .panel__quote { grid-column: auto; }
  .panel__quote { padding-top: var(--spacing-md); }

  .steps-nav { grid-template-columns: repeat(2, 1fr); }

  .step { grid-template-columns: 1fr; }
  .step__aside { flex-direction: row; align-items: center; flex-wrap: wrap; gap: var(--spacing-sm); }
  .step__icon { width: 4rem; height: 4rem; margin-bottom: 0; }
  .step__cols { grid-template-columns: 1fr; gap: var(--spacing-md); }

  .meerwaarde__stage { grid-template-columns: 1fr; }
  .meerwaarde__col { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: stretch; }
  /* Zonder Jasper ertussen heeft naar-binnen-wijzen geen betekenis meer: alles links */
  .meerwaarde__col--left { text-align: left; }
  .meerwaarde__col--left .value-point,
  .meerwaarde__col--right .value-point { align-items: flex-start; text-align: left; }
  .value-point { flex: 1 1 16.25rem; }
  .meerwaarde__figure { order: -1; }
  .meerwaarde__figure img { max-height: 20rem; }

  .oplevert__grid { grid-template-columns: 1fr; }
  .jasper__inner { grid-template-columns: 1fr; }
  .jasper__media { max-width: 28.75rem; }
  .cards--3 { grid-template-columns: 1fr; }
  .contact__inner { grid-template-columns: 1fr; }
  .form__row { grid-template-columns: 1fr; }
  .footer__inner { grid-template-columns: 1fr; gap: var(--spacing-md); }
}

@media (max-width: 420px) {
  .container { padding-inline: var(--spacing-sm); }
  .step, .boost, .form { padding: var(--spacing-md); }
  .steps-nav { grid-template-columns: 1fr; }
  .statement p { font-size: 1.3rem; }
  /* Op de smalste telefoons schuurt de tekst anders tegen de cirkel (gemeten op 320px) */
  .target::after { width: 5.5rem; }
}
