/* Breinfijn LP Kalmeer je Zenuwstelsel */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

/* Horizontale klipping op html en body samen, met hidden als bodem en clip als verbetering.

   Waarom die trap: overflow van body propageert naar de viewport, en iOS Safari gaat daar anders mee
   om dan Chrome, dus de regel staat op beide. En clip bestaat pas vanaf Safari 16. Op 04-08-2026 stond
   hier een tijdje alleen clip op body, en op een oudere iOS is die declaratie ongeldig en had de body
   dus helemaal geen klipping meer, waar eerst hidden stond. Dat was een verslechtering.

   Nu dus: hidden voor iedereen, en clip erbovenop waar het bestaat. Clip is de betere van de twee,
   want hidden maakt van het element een scrollcontainer en dat sloopt position: sticky en scroll-snap,
   precies zoals bij .section--bleed staat. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  overflow-x: clip;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bf-bg);
  color: var(--bf-text);
  font-family: var(--bf-font);
  font-size: var(--bf-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  /* Tegen het horizontale doorveren op iOS, ook als er toch nog iets buiten de rand valt. */
  overscroll-behavior-x: none;
}

@supports (overflow: clip) {
  body { overflow-x: clip; }
}

h1, h2, h3 {
  margin: 0;
  color: var(--bf-heading);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.2;
  text-wrap: balance;
}
h1 { font-size: var(--bf-h1); line-height: 1.15; }
h2 { font-size: var(--bf-h2); }
h3 { font-size: var(--bf-h3); }

p { margin: 0; max-width: var(--bf-measure); }
/* ol staat er sinds 04-08-2026 bij. Zonder die toevoeging hield de lessenlijst in blok 6 de
   standaard padding-inline-start van de browser, en stonden de nummers plus de haarlijnen 40px naar
   binnen ten opzichte van elke andere lijst op de pagina. */
ul, ol { margin: 0; padding: 0; list-style: none; }
img { max-width: 100%; height: auto; display: block; }
strong { font-weight: 600; color: var(--bf-heading); }

a { color: var(--bf-cta-hover); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }

:focus-visible {
  outline: 3px solid var(--bf-mark);
  outline-offset: 2px;
  border-radius: var(--bf-radius);
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ============================================================
   LAYOUT
   ============================================================ */

.section { padding: var(--bf-section-y) max(var(--s5), calc((100% - var(--bf-container)) / 2)); }
/* Staat op de drie secties met een swipe-rij (blok 3, 4 en 5). De bleed naar de viewportrand is er op
   04-08-2026 uit gehaald, dus strikt noodzakelijk is deze regel niet meer. Hij blijft staan als
   bescherming: valt er ooit toch iets buiten de container, dan wordt het hier afgesneden in plaats van
   dat de hele pagina horizontaal gaat schuiven. clip en niet hidden, want hidden maakt er een
   scrollcontainer van en dat sloopt sticky en scroll-snap. */
.section--bleed { overflow-x: clip; }
.section--soft { background: var(--bf-soft); }
.section--mist { background: var(--bf-mist); }
.section--warm { background: var(--bf-warm); }
.section--deep { background: var(--bf-deep); color: #eeecff; }
.section--deep h2 { color: #ffffff; }
.section--deep p { color: #d9d6ff; }

/* margin-inline: auto is niet cosmetisch. De sectiepadding is berekend om een container van
   1080px te centreren, dus een wrap van 680px bleef daarbinnen links kleven met bijna 600px leeg
   rechts op 1440px. Dat is precies de desktopklacht die de CRO-audit over de oude pagina maakt. */
.wrap { max-width: var(--bf-container); margin-inline: auto; }
.wrap--text { max-width: var(--bf-container-text); }

.stack > * + * { margin-top: var(--s5); }
.stack-tight > * + * { margin-top: var(--s3); }
.stack-loose > * + * { margin-top: var(--s6); }

.lead { font-size: var(--bf-lead); }
.muted { color: var(--bf-text-muted); }

.label {
  font-size: var(--bf-label);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bf-text-muted);
}

.rule { height: 1px; background: var(--bf-line); border: 0; margin: 0; }

/* ============================================================
   CARROUSEL-BOLLETJES
   ============================================================ */

/* Dient de drie swipe-rijen op de pagina: de kaarten in blok 3, de reviews in blok 4 en de
   kaartenrij in blok 5. De rijen swipen zonder JavaScript al, dit is er alleen de aanwijzing en de
   muis- en toetsenbordbediening bovenop. Vandaar display: none als beginwaarde: js/lp.js bouwt de
   balk en zet hem aan, en haalt is-scrollable er weer af zodra een rij op een breed scherm een
   raster wordt. Zo staat er nooit een lege of dode balk onder een rij. */
/* Snapgedrag van de drie rijen. Twee regels die het terugscrollen repareren:

   scroll-snap-align: end op de laatste kaart. Met start op alle kaarten ligt het snappunt van de
   laatste kaart voorbij de maximale scrollpositie: bij vier reviewkaarten van 340px in een rij van
   342px wil de vierde naar 1019 terwijl de rij op 1004 ophoudt. Dat snappunt is dus onbereikbaar, en
   dan vecht de snap-engine met je vinger zodra je van het einde terug wilt. Met end als laatste
   snappunt valt dat samen met de maximale scrollpositie en loopt het terugscrollen gewoon.

   scroll-snap-stop: always laat één veeg precies één kaart opschuiven in plaats van er twee of drie
   voorbij te schieten. Bij vier kaarten met tekst wil je ze allemaal langs, niet de helft overslaan. */
/* contain: paint op de drie rijen. Dit is een echte bugfix, geen optimalisatie, en de reden is
   subtiel genoeg om uit te schrijven.

   Op een viewport van 390px stond `document.documentElement.scrollWidth` op **1094** terwijl de pagina
   helemaal niet zijwaarts kan (pantest `scrollTo(300,0)` geeft `scrollX` 0). Die 1094 kwam volledig uit
   .reviews: die rij verbergen liet hem naar 390 zakken, .pcards en .board__row droegen niets bij. In
   een eerdere ronde is dat afgedaan als onschuldig meetartefact van de carrousels. Dat was het niet.

   Waarom het schaadt: scripts van derden meten de paginabreedte met precies dat getal. Cookiebot doet
   dat aantoonbaar, in `cc.js` staat `underlay.style.width = this.viewport.docWidth() + "px"`. Die zet
   dan een `position: fixed` element van circa 1100px op de pagina. Mobiele Chrome verbreedt daarop de
   layoutviewport en zoomt de hele pagina uit om dat element te laten passen, en dan staat de content in
   een smalle kolom van een derde van het scherm met de banner op normale grootte ernaast. Precies het
   beeld dat op Android gemeld is. Desktop-Chromium doet die zoom-to-fit niet, dus daar is het
   onzichtbaar, en dat is waarom dit lang onopgemerkt bleef.

   Waarom juist `contain: paint`: gemeten op 390px zakt de scrollWidth ermee naar 390. `overflow-x:
   hidden` op de rijen doet dat níet, en `overflow-x: hidden` op html ook niet. De rijen blijven
   scrollbaar (scrollWidth 1052, 1396 en 1168 tegen een clientWidth van 342), `scroll-snap-type` blijft
   `x mandatory` en `scrollLeft` werkt. Focusringen werden al geklipt doordat een scrollcontainer clipt,
   dus daar verandert niets. */
.pcards, .reviews, .board__row { contain: paint; }

.pcard, .rv, .board__slide { scroll-snap-stop: always; }
.pcards > :last-child,
.reviews > :last-child,
.board__row > :last-child { scroll-snap-align: end; }

.dots { display: none; }
.dots.is-scrollable {
  display: flex;
  justify-content: center;
  gap: var(--s2);
  margin-top: var(--s5);
}

/* Tikdoel van 44px met een bolletje van 8px erin, via padding in plaats van een klein knopje met
   een pseudo-element eromheen. De WCAG-eis van 44px zit zo in de knop zelf. */
.dots__dot {
  appearance: none;
  width: 44px;
  height: 44px;
  padding: 18px;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.dots__dot::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  border-radius: var(--bf-radius-round);
  background: var(--bf-line);
  transition: background var(--bf-duration) var(--bf-ease),
              transform var(--bf-duration) var(--bf-ease);
}
.dots__dot:hover::before { background: var(--bf-text-muted); }
/* De rand van --bf-line haalt geen 3:1 op de sectiegronden, dus het verschil tussen actief en
   inactief mag niet alleen kleur zijn. Het actieve bolletje is daarom ook groter. */
.dots__dot[aria-current]::before { background: var(--bf-cta); transform: scale(1.5); }

/* ============================================================
   ACCORDEON
   ============================================================ */

/* Eén set selectors voor de twee accordeons op de pagina: de FAQ in blok 9 en de lessen in blok 6.
   Zo kunnen het tikdoel en de chevron niet uit elkaar gaan lopen. Alles wat een van de twee anders
   doet, staat bij dat blok zelf, en die regels staan verder in dit bestand en winnen dus van deze.
   Dat is de reden dat deze set hier bovenaan staat en niet bij de FAQ.

   "Lees verder" op de reviewkaart hoorde hier ook bij, maar dat is sinds 04-08-2026 geen details meer:
   zie .rv__rest bij blok 4. */
.faq details, .lessons details { border-bottom: 1px solid var(--bf-line); }
.faq summary, .lessons summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  min-height: 56px; padding: var(--s4) 0;
  color: var(--bf-heading); font-weight: 600; font-size: var(--bf-body);
  cursor: pointer; list-style: none;
}
.faq summary::-webkit-details-marker,
.lessons summary::-webkit-details-marker { display: none; }
.faq summary::after, .lessons summary::after {
  content: "";
  flex: 0 0 auto; width: 10px; height: 10px;
  border-right: 2px solid var(--bf-cta); border-bottom: 2px solid var(--bf-cta);
  transform: rotate(45deg); transform-origin: center;
  transition: transform var(--bf-duration) var(--bf-ease);
}
.faq details[open] summary::after,
.lessons details[open] summary::after { transform: rotate(225deg); }

/* ============================================================
   KNOP
   ============================================================ */

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding-inline: var(--s5);
  background: var(--bf-cta);
  color: #ffffff;
  font-family: inherit;
  font-size: 1.0625rem;
  font-weight: 500;
  text-decoration: none;
  border: 0;
  border-radius: var(--bf-radius);
  padding-block: var(--s3);
  text-align: center;
  line-height: 1.3;
  transition: background var(--bf-duration) var(--bf-ease),
              transform var(--bf-duration) var(--bf-ease);
}
.cta:hover { background: var(--bf-cta-hover); transform: translateY(-1px); }
.cta:active { transform: translateY(0); }

/* ------------------------------------------------------------
   DOORLEES-KNOP

   Eén afspraak op de hele pagina: een gevulde knop koopt, een omlijnde knop leest door naar de
   volgende sectie. Zou een gevulde knop soms kopen en soms scrollen, dan leert de bezoeker dat
   knoppen hier onbetrouwbaar zijn, en dat kost je juist de klik die je wel wil.

   De rand staat als inset box-shadow en niet als border, zodat de knop exact dezelfde hoogte en
   binnenruimte houdt als .cta ernaast en erboven.
   ------------------------------------------------------------ */

.cta--ghost {
  background: transparent;
  color: var(--bf-cta);
  box-shadow: inset 0 0 0 2px var(--bf-cta);
  /* Ruimer dan .cta: deze labels zijn vragen en lopen vaak over twee regels. Met de padding van de
     koopknop komt de tweede regel tegen de omlijning aan te liggen. */
  padding-block: var(--s4);
  padding-inline: var(--s5);
}

/* Balanceert de twee regels, zodat er geen los woord op de tweede regel achterblijft. Waar
   text-wrap: balance niet bestaat, breekt de tekst gewoon zoals hij altijd al deed. */
.cta--ghost span { text-wrap: balance; }

/* De pijl staat in de tekstflow en niet als los flex-item, anders duwt de flexbox hem naar de
   rechterrand van de knop en raakt hij los van het laatste woord. */
.cta--ghost svg,
.cta-alt svg {
  display: inline-block;
  vertical-align: -2px;
  margin-left: var(--s2);
  transition: transform var(--bf-duration) var(--bf-ease);
}

/* Geen lichte vulling uit de tokens: blok 2 staat zelf op mist, daar zou die vulling wegvallen.
   Een doorschijnende tint van de knopkleur werkt op alle vier de sectiegronden. */
.cta--ghost:hover {
  background: rgba(69, 54, 245, 0.07);
  color: var(--bf-cta-hover);
  box-shadow: inset 0 0 0 2px var(--bf-cta-hover);
  transform: none;
}
.cta--ghost:hover svg,
.cta-alt:hover svg { transform: translateY(2px); }

/* De pijl beweegt in plaats van de knop: dit is een secundair element en deze doelgroep noemt
   drukke beweging expliciet als reden om af te haken. */

/* ------------------------------------------------------------
   COMPACTE KOOPKNOP ("Of start direct")

   De tweede kooproute onder een doorlees-knop, sinds 10-08-2026 een knop in plaats van het
   grijze tekstlinkje (feedback: las als kleine lettertjes). Gevuld en niet omlijnd, want de
   afspraak op deze pagina is dat een gevulde knop koopt en een omlijnde knop doorleest. Wel
   een maat kleiner dan .cta, zodat de doorlees-knop erboven de eerste keuze in het blok blijft.
   ------------------------------------------------------------ */

.cta--secondary {
  min-height: 44px;
  padding-block: var(--s2);
  font-size: 1rem;
}

/* ------------------------------------------------------------
   KLEIN TEKSTLINKJE ONDER DE KNOP

   In het middendeel: de kooproute onder een doorlees-knop. In de hero omgekeerd, daar staat de
   leesroute onder de koopknop. Zelfde vorm, want het is in beide gevallen de tweede keuze.
   ------------------------------------------------------------ */

.cta-alt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 44px;
  padding-inline: var(--s2);
  color: var(--bf-text-muted);
  font-size: var(--bf-small);
  line-height: 1.4;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: var(--bf-text-muted);
  transition: color var(--bf-duration) var(--bf-ease);
}
.cta-alt:hover { color: var(--bf-heading); text-decoration-color: currentColor; }

/* Extra lucht tussen de knop en het linkje eronder, bovenop de gap van de groep. Zonder dit kleeft
   de onderstreping tegen de rand van de knop en lezen de twee routes als één blok. */
.cta + .cta-alt { margin-top: var(--s2); }

/* .cta-note (de prijsregel onder de knop) is op 30-07-2026 op klantverzoek van alle knoppen
   gehaald. De prijs staat nog in de hero, in de stickybalk, in blok 8 en in de FAQ. */
.cta-group {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  margin-top: var(--s6);
}
.cta-group .cta { width: 100%; }

@media (min-width: 560px) {
  /* width: fit-content + align-items: stretch: de groep krimpt tot de breedte van zijn breedste
     knop (de doorlees-vraag), en een knop eronder (bv. "Of start direct") rekt mee tot diezelfde
     breedte. Zonder dit stonden twee knoppen in dezelfde groep op ongelijke breedte. */
  .cta-group { align-items: stretch; width: fit-content; }
  /* De doorlees-labels zijn hele vragen, dus geen vaste minimumbreedte maar een bovengrens,
     anders wordt de knop op een breed scherm één lange strook tekst. */
  .cta-group .cta { width: auto; min-width: 280px; max-width: 40ch; }
  /* .cta--secondary heeft een kleinere font-size dan .cta, dus 40ch valt voor deze knop op minder
     px uit dan voor de knop erboven: exact het gat uit de screenshot. Deze knop stelt zelf nooit
     de breedte van de groep vast (ze staat altijd onder een langere doorlees-knop), dus mag hij
     zonder eigen bovengrens meerekken tot de breedte die de knop erboven al bepaalt. */
  .cta-group .cta--secondary { max-width: none; }
}

.nowrap { white-space: nowrap; }
.tnum { font-variant-numeric: tabular-nums; }

/* ============================================================
   HEADER
   ============================================================ */

.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  height: 56px;
  padding: 0 max(var(--s5), calc((100% - var(--bf-container)) / 2));
  background: var(--bf-bg);
  border-bottom: 1px solid var(--bf-line);
}
.header__logo {
  display: flex; align-items: center; gap: var(--s2);
  min-height: 44px;
  color: var(--bf-heading); font-weight: 600; font-size: 1.0625rem;
  text-decoration: none; letter-spacing: -0.01em;
}
.header__logo img { height: 30px; width: 30px; }
.header .cta { display: none; min-height: 44px; padding: var(--s2) var(--s5); font-size: var(--bf-small); }
@media (min-width: 640px) { .header .cta { display: inline-flex; } }

/* ============================================================
   BLOK 1  HERO
   ============================================================ */

.hero { padding: var(--s6) max(var(--s5), calc((100% - var(--bf-container)) / 2)) var(--s7); }
.hero__grid { display: grid; gap: var(--s7); align-items: start; }
.hero h1 { margin-bottom: var(--s5); }
.hero__lead { font-size: var(--bf-lead); }
.hero__price {
  margin-top: var(--s5);
  font-size: var(--bf-lead);
  font-weight: 600;
  color: var(--bf-heading);
}
.hero .cta-group { margin-top: var(--s5); }

/* De doorlees-link onder de lead. Geen knopvorm: zie het commentaar in index.html. padding-inline op 0,
   anders staat de tekst 8px naar binnen ten opzichte van de lead erboven; de hoogte van 44px voor het
   tikdoel komt uit .cta-alt zelf en blijft staan. */
.hero__readmore { margin-top: var(--s4); }
.hero__readmore .cta-alt { padding-inline: 0; }

.proofline {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s2);
  margin-top: var(--s5);
  font-size: var(--bf-small);
  color: var(--bf-text-muted);
}
.proofline__item { display: inline-flex; align-items: center; gap: var(--s2); }
.proofline__stars { display: inline-flex; gap: 2px; color: var(--bf-star); }

/* De link houdt de kleur van de prooflineregel: hij hoort bij die regel en moet niet met de CTA
   gaan concurreren. Dat hij een link is, blijft leesbaar aan de onderstreping. */
.proofline__link {
  color: inherit;
  text-decoration-color: var(--bf-text-muted);
  text-underline-offset: 4px;
}
.proofline__link:hover { color: var(--bf-heading); text-decoration-color: currentColor; }

/* Zonder dit landt de kop van een ankersectie tegen de bovenrand van het scherm. De sectiepadding
   doet het meeste werk, dit is de extra ademruimte erbovenop. Geldt voor alle zeven de ankerdoelen,
   niet alleen voor het bewijsblok waar het anker begon. */
#herkenning,
#alarmstand,
#bewijs,
#psychologen,
#lessen,
#herkomst,
#kosten { scroll-margin-top: var(--s5); }

/* De ankerdoelen staan op tabindex="-1" zodat de focus na een sprong meeverhuist. Dat maakt ze
   focusbaar met de muis, en een focusring om een hele sectie is lelijk en zegt niets. De ring blijft
   dus alleen voor toetsenbordgebruik, waar hij wel iets zegt. */
section[tabindex="-1"]:focus { outline: none; }
section[tabindex="-1"]:focus-visible { outline: 2px solid var(--bf-cta); outline-offset: -4px; }

@media (min-width: 480px) {
  .proofline { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s6); }
}

@media (min-width: 900px) {
  .hero__grid { grid-template-columns: 1.05fr 0.95fr; gap: var(--s9); align-items: center; }
}

/* ============================================================
   DAGSTRIP  (signature element)
   ============================================================ */

/* Kop boven de vakjes, sinds 04-08-2026. Op de maat van een h3 en niet van een h2, want in de hero
   mag niets met de h1 concurreren. Blok 6 had deze kop eerst en heeft nu een eigen kop. */
.daystrip__title { font-size: var(--bf-h3); margin-bottom: var(--s4); }

.daystrip__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--s2);
}
.day {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border: 1px solid var(--bf-line);
  border-radius: var(--bf-radius);
  background: var(--bf-surface);
  color: var(--bf-text-muted);
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.daystrip__caption {
  margin-top: var(--s4);
  font-size: var(--bf-small);
  color: var(--bf-text-muted);
}

/* Mijlpalen: les 7, 14 en 21 in de hero. Lichtblauw en aanklikbaar, en ze klappen uit met waar je na
   die lessen staat. Hier stond ook een .day--on voor het gevulde vakje van les 1. Die is er op
   04-08-2026 uit gegaan, zodat lichtblauw op deze strip één ding betekent: hier kun je op tikken. */
.day--mile {
  padding: 0;
  background: var(--bf-mist);
  border-color: var(--bf-cta);
  /* Inset-schaduw bovenop de border: samen ogen ze als een 2px rand zonder dat de tegel van
     binnenmaat verandert. Extra randgewicht als klik-signaal (feedbackronde 10-08-2026). */
  box-shadow: inset 0 0 0 1px var(--bf-cta);
  color: var(--bf-heading);
}
.day__toggle {
  appearance: none;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: inherit;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
/* Klik-indicator (feedbackronde 10-08-2026): de lichtblauwe tint alleen zei niet dat je hier kon
   tikken. Een pijltje-omlaag rechtsboven in de tegel (zelfde rand-chevron als de FAQ- en
   lessen-accordeons, zodat "hier klapt iets uit" er overal hetzelfde uitziet), dat omhoog draait
   als het paneel open staat. Decoratief: de knop draagt de betekenis al via aria-expanded.
   Zonder JavaScript staan de panelen vast open en is er niets te klikken, dus daar gaat het
   pijltje weer af. */
.day__toggle::after {
  content: "";
  position: absolute;
  bottom: 5px;
  right: 6px;
  width: 6px;
  height: 6px;
  border-right: 2px solid var(--bf-cta);
  border-bottom: 2px solid var(--bf-cta);
  transform: rotate(45deg);
  transform-origin: center;
  transition: transform var(--bf-duration) var(--bf-ease);
}
.day--mile.is-open .day__toggle::after { border-color: #ffffff; transform: rotate(225deg); }
.no-js .day__toggle::after { content: none; }
/* Open: omgekeerd, zodat je zonder de panelen te lezen ziet welke mijlpaal open staat. Kleur alleen
   zou niet genoeg zijn, de rand verandert mee van dikte via de vulling. */
.day--mile.is-open { background: var(--bf-cta); border-color: var(--bf-cta); color: #ffffff; }
.day--mile:hover { background: #d8fbff; }
.day--mile.is-open:hover { background: var(--bf-cta-hover); }

/* De panelen. Beginwaarde is dicht; js/lp.js zet is-open erop. Werkt JavaScript niet, dan haalt de
   inline regel in de head .no-js niet weg en staan ze alle drie open. */
.mstones:has(.mstone.is-open) { margin-top: var(--s4); }
.mstone {
  display: none;
  padding: var(--s4);
  background: var(--bf-mist);
  border-radius: var(--bf-radius);
  font-size: var(--bf-small);
  color: var(--bf-text);
}
.mstone strong { display: block; }
.mstone.is-open { display: block; }
.no-js .mstones { margin-top: var(--s4); display: grid; gap: var(--s2); }
.no-js .mstone { display: block; }

/* De reveal-animatie stond op de tweede dagstrip in blok 6. Die strip is op 04-08-2026 verwijderd,
   dus .daystrip--reveal, .is-revealed en de bijbehorende IntersectionObserver in js/lp.js zijn ook
   weg. De dagstrip in de hero heeft geen reveal: die staat direct in beeld. */

@media (min-width: 560px) {
  .daystrip__grid { grid-template-columns: repeat(11, minmax(0, 1fr)); }
  .day { font-size: 1rem; }
}
@media (min-width: 900px) {
  .hero .daystrip__grid { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--s3); }
}

/* ============================================================
   BLOK 2  HERKENNING
   ============================================================ */

.signs__layout { display: grid; }
.signs__body { max-width: var(--bf-container-text); }

/* Illustratie vult op desktop de rechterkolom. Onder 900px verborgen: daar loopt
   de tekstkolom over de volle breedte en zou het beeld alleen lengte toevoegen. */
.signs__figure { display: none; }

@media (min-width: 900px) {
  .signs__layout {
    grid-template-columns: minmax(0, 1fr) minmax(280px, 400px);
    gap: var(--s8);
    align-items: start;
  }
  /* Bovenaan uitgelijnd met de eerste regel van de lijst, niet gecentreerd in de
     kolom: gecentreerd zakte het beeld te ver weg onder de kop. */
  .signs__figure {
    display: block;
    width: 100%;
    height: auto;
    margin-top: var(--s6);
    border-radius: var(--bf-radius);
  }
}

.signs { margin-top: var(--s6); border-top: 1px solid var(--bf-line); }
.signs li {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--bf-line);
  font-size: var(--bf-lead);
  color: var(--bf-heading);
}
.signs svg { flex: 0 0 auto; margin-top: 5px; color: var(--bf-cta); }

/* Twee kolommen alleen op tablet. Vanaf 900px staat de illustratie ernaast en is
   de tekstkolom te smal voor twee kolommen zonder lelijke afbrekingen. */
@media (min-width: 720px) and (max-width: 899px) {
  .signs { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s7); }
}

/* ============================================================
   BLOK 3  PROBLEEM
   ============================================================ */

.problem__head { display: grid; gap: var(--s6); align-items: start; }

/* Merkvorm van Breinfijn, getraceerd uit het merkbestand. Vult op desktop de
   rechterkolom die anders leeg blijft.

   Onder 760px verborgen sinds 04-08-2026. Daar staat de vorm onder de tekst in plaats van ernaast en
   kost hij circa 190px paginahoogte zonder iets te zeggen. Zelfde afweging als bij .signs__figure in
   blok 2, die om precies dezelfde reden al niet op mobiel staat. */
.blob { display: none; width: 100%; max-width: 150px; height: auto; justify-self: start; }

@media (min-width: 760px) {
  .blob { display: block; }
  .problem__head {
    grid-template-columns: minmax(0, var(--bf-container-text)) 1fr;
    gap: var(--s8);
    align-items: center;
  }
  .blob { max-width: 320px; justify-self: center; }
}

.subhead { margin-top: var(--s6); margin-bottom: var(--s3); }

/* Kaartenrij met de drie erkenningen. Neemt de scroll-snap-mechaniek over van .board__row in blok 5,
   maar met een tekstkaart in plaats van een beeldkaart: geen aspect-ratio, geen verloop, geen
   doorschijnend paneel en de radius van de pagina in plaats van de 24px die in blok 5 een
   gedocumenteerde uitzondering is. Dit blok breekt dus geen enkele regel van de Say-No List. */
.pcards {
  display: flex;
  /* Elke kaart zijn eigen hoogte. Met de standaard stretch worden alle drie zo hoog als de langste
     en houdt de kortste ruim 200px leegte onder de tekst, en dat leest als een fout. In het raster
     vanaf 1000px staan ze naast elkaar en zijn ze wel gelijk, want daar zie je ze samen. */
  align-items: start;
  gap: var(--s4);
  margin-top: var(--s7);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.pcards::-webkit-scrollbar { display: none; }

.pcard {
  flex: 0 0 auto;
  /* Grid en niet flex-column, zodat het icoon náást de kop staat in plaats van erboven. Op verzoek
     van de klant (04-08-2026). Dat is ook consistent met de lesonderdelen in blok 6, waar icoon en
     tekst al naast elkaar stonden. Het icoon kostte hier een eigen regel van 36px per kaart.

     Drie kinderen in de HTML (icoon, kop, body) vullen automatisch rij 1 kolom 1, rij 1 kolom 2 en
     dan rij 2. De body moet expliciet over beide kolommen, anders komt die naast het icoon terecht. */
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  /* align-content: start is niet optioneel. In het raster vanaf 1000px worden de kaarten even hoog
     gerekt, en de standaardwaarde van align-content is stretch: die verdeelt de overruimte over de
     twee auto-rijen, waardoor de tekst in de kortere kaarten halverwege de kaart begon. Flexbox deed
     dat niet, dus dit is een valkuil die pas met deze grid-omzetting ontstond. */
  align-content: start;
  column-gap: var(--s3);
  row-gap: var(--s3);
  /* 100% en niet 84vw. Een percentage rekent tegen de contentbox van de rij, vw tegen de
     layoutviewport, en die twee lopen op iOS uiteen tijdens het in- en uitschuiven van de adresbalk.
     Dit was de laatste plek in de layout die met de viewportbreedte rekende. */
  width: min(100%, 340px);
  padding: var(--s5);
  scroll-snap-align: start;
  background: var(--bf-surface);
  border: 1px solid var(--bf-line);
  border-radius: var(--bf-radius-card);
}

/* De 2px duwt het icoon optisch gelijk met de eerste regel van de kop: het icoon is 24px hoog en de
   regel van de kop 22px, en de tekentjes in het icoon beginnen iets onder de bovenrand. */
.pcard__icon { color: var(--bf-cta); margin-top: 2px; }
.pcard__title { font-size: var(--bf-h3); }
/* Kleiner dan de body: dit is de derde tekstlaag van de sectie, na de inleiding en de kaartkop.
   grid-column over beide kolommen, zodat de tekst onder het icoon door loopt en niet ernaast begint. */
.pcard__body { grid-column: 1 / -1; font-size: var(--bf-small); }
.pcard__body > * + * { margin-top: var(--s3); }

/* Vanaf 1000px passen drie kaarten van 340px plus twee tussenruimtes binnen de container van 1080px,
   dus daar staat de rij stil en wordt het een gewoon raster. Zelfde overgang als de board-rij, die
   op 1280px stilvalt omdat die kaarten breder zijn. */
@media (min-width: 1000px) {
  .pcards {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    /* Terug naar stretch: naast elkaar zie je de drie kaarten samen, en dan lezen gelijke randen als
       één set. De start uit de swipe-rij zou hier drie kaarten met ongelijke onderkanten geven. */
    align-items: stretch;
    overflow: visible;
    scroll-snap-type: none;
  }
  .pcard { width: auto; }
}

/* Redactionele tweedeling: kop plus aanleiding links, de uitwerking rechts op leesmaat.
   Vervangt een kolom van 680px die op 1440px bijna 600px leeg liet rechts. De tekst zelf blijft
   op 62ch, want prose in krantenkolommen zetten leest slechter, niet beter. */
.editorial__body > .subhead--first { margin-top: var(--s6); }

@media (min-width: 900px) {
  .editorial { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--s8); align-items: start; }
  .editorial__aside { position: sticky; top: calc(56px + var(--s5)); }
  .editorial__body > .subhead--first { margin-top: 0; }
}

/* ============================================================
   BLOK 4  BEWIJS
   ============================================================ */

/* Reviewkaart. De vier signalen die de CRO-audit als reden noemt dat dit het sterkste bewijs is:
   echte naam, datum, sterren, geverifieerd-vinkje. Plus het Google-beeldmerk, zodat je zonder
   te lezen ziet dat dit niet door Breinfijn geschreven is. Geen schaduw: de rand plus het
   kleurverschil met de sectiegrond doen het werk. */

/* Onder 900px een swipe-rij met bolletjes, op verzoek van de klant (04-08-2026). Vier reviewkaarten
   onder elkaar kostten ruim 900px hoogte; naast elkaar op één rij is dat de hoogte van de langste
   kaart. Vanaf 900px is er ruimte voor twee kolommen, wordt het weer een raster en verbergen de
   bolletjes zich, want dan valt er niets te scrollen. */
.reviews {
  margin-top: var(--s6);
  display: flex;
  /* Zie .pcards: in de swipe-rij krijgt elke kaart zijn eigen hoogte. Hier weegt dat zwaarder, want
     de langste recensie is ruim twee keer zo hoog als de kortste. */
  align-items: start;
  gap: var(--s4);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.reviews::-webkit-scrollbar { display: none; }

.rv {
  flex: 0 0 auto;
  /* Zie .pcard: percentage in plaats van vw. */
  width: min(100%, 340px);
  scroll-snap-align: start;
  background: var(--bf-surface);
  border: 1px solid var(--bf-line);
  border-radius: var(--bf-radius-card);
  padding: var(--s4);
}

.rv__head { display: grid; grid-template-columns: 40px 1fr 20px; gap: var(--s3); align-items: center; }
.rv__avatar { width: 40px; height: 40px; border-radius: var(--bf-radius-round); }
.rv__who { display: flex; flex-direction: column; min-width: 0; }
.rv__name { font-weight: 600; color: var(--bf-heading); }
.rv__date { font-size: var(--bf-label); color: var(--bf-text-muted); font-variant-numeric: tabular-nums; }

.rv__rating { display: flex; align-items: center; gap: var(--s2); margin: var(--s3) 0 0; max-width: none; }
.rv__stars { display: inline-flex; gap: 2px; color: var(--bf-star); }
/* Geen max-width: none hier. Tussen circa 600 en 900px staat de kaart nog in een kolom en wordt
   hij ruim 800px breed; zonder de leesmaat van 62ch levert dat regels van rond de 100 tekens op.
   Op desktop is de kaart 528px, dus daar is de kaartbreedte de begrenzing en niet deze regel. */
.rv__text { margin: var(--s3) 0 0; color: var(--bf-heading); max-width: var(--bf-measure); }
/* .rv__cut is op 04-08-2026 vervallen: de recensie van Johan staat nu voluit, dus er is geen
   afkapteken meer op de pagina. De regel is weg, niet uitgecommentarieerd. */

/* Lees verder, alleen op de langste recensie. Hier stond eerst een line-clamp van zes regels, maar die
   knipt op de regel en dus middenin een zin, en dan lijkt er tekst weggevallen. Daarna een native
   details, maar de inhoud daarvan blijft een blok, dus na het uitklappen begon de tweede helft op een
   nieuwe regel en las het als twee alinea's terwijl het één doorlopende zin is.

   Nu een inline span met een knop ernaast. Uitgeklapt loopt de tekst door alsof er nooit een knop
   stond, en de kaart begint even hoog als de andere drie. De knop verdwijnt zodra je hem gebruikt, op
   verzoek van de klant: één keer klikken en dan gewoon lezen.

   Zonder JavaScript staat de hele tekst er en is de knop weg. Dat is beter dan een knop die niets
   doet, en beter dan een halve recensie. */
.rv__rest { display: none; }
.rv__rest.is-open { display: inline; }
.rv__rest:focus { outline: none; }
.no-js .rv__rest { display: inline; }

.rv__more {
  appearance: none;
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--bf-cta-hover);
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
  cursor: pointer;
}
.rv__more::before { content: " "; }
.rv__more:hover { color: var(--bf-cta); }
.no-js .rv__more { display: none; }

/* Mobiel telt elke pixel: een kaart kost meer hoogte dan de haarlijnrij die hier eerst stond.
   Compacter maken waar het niets kost aan leesbaarheid, tikdoelen of de vier signalen zelf. */
@media (max-width: 599px) {
  .reviews { gap: var(--s3); }
  .rv { padding: var(--s3); }
  .rv__head { grid-template-columns: 36px 1fr 20px; gap: var(--s2); }
  .rv__avatar { width: 36px; height: 36px; }
  .rv__rating { margin-top: var(--s2); }
  .rv__text { margin-top: var(--s2); }
}

/* Twee kolommen zodra er ruimte is. De kaart wordt dan circa 500px, dus de leesregel blijft
   rond de 60 tekens. Over de volle 1080px zou een reviewregel op 110 tekens komen. */
@media (min-width: 900px) {
  .reviews {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s5);
    align-items: start;
    overflow: visible;
    scroll-snap-type: none;
  }
  .rv { width: auto; }
}

/* ============================================================
   BLOK 5  AUTORITEIT  (board, exact naar theliven.com)
   ============================================================

   Op klantverzoek (30-07-2026) overgenomen van theliven.com, sectie "Board of health
   professionals". Alle maten hieronder zijn uitgelezen uit de live computed styles en de CSSOM van
   die pagina op 390px en 1440px. Liven rekent in rem met html op 10px, dus 1.6rem is 16px. Hier
   staat het in px en in de tokens van deze pagina.

   Dit blok breekt vier regels van de Say-No List: verloop, doorschijnend paneel, een derde radius
   en een symmetrisch veelluik. Zie de gedocumenteerde uitzondering in DESIGN.md. Het oude blok
   staat in PARKED-blok4-expertkaart.md.

   Liven heeft ook een .expert-card__overlay en een __hover met blur. Die staan daar op opacity 0
   en dienen alleen hun klikbare videokaarten, dus die zijn hier niet overgenomen.

   Paginatiebolletjes en pijlen heeft Liven niet, gecontroleerd in de DOM: het is daar puur swipen.
   Tot 04-08-2026 volgde deze rij dat en had hij dus geen JS nodig. Sinds de klant om bolletjes bij
   de reviews vroeg, staan ze hier ook: de pagina heeft nu drie swipe-rijen, en één rij zonder
   aanwijzing tussen twee rijen met bolletjes leest als een fout in plaats van als een keuze. De
   bolletjes zitten los van de rij (zie CARROUSEL-BOLLETJES bovenaan dit bestand), dus wil je terug
   naar het model van Liven, dan haal je data-dots van de rij in de HTML en verandert hier niets. */

.board { display: flex; flex-direction: column; gap: var(--s6); }

/* Header. Bij Liven gecentreerd, en dat is de enige gecentreerde kop op deze pagina. Bewuste
   afwijking van het linkslijnende ritme, want een kaartenrij onder een linkse kop hangt scheef.
   Liven heeft hier ook een badge boven de kop staan. Die is er op klantverzoek (30-07-2026) uit,
   dus de header heeft nu alleen de kop. */
.board__header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s3);
  text-align: center;
}

.board__title {
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--bf-heading);
  max-width: 20ch;
}

/* Liven heeft onder de kop geen tekst. Deze regel staat er wel, want de audit vraagt bij dit blok
   expliciet om de kernzin over psychologen plus het mechanisme. Zo kort mogelijk gehouden: drie
   zinnen, en de leesmaat blijft binnen de 60 tekens die de rest van de pagina aanhoudt. */
.board__lead {
  max-width: 52ch;
  color: var(--bf-text-muted);
  /* Mobiel links, want zeven gecentreerde regels lezen slecht. Vanaf 768px staat de regel op
     ongeveer drie regels en volgt hij de gecentreerde kop van dit blok. */
  text-align: left;
}
@media (min-width: 768px) { .board__lead { text-align: center; } }

/* Rij. Onder 1280px een swipe-carrousel, naar model van Liven's .experts-list__swiper-row. Links
   lijnt de rij uit op de sectiepadding in plaats van op Liven's 16px vanaf de viewportrand, want uit
   de pas lopen met de rest van de pagina is erger dan 8px verschil in de indent.

   Liven laat de rij rechts doorlopen tot de viewportrand met margin-inline-end: calc(50% - 50vw), en
   dat deed deze rij tot 04-08-2026 ook. Eruit gehaald: op een echte iPhone kon de pagina daardoor
   horizontaal pannen, en een pagina die scheef staat is erger dan 24px minder doorkijk. De rij
   eindigt nu op de containerrand. Geldt ook voor .pcards in blok 3 en .reviews in blok 4. */
.board__row {
  display: flex;
  gap: var(--s4);
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.board__row::-webkit-scrollbar { display: none; }

.board__slide { flex: 0 0 auto; display: flex; scroll-snap-align: start; }
.board__cta { align-self: center; text-align: center; }

/* .cta-group lijnt zijn kinderen vanaf 560px links uit. Hier staat de groep zelf gecentreerd onder
   de kaartenrij, dus moeten de knop en het linkje daaronder dat ook zijn. */
@media (min-width: 560px) { .board__cta { align-items: center; } }

/* .board is een flexkolom met een gap van 32px, dus de eigen bovenmarge van de bolletjesbalk zou
   daar bovenop komen. */
.board .dots.is-scrollable { margin-top: 0; }

/* Kaart. Liven: aspect-ratio 288/440, radius 24px, padding 16px, breedte 280px en 284px vanaf
   1280px, inhoud onderaan. */
.bcard {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  width: 280px;
  aspect-ratio: 288 / 440;
  padding: var(--s4);
  border-radius: 24px;
  background: var(--bf-surface);
  overflow: hidden;
}

.bcard__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Het verloop stond op 160px met eindalpha 0,6. Die maat is gemeten op de foto van Marlies, waar de
   onderkant van het beeld al middendonker is. Sinds 04-08 staan er drie echte portretten en dat van
   Charlotte eindigt in een wit T-shirt in fel licht, waar wit op 0,6 zwart niet leesbaar is. Nu
   300px hoog met eindalpha 0,82, zodat het naamplaatje op alle drie de foto's op ongeveer dezelfde
   ondergrond staat. Het vlak van Charlotte en Lars met hun voorletter is hiermee vervallen. */
.bcard__gradient {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  min-height: 300px;
  background: linear-gradient(180deg,
    rgba(9, 13, 16, 0) 0%,
    rgba(9, 13, 16, 0.42) 46%,
    rgba(9, 13, 16, 0.82) 100%);
  pointer-events: none;
}

/* Was rgba(255,255,255,0.1): een licht vlak dat op een lichte foto oplost. Nu een donker vlak, dat
   werkt op elk beeld hetzelfde en houdt de witte tekst boven 4,5:1. De blur blijft. De gap is van
   8px naar 2px, want naam en functie horen bij elkaar en de kaarthoogte staat vast. Het plaatje is
   sinds 04-08 weer twee regels: de derde regel is er op klantverzoek af, zie de noot lager.

   De alpha is 0,46 en dat is gemeten, niet geschat. Op 0,34 haalde de slechtste beeldrij van het
   plaatje van Charlotte 4,3:1, net onder de eis: haar foto eindigt in een wit T-shirt in fel licht.
   Op 0,46 halen alle drie de plaatjes het. Verlaag deze waarde niet zonder opnieuw te meten, en meet
   ook opnieuw als er een lichtere foto bij komt. Meetwijze staat in QA.md. */
.bcard__info {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 104px;
  padding: var(--s3) var(--s4);
  border-radius: 16px;
  background: rgba(9, 13, 16, 0.46);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.bcard__name {
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.008em;
  color: #ffffff;
}

/* Liven zet de titel op #dee7ed. Dat haalt 12,3:1 op hun donkere verloop, maar op ons beeld staat
   de tekst op een lichter deel, dus wit is hier veiliger en verandert het beeld nauwelijks. */
.bcard__role {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.008em;
  color: #ffffff;
}

/* De regel onder de functietitel (.bcard__bio, 14px, geklemd) is op 04-08-2026 op klantverzoek weg,
   dezelfde dag dat hij erop kwam. De kaart is nu weer naam plus functietitel, zoals bij Liven. De
   regels zelf staan in COPY.md; de opmaak is hier weggehaald in plaats van uitgezet, want dode CSS
   voor drie verwijderde alinea's is erger dan hem opnieuw schrijven als de klant hem terugvraagt.

   Hover-zoom op het portret, klantverzoek 04-08-2026. Voorwaarden in de mediaquery, alle drie
   bewust:
   - `hover: hover` en `pointer: fine`: op touch blijft :hover na een tik hangen, en een kaart die
     ingezoomd blijft staan leest als een fout.
   - vanaf 1180px: onder die grens is de rij een swipe-carrousel en is dit een tikdoel, niet een
     muisdoel.
   Alleen `transform`, dus geen layoutwerk, en `.bcard` heeft overflow: hidden, dus de zoom blijft
   binnen de radius. Bron is 576x880 tegen een kaart van 258x394, dus ook op 1,06 en een 2x-scherm
   is er beeld genoeg (546 van 576 px). 500ms in plaats van de 200ms van de knoppen: een portret dat
   in 200ms opschiet leest als een schok en dit is een pagina over kalmeren. Onder
   prefers-reduced-motion gaat de zoom er helemaal af, niet alleen de duur naar 0, want een beeld dat
   in één keer verspringt is precies wat die voorkeur wil voorkomen. */
@media (hover: hover) and (pointer: fine) and (min-width: 1180px) {
  .bcard__media {
    transform-origin: center;
    transition: transform var(--bf-duration-slow) var(--bf-ease);
  }
  .bcard:hover .bcard__media { transform: scale(1.06); }
  @media (prefers-reduced-motion: reduce) {
    .bcard:hover .bcard__media { transform: none; }
  }
}

/* Vierde kaart. Liven: radius 24px, padding 24px, inhoud verdeeld over de hoogte, en geen eigen
   verhouding maar meerekken met de hoogte van de fotokaarten (align-self: stretch). Dat is hier
   veiliger dan een vaste verhouding, want Nederlandse woorden zijn langer en de kaart mag groeien
   als de claim ooit een regel langer wordt. */
.bcard--claim {
  justify-content: space-between;
  align-items: flex-start;
  aspect-ratio: auto;
  height: auto;
  padding: var(--s5);
  background: var(--bf-surface);
}

/* Liven levert de avatarrij als plaatje van 228x48 met vijf gezichten. Hier in HTML gebouwd, want
   er is maar een echte foto en gegenereerde of gekochte gezichten mogen niet. */
.bcard__avatars { display: flex; align-items: center; align-self: stretch; }
.bcard__avatar {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: var(--bf-radius-round);
  border: 2px solid var(--bf-surface);
  object-fit: cover;
  object-position: center 20%;
  background: var(--bf-soft);
}
.bcard__avatar + .bcard__avatar { margin-left: -12px; }
/* De vier lege gekleurde cirkels (--2 t/m --5) zijn er op 04-08-2026 uit. Zie de noot in
   index.html: ze suggereerden mensen zonder dat er iemand achter zat. */
.bcard__avatar--check {
  display: grid;
  place-items: center;
  background: var(--bf-cta);
  color: #ffffff;
}

.bcard__claim {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-self: stretch;
  gap: var(--s2);
}

/* Drie losse regels, net als bij Liven, zodat de regelval vast staat en niet meebeweegt met de
   kaartbreedte. */
.bcard__claim-line {
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--bf-heading);
}
.bcard__claim-note {
  font-size: 1rem;
  line-height: 1.5;
  color: var(--bf-text-muted);
}

@media (min-width: 768px) {
  .board { gap: 40px; }
}

/* Vanaf 1180px staat de rij stil, zoals bij Liven. Liven's exacte kaartbreedte van 284px kan hier
   niet: 4 x 284 plus 3 x 16 is 1184px en de container is 1080px. Tot 04-08-2026 stond hier
   width: 284px met justify-content: center, en dat sneed op desktop 52px van de eerste en de
   laatste kaart af. Niet omdat overflow het deed (die stond op visible), maar omdat deze rij
   contain: paint heeft staan voor de carrousel eronder, en die eigenschap klemt af op de
   padding-box los van wat overflow zegt. Zie QA.md.

   Dus: de vier kaarten verdelen de containerbreedte, wat neerkomt op 258px per kaart. Randen lopen
   nu gelijk met blok 3 en blok 4. Zet hier geen vaste breedte terug zonder ook contain: paint van
   deze rij af te halen, anders komt de afsnijding terug.

   Grens van 1280px naar 1180px: bij 1180px is de sectiepadding 50px en is de container precies
   1080px, dus daar past de vaste rij al. Met de oude grens kreeg een venster van 1180 tot 1279px een
   swipe-carrousel met 88px speling, onbedoeld op een muisscherm. Lager dan 1180px kan niet: dan
   krimpt de container mee en lopen de drie vaste claimregels buiten de vierde kaart. */
@media (min-width: 1180px) {
  .board { gap: 72px; }
  .board__row {
    margin-inline-end: 0;
    overflow: visible;
    scroll-snap-type: none;
  }
  .board__slide { flex: 1 1 0; min-width: 0; }
  .bcard { width: auto; }
  /* De drie claimregels zijn losse regels met een vaste regelval, dus ze moeten binnen 258 min 48
     padding is 210px passen. Op 1,75rem loopt "Ontwikkeld door" daar net buiten. */
  .bcard__claim-line { font-size: 1.5rem; }
  .board__title { font-size: 3.25rem; line-height: 1.1; letter-spacing: -0.04em; max-width: 18ch; }
}

/* ============================================================
   BLOK 6  WAT JE KRIJGT
   ============================================================ */

.anatomy { margin-top: var(--s6); display: grid; gap: 0; border-top: 1px solid var(--bf-line); }
/* Pictogram in een eigen kolom, zelfde opzet als de feitenlijst in blok 8: zo lijnen de koppen
   onder elkaar uit ook als een icoon smaller oogt dan het andere. */
.anatomy li {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: var(--s3);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--bf-line);
}
.anatomy svg { margin-top: 3px; color: var(--bf-cta); }
.anatomy strong { display: block; }
.anatomy div > span { display: block; font-size: var(--bf-small); color: var(--bf-text-muted); }

@media (min-width: 760px) {
  .anatomy { grid-template-columns: 1fr 1fr; column-gap: var(--s7); }
}

/* Lessen als dropdowns. De rand, het tikdoel en de chevron komen uit de accordeon van blok 9, die
   selectors staan daar op .faq en .lessons samen. Hier staat alleen wat deze lijst anders doet: de
   kop is tweeregelig (het lesbereik plus wat het je oplevert) en de inhoud is een genummerde lijst
   die doorloopt van 1 tot 21. */
.lessons { margin-top: var(--s6); border-top: 1px solid var(--bf-line); }

.lessons__sum { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lessons__range {
  font-size: var(--bf-label);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--bf-text-muted);
}
.lessons__gain { font-size: var(--bf-body); }

.lessons__answer { padding: 0 0 var(--s5); }
.lessons__intro { color: var(--bf-text-muted); font-size: var(--bf-small); }

/* Het lesnummer staat in een eigen kolom, net als de iconen bij .signs, .anatomy en .price__facts.
   Zo liggen de haarlijnen van deze lijst op dezelfde x als elke andere lijst op de pagina, en loopt
   een lestitel die afbreekt niet onder zijn eigen nummer door.

   Het nummer komt uit een counter en niet uit ::marker, want een marker kan niet in een gridkolom
   staan. De startwaarde komt per blok uit --from op het element, zodat de reeks doorloopt van 1 tot
   21 over de drie dropdowns. Het start-attribuut in de HTML blijft staan: dat is wat een schermlezer
   en een pagina zonder CSS gebruiken. */
.lessons__list {
  margin-top: var(--s4);
  border-top: 1px solid var(--bf-line);
  counter-reset: les var(--from, 0);
}
.lessons__list li {
  display: grid;
  grid-template-columns: 2.2em minmax(0, 1fr);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--bf-line);
  font-size: var(--bf-small);
  color: var(--bf-heading);
}
.lessons__list li::before {
  counter-increment: les;
  content: counter(les);
  color: var(--bf-text-muted);
  font-variant-numeric: tabular-nums;
}

/* Twee kolommen zodra er ruimte is. Anders dan bij de FAQ staat hier geen bovenrand-correctie: de
   drie dropdowns blijven onder elkaar, alleen de lessenlijst binnen een open dropdown splitst. */
/* Twee kolommen zodra er ruimte is. De bovenrand verhuist van de lijst naar elk item, anders loopt er
   in de tweede kolom een lijn door waar geen item onder staat. */
@media (min-width: 760px) {
  .lessons__list { columns: 2; column-gap: var(--s7); border-top: 0; }
  .lessons__list li { break-inside: avoid; border-top: 1px solid var(--bf-line); border-bottom: 0; }
}

/* ============================================================
   BLOK 7B  ANONIEME EVALUATIE
   ============================================================ */

/* Eigen sectie sinds 04-08-2026, zie de toelichting bij dit blok in index.html. Krapper dan een
   gewone sectie: het zijn twee quotes en een regel, en de volle sectiehoogte van de buren zou dit
   blok meer gewicht geven dan het heeft. */
.evalsection { padding-block: clamp(32px, 5.5vw, 56px); }

/* Gecentreerd in plaats van links: op 1440px zou een kolom van 680px links kleven met 400px leeg
   rechts, en dat is precies de desktopklacht uit de CRO-audit. Bij een lopend verhaal is centreren
   geen optie, bij twee losse quotes wel. */
.evaluations { max-width: var(--bf-container-text); margin-inline: auto; }
.evaluations blockquote {
  margin: 0; padding: var(--s4) 0;
  border-bottom: 1px solid var(--bf-line);
  color: var(--bf-heading);
}
.evaluations blockquote:first-of-type { border-top: 1px solid var(--bf-line); }
.evaluations .label + blockquote { margin-top: var(--s4); }

/* ============================================================
   BLOK 8  PRIJS
   ============================================================ */

/* De merkvorm stond hier als vulling van de rechterhelft, met als enige onderbouwing dat die
   helft anders leeg bleef. Nu de garantie daar staat, is die onderbouwing weg en zou de vorm
   alleen nog ruis achter tekst zijn. Weggehaald. De merkvorm blijft in blok 3.
   .section--warm houdt position: relative, want de sectie is verder ongewijzigd. */
.section--warm { position: relative; overflow: hidden; }

/* Links de beslissing (bedrag, termijnen, feiten, knop), rechts de gemoedsrust (garantie). */
@media (min-width: 900px) {
  .price { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--s8); align-items: start; }
  .guarantee { margin-top: var(--s5); }
}

.price__amount {
  font-size: clamp(2.75rem, 9vw, 4rem);
  font-weight: 600;
  line-height: 1;
  color: var(--bf-heading);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.price__terms { margin-top: var(--s3); font-size: var(--bf-lead); }
.price__facts { margin-top: var(--s6); border-top: 1px solid rgba(27, 22, 80, 0.14); }
.price__facts li {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: var(--s3);
  padding: var(--s4) 0;
  border-bottom: 1px solid rgba(27, 22, 80, 0.14);
}
/* 5px optische correctie, zelfde als bij de lijst in blok 2: het vinkje lijnt op de x-hoogte van de
   eerste regel en niet op de bovenkant van de regelhoogte. */
.price__facts svg { margin-top: 5px; color: var(--bf-cta); }
.price__facts strong { display: block; margin-bottom: 2px; }
/* Direct kind van de div, anders pakt deze regel ook de data-offer-spans binnen de strong en de
   getalspans binnen de uitleg, en dan staat er kleinere tekst midden in een regel. */
.price__facts div > span { display: block; font-size: var(--bf-small); }

.guarantee { margin-top: var(--s6); }
.guarantee strong { display: block; font-size: var(--bf-lead); margin-bottom: var(--s2); }


/* ============================================================
   BLOK 9  FAQ
   ============================================================ */

.faq { margin-top: var(--s6); border-top: 1px solid var(--bf-line); }

.faq__answer { padding: 0 0 var(--s5); }
.faq__answer > * + * { margin-top: var(--s3); }

/* Acht vragen in twee kolommen op desktop. De bovenrand verhuist van de container naar de
   eerste vraag van elke kolom, anders loopt er een lijn door waar geen vraag onder staat.
   Gebonden aan acht items in twee kolommen: verandert het aantal vragen, dan moet nth-child mee. */
@media (min-width: 900px) {
  .faq { border-top: 0; display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s8); align-items: start; }
  .faq details:nth-child(-n + 2) { border-top: 1px solid var(--bf-line); }
}

/* Blok 9b. Stond eerst op 680px en bleef daarmee links kleven onder de linkerkolom van de FAQ,
   met bijna 800px leeg rechts. Nu volle breedte met dezelfde tweedeling als blok 7: kop links,
   tekst rechts op leesmaat. Zo vult de kaart zichzelf in plaats van een gat te laten. */
.alt {
  margin-top: var(--s6);
  padding: var(--s5);
  background: var(--bf-surface);
  border: 1px solid var(--bf-line);
  border-radius: var(--bf-radius-card);
}
.alt h3 { margin-bottom: var(--s3); }
.alt a { display: inline-block; margin-top: var(--s4); min-height: 44px; line-height: 44px; font-weight: 600; }

@media (min-width: 900px) {
  .alt {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--s7);
    align-items: start;
    padding: var(--s6);
  }
  .alt h3 { margin-bottom: 0; }
}

/* ============================================================
   BLOK 10  SLOT
   ============================================================ */

.closing { text-align: left; }
.closing .price__amount { color: #ffffff; font-size: clamp(2rem, 6vw, 2.5rem); }
.closing .cta { background: #ffffff; color: var(--bf-deep); }
.closing .cta:hover { background: #eeecff; }

/* ============================================================
   STICKY BALK  (mobiel)
   ============================================================ */

/* z-index vlak onder het maximum, want de ronde Cookiebot-knop linksonder valt anders over de prijs in
   deze balk. Cookiebot werkt met 2147483630, 2147483631 en 2147483647; met 2147483646 gaat de balk over
   de eerste twee heen.

   Dat mag alleen omdat js/lp.js de balk weghoudt zolang de cookiedialoog open staat, ook als die later
   opnieuw verschijnt via de knop. Zonder die koppeling zou de balk over een consent-dialoog liggen, en
   dat mag niet. Pas die twee dus altijd samen aan.

   Gebruikt de knop wél 2147483647, dan is een z-index nooit genoeg. Daarvoor staat de regel bij
   .sticky-open hieronder: dan schuift de knop boven de balk. */
.sticky {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 2147483646;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s3) var(--s4);
  padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  background: var(--bf-surface);
  border-top: 1px solid var(--bf-line);
  box-shadow: 0 -2px 12px rgba(27, 22, 80, 0.07);
  transform: translateY(110%);
  transition: transform var(--bf-duration) var(--bf-ease);
}
.sticky.is-visible { transform: translateY(0); }
.sticky__price { flex: 1 1 auto; min-width: 0; line-height: 1.25; white-space: nowrap; }
.sticky__price strong { display: block; font-size: var(--bf-small); font-weight: 600; color: var(--bf-heading); }
.sticky__price span { display: block; font-size: var(--bf-label); color: var(--bf-text-muted); }
.sticky .cta { min-height: 48px; padding: var(--s3) var(--s5); font-size: var(--bf-small); flex: 0 0 auto; }

/* Op desktop stond deze balk eerder op display: none, want daar deden de knoppen in de pagina het
   werk. Sinds die knoppen doorlees-ankers zijn, is dit ook op desktop de enige kooproute tussen de
   hero en blok 8. De balk blijft over de volle breedte staan, de inhoud erin schuift mee met de
   paginacontainer, zodat prijs en knop onder de tekstkolom uitkomen en niet in de hoeken. */
@media (min-width: 900px) {
  .sticky {
    padding-block: var(--s2);
    padding-inline: max(var(--s5), calc((100% - var(--bf-container)) / 2));
    gap: var(--s6);
  }
  .sticky .cta { min-height: 44px; }
}

/* Zonder JS blijft de balk weg, want de knoppen in de pagina doen het werk */
.no-js .sticky { display: none; }

/* Vangnet voor het geval de ronde Cookiebot-knop op de maximale z-index staat en dus niet te
   overschrijven is: dan schuift de knop boven de balk zolang die in beeld is. js/lp.js zet de class
   sticky-open op het html-element. Staat de balk niet in beeld, dan zit de knop weer op zijn eigen
   plek linksonder. */
.sticky-open #CookiebotWidget {
  bottom: 88px !important;
  transition: bottom var(--bf-duration) var(--bf-ease);
}

/* ============================================================
   FOOTER
   ============================================================ */

.footer {
  padding: var(--s7) max(var(--s5), calc((100% - var(--bf-container)) / 2)) calc(var(--s9) + var(--s5));
  border-top: 1px solid var(--bf-line);
  font-size: var(--bf-small);
  color: var(--bf-text-muted);
}
.footer p { max-width: var(--bf-measure); }
.footer p + p { margin-top: var(--s3); }

@media (min-width: 900px) { .footer { padding-bottom: var(--s7); } }
