/* ── module: lettertypen ── */
/* Lokaal gehoste webfonts — gegenereerd door studio/tools/haal_webfonts_lokaal.py.
   Bewerk dit bestand niet met de hand: draai het script opnieuw na een
   wijziging in de fontbron.

   Reden voor lokaal hosten: een verzoek aan fonts.gstatic.com stuurt het
   IP-adres van de bezoeker naar Google vóór er toestemming is gevraagd.
   Lokaal hosten haalt die post uit de cookieverklaring, scheelt twee
   preconnect-rondes plus een DNS-lookup, en maakt de site onafhankelijk
   van een dienst van derden. */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/fraunces-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/fraunces-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/fraunces-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/fraunces-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/fraunces-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/fraunces-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/manrope-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/manrope-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/manrope-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/manrope-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/manrope-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(assets/fonts/manrope-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/manrope-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(assets/fonts/manrope-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(assets/fonts/manrope-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}  /* latin-ext */

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url(assets/fonts/manrope-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}  /* latin */

/* ── module: basis ── */
/* ============================================================
   BASIS — reset, ritme, containers, focus.
   Geen kleur- of maatwaarde: alles komt uit tokens.css.
   ============================================================ */
*{box-sizing:border-box;margin:0;padding:0}

html{
  scroll-behavior:smooth;
  /* Ankers landen onder de vaste header in plaats van erachter.
     Stond eerder nergens: #pakketten sprong naar een kop die door de
     balk bedekt werd, wat als "de link doet niets" oogt. */
  scroll-padding-top:calc(var(--ev-layout-header) + var(--ev-space-5));
}

body{
  font-family:var(--ev-font-body);
  background:var(--ev-color-surface-dark);
  color:var(--ev-color-ink-on-dark);
  line-height:var(--ev-leading-normal);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}

img{max-width:100%;display:block;height:auto}
svg{display:block}
ul,ol{list-style:none}

a{color:var(--ev-color-brand-accent);text-underline-offset:.22em;text-decoration-thickness:1px}
a:hover{color:var(--ev-color-brand-accent-bright)}

:focus-visible{
  outline:2px solid var(--ev-color-focus);
  outline-offset:3px;
  border-radius:var(--ev-radius-sm);
}

::selection{background:var(--ev-color-brand-accent);color:var(--ev-color-surface-dark)}

/* ── Containers ─────────────────────────────────────────────── */
.container{max-width:var(--ev-container);margin-inline:auto;padding-inline:var(--ev-space-5)}
.container-breed{max-width:var(--ev-layout-wide);margin-inline:auto;padding-inline:var(--ev-space-5)}
.container-smal{max-width:var(--ev-layout-narrow);margin-inline:auto;padding-inline:var(--ev-space-5)}

/* ── Sectieritme ────────────────────────────────────────────── */
.sectie{padding-block:var(--ev-section-y);position:relative}
.sectie-ruim{padding-block:calc(var(--ev-section-y) * 1.6)}
.sectie-krap{padding-block:var(--ev-space-8)}
.vlak-2{background:var(--ev-color-surface-dark-2)}
.vlak-licht{background:var(--ev-color-surface-light);color:var(--ev-color-ink-on-light)}
.vlak-licht h1,.vlak-licht h2,.vlak-licht h3{color:var(--ev-color-ink-on-light)}
.vlak-licht a{color:var(--ev-color-brand-action)}
.vlak-licht a:hover{color:var(--ev-color-brand-action-hover)}

/* Haarlijn tussen twee donkere vlakken — scheidt zonder te snijden. */
.rand-boven{border-top:1px solid var(--ev-color-border-on-dark)}

/* ── Toegankelijkheid ───────────────────────────────────────── */
.skip{
  position:absolute;left:var(--ev-space-4);top:var(--ev-space-4);z-index:200;
  transform:translateY(calc(-1 * (var(--ev-layout-header) + var(--ev-space-8))));
  background:var(--ev-color-brand-accent);color:var(--ev-color-surface-dark);
  padding:var(--ev-space-3) var(--ev-space-5);border-radius:var(--ev-radius-sm);
  font-weight:var(--ev-weight-bold);text-decoration:none;
  transition:transform var(--ev-dur-fast) var(--ev-ease);
}
.skip:focus{transform:none}

.enkel-screenreader{
  position:absolute;width:1px;height:1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0;
}

/* ── module: typografie ── */
/* ============================================================
   TYPOGRAFIE — de redactionele stem.
   Fraunces draagt de museale toon; Manrope leest.
   ============================================================ */
h1,h2,h3,h4{
  font-family:var(--ev-font-head);
  line-height:var(--ev-leading-tight);
  font-weight:var(--ev-weight-semibold);
  letter-spacing:-.015em;
  text-wrap:balance;
}

.kop-display{font-size:var(--ev-text-display);font-weight:var(--ev-weight-bold)}
.kop-sectie{font-size:var(--ev-text-5xl);margin-bottom:var(--ev-space-5);max-width:20ch}
.kop-sectie-breed{max-width:32ch}
.kop-klein{font-size:var(--ev-text-2xl)}

/* Het ene redactionele moment per pagina. */
.kop-mega{
  font-size:var(--ev-text-mega);
  font-weight:var(--ev-weight-bold);
  line-height:.98;
  letter-spacing:-.035em;
  text-wrap:balance;
}

/* Sectienummer als eyebrow — geeft redactionele structuur. */
.eyebrow{
  display:flex;align-items:center;gap:var(--ev-space-3);
  font-size:var(--ev-text-xs);font-weight:var(--ev-weight-bold);
  letter-spacing:.16em;text-transform:uppercase;
  margin-bottom:var(--ev-space-4);
  color:var(--ev-color-brand-accent);
}
.eyebrow::before{content:"";width:var(--ev-space-8);height:1px;background:var(--ev-signature-gradient);flex:none}
.eyebrow .nr{font-weight:var(--ev-weight-black);opacity:.5;font-variant-numeric:tabular-nums}
.vlak-licht .eyebrow{color:var(--ev-color-brand-action)}
.vlak-licht .eyebrow::before{background:var(--ev-color-brand-primary)}

.lead{
  font-size:var(--ev-text-xl);
  color:var(--ev-color-ink-on-dark-soft);
  max-width:56ch;
  line-height:1.5;
}
.vlak-licht .lead{color:var(--ev-color-ink-on-light-soft)}

.tekst{color:var(--ev-color-ink-on-dark-soft);max-width:64ch}
.tekst + .tekst{margin-top:var(--ev-space-4)}
.vlak-licht .tekst{color:var(--ev-color-ink-on-light-soft)}

.meta{color:var(--ev-color-ink-on-dark-muted);font-size:var(--ev-text-sm)}
.vlak-licht .meta{color:var(--ev-color-ink-on-light-soft)}

/* Signatuur: één gradient-woord per viewport. */
.goudwoord{
  background:var(--ev-signature-gradient);
  -webkit-background-clip:text;background-clip:text;
  color:transparent;
  /* Zonder deze regel kapt Fraunces' schuine uiteinden af in Safari. */
  padding-inline:.04em;margin-inline:-.04em;
}

/* Contourwoord — de tegenhanger van het gouden woord: aanwezig, niet luid. */
.contourwoord{
  color:transparent;
  -webkit-text-stroke:1.5px var(--ev-color-brand-accent);
  paint-order:stroke fill;
}

.cijfer-groot{
  font-family:var(--ev-font-head);
  font-size:var(--ev-text-4xl);
  font-weight:var(--ev-weight-bold);
  font-variant-numeric:tabular-nums;
  line-height:1;
  color:var(--ev-color-brand-accent);
}

blockquote.citaat{
  font-family:var(--ev-font-head);
  font-size:var(--ev-text-2xl);
  line-height:1.35;
  color:var(--ev-color-ink-on-dark);
  border-left:2px solid var(--ev-color-brand-accent);
  padding-left:var(--ev-space-5);
  max-width:34ch;
}
blockquote.citaat footer{
  font-family:var(--ev-font-body);
  font-size:var(--ev-text-sm);
  color:var(--ev-color-ink-on-dark-muted);
  margin-top:var(--ev-space-4);
  font-weight:var(--ev-weight-semibold);
  letter-spacing:.04em;
}

@media (max-width:720px){
  .kop-sectie{max-width:none}
  .lead{font-size:var(--ev-text-lg)}
}

/* ── module: knoppen ── */
/* ============================================================
   KNOPPEN — lift 2px, pijl schuift 5px mee.
   ============================================================ */
.knop{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--ev-space-3);
  font-family:var(--ev-font-body);font-weight:var(--ev-weight-bold);
  font-size:var(--ev-text-base);line-height:1.2;
  padding:var(--ev-space-4) var(--ev-space-6);
  border-radius:var(--ev-radius-sm);
  text-decoration:none;border:1px solid transparent;cursor:pointer;
  /* Labels breken niet binnen de knop — poort 1 meet dat. */
  white-space:nowrap;
  transition:transform var(--ev-dur-fast) var(--ev-ease),
             box-shadow var(--ev-dur-fast) var(--ev-ease),
             background var(--ev-dur-fast) var(--ev-ease),
             color var(--ev-dur-fast) var(--ev-ease),
             border-color var(--ev-dur-fast) var(--ev-ease);
}
.knop-goud{background:var(--ev-color-brand-accent);color:var(--ev-color-surface-dark)}
.knop-goud:hover{background:var(--ev-color-brand-accent-bright);color:var(--ev-color-surface-dark);transform:translateY(-2px);box-shadow:var(--ev-shadow-glow)}

.knop-lijn{background:transparent;color:var(--ev-color-brand-accent);border-color:color-mix(in srgb, var(--ev-color-brand-accent) 45%, transparent)}
.knop-lijn:hover{background:color-mix(in srgb, var(--ev-color-brand-accent) 10%, transparent);border-color:var(--ev-color-brand-accent);color:var(--ev-color-brand-accent-bright);transform:translateY(-2px)}

.knop-stil{background:transparent;color:var(--ev-color-ink-on-dark-soft);padding-inline:0}
.knop-stil:hover{color:var(--ev-color-brand-accent);transform:none}

.vlak-licht .knop-goud{background:var(--ev-color-brand-action);color:var(--ev-color-surface-light)}
.vlak-licht .knop-goud:hover{background:var(--ev-color-brand-action-hover);color:var(--ev-color-surface-light)}
.vlak-licht .knop-lijn{color:var(--ev-color-brand-action);border-color:color-mix(in srgb, var(--ev-color-brand-action) 40%, transparent)}
.vlak-licht .knop-lijn:hover{background:color-mix(in srgb, var(--ev-color-brand-action) 8%, transparent);color:var(--ev-color-brand-action-hover)}

.knop-rij{display:flex;flex-wrap:wrap;gap:var(--ev-space-4);align-items:center}

.pijl{display:inline-block;transition:transform var(--ev-dur-fast) var(--ev-ease)}
a:hover .pijl,button:hover .pijl{transform:translateX(5px)}

/* Chip: klein etiket, ook als filterknop in de galerij. */
.chip{
  display:inline-flex;align-items:center;gap:var(--ev-space-2);
  font-size:var(--ev-text-xs);font-weight:var(--ev-weight-bold);
  letter-spacing:.1em;text-transform:uppercase;
  padding:var(--ev-space-2) var(--ev-space-4);
  border-radius:var(--ev-radius-pill);
  border:1px solid var(--ev-color-border-on-dark);
  background:color-mix(in srgb, var(--ev-color-surface-dark) 70%, transparent);
  color:var(--ev-color-ink-on-dark-soft);
  text-decoration:none;cursor:pointer;
  transition:color var(--ev-dur-fast) var(--ev-ease),border-color var(--ev-dur-fast) var(--ev-ease),background var(--ev-dur-fast) var(--ev-ease);
}
.chip:hover{color:var(--ev-color-brand-accent);border-color:color-mix(in srgb, var(--ev-color-brand-accent) 50%, transparent)}
.chip[aria-pressed="true"]{background:var(--ev-color-brand-accent);color:var(--ev-color-surface-dark);border-color:var(--ev-color-brand-accent)}
.chip-goud{background:var(--ev-color-brand-accent);color:var(--ev-color-surface-dark);border-color:var(--ev-color-brand-accent)}

/* ── module: lichtval ── */
/* ============================================================
   LICHTVAL — het bewegingssysteem van deze case.
   ------------------------------------------------------------
   Eén idee, overal doorgevoerd: licht valt op wat donker was.
   Dat is letterlijk wat Esther in de studio doet, dus elke
   overgang op deze site is een vorm van belichten — nooit een
   effect dat er los overheen ligt.

   Drie lagen, in deze volgorde:

   1. RUSTSTAND. Alles staat in de eindstand. Geen script, geen
      ondersteuning nodig. Dit is wat een crawler, een reader en
      een browser zonder JavaScript krijgen te zien.
   2. REVEAL (.rv). IntersectionObserver zet .zichtbaar. Werkt
      overal, ook waar laag 3 niet werkt.
   3. SCROLL-GESTUURD (.lv-*). Alleen binnen
      @supports (animation-timeline: view()).

   Waarom laag 3 achter @supports staat en niet gewoon los:
   zonder animation-timeline valt `animation: x linear both`
   terug op een TIJD-gestuurde animatie. Die vuurt dan bij het
   laden — alles tegelijk, ver buiten beeld — en er faalt niets,
   dus dat blijft onopgemerkt tot iemand het toevallig ziet.
   Gemeten steun (27-08-2026, twee bronnen, oneens over Firefox):
     web-features   → Chrome/Edge 115+, Safari 26+, Firefox nee
     caniuse        → idem plus Firefox 157+, globaal 85,4%
   Ik reken met de pessimistische lezing. Circa 15% van de
   bezoekers krijgt laag 2 in plaats van laag 3, en die 15% moet
   een àf ontwerp zien — geen kaal ontwerp met gaten waar de
   animatie had gemoeten.
   ============================================================ */

/* ── Laag 2: reveal ─────────────────────────────────────────── */
.rv{
  opacity:0;
  transform:translateY(var(--ev-reveal-afstand));
  transition:opacity var(--ev-dur-base) var(--ev-ease),
             transform var(--ev-dur-base) var(--ev-ease);
}
.rv.zichtbaar{opacity:1;transform:none}
.rv-d1{transition-delay:.08s}
.rv-d2{transition-delay:.16s}
.rv-d3{transition-delay:.24s}
.rv-d4{transition-delay:.32s}
.rv-d5{transition-delay:.40s}

/* Geen JavaScript? Dan is de ruststand de eindstand. Zonder deze
   regel is een pagina zonder script volledig onzichtbaar — de
   duurste stille storing die dit systeem kan hebben. */
html.geen-js .rv{opacity:1;transform:none}

/* ── Textuur: korrel en vignet ──────────────────────────────── */
.grain{position:relative;isolation:isolate}
.grain::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:1;
  opacity:.05;border-radius:inherit;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.7'/%3E%3C/svg%3E");
}

/* Rembrandt-gloed: de warme lichtval die de hele richting draagt. */
.gloed{position:relative;isolation:isolate}
.gloed::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:var(--ev-signature-glow);
}
.gloed > *{position:relative;z-index:1}

/* ── De lichtvlek die de muis volgt ─────────────────────────── */
/* Het script levert alleen de coördinaat (--ev-motion-pointer-*).
   Wat er met die coördinaat gebeurt, staat hier — zodat een
   vormwijziging geen scriptwijziging is. */
.lv-spot{position:relative;isolation:isolate}
.lv-spot::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:0;
  background:radial-gradient(
      26rem 26rem at calc(var(--ev-motion-pointer-x) * 1%) calc(var(--ev-motion-pointer-y) * 1%),
      color-mix(in srgb, var(--ev-color-brand-accent) 14%, transparent) 0%,
      transparent 68%);
  opacity:0;
  transition:opacity var(--ev-dur-slow) var(--ev-ease);
}
.lv-spot.spot-aan::before{opacity:1}
.lv-spot > *{position:relative;z-index:1}

/* ── Fotokader: het doek ────────────────────────────────────── */
.doek{
  position:relative;overflow:hidden;
  border-radius:var(--ev-radius-md);
  border:1px solid var(--ev-color-border-on-dark);
  background:var(--ev-color-surface-dark-2);
  display:block;
}
.doek img{width:100%;height:100%;object-fit:cover;transition:transform var(--ev-dur-slow) var(--ev-ease)}
.doek::after{content:"";position:absolute;inset:0;background:var(--ev-signature-vignette);pointer-events:none}
.doek:hover img{transform:scale(1.04)}

/* Het lijstje: een dun goudlijntje dat bij hover om het doek trekt. */
.doek-lijst::before{
  content:"";position:absolute;inset:var(--ev-space-2);z-index:2;pointer-events:none;
  border:1px solid color-mix(in srgb, var(--ev-color-brand-accent) 0%, transparent);
  transition:border-color var(--ev-dur-base) var(--ev-ease),inset var(--ev-dur-base) var(--ev-ease);
}
.doek-lijst:hover::before{border-color:color-mix(in srgb, var(--ev-color-brand-accent) 55%, transparent)}

/* Eén echt beeld wijkt af van de rest: de werkfoto van Esther is op een
   lichte set gemaakt en breekt de donkere toon. Niet vervangen — hij is
   authentiek en juist daarom van waarde. Wel inpassen met randverdonkering
   en een spoortje minder verzadiging; het beeld zelf blijft ongewijzigd. */
.doek-warm img{filter:saturate(.9) brightness(.94) contrast(1.03)}
.doek-warm::after{background:var(--ev-signature-vignette),radial-gradient(120% 100% at 50% 50%, transparent 34%, color-mix(in srgb, var(--ev-color-surface-dark) 62%, transparent) 100%)}

.bijschrift{
  position:absolute;left:var(--ev-space-4);bottom:var(--ev-space-4);z-index:3;
  font-size:var(--ev-text-xs);letter-spacing:.12em;text-transform:uppercase;
  font-weight:var(--ev-weight-bold);
  color:var(--ev-color-ink-on-dark);
  text-shadow:0 1px 6px color-mix(in srgb, var(--ev-color-zwart) 70%, transparent);
  opacity:0;transform:translateY(var(--ev-space-2));
  transition:opacity var(--ev-dur-base) var(--ev-ease),transform var(--ev-dur-base) var(--ev-ease);
}
.doek:hover .bijschrift,.doek:focus-within .bijschrift{opacity:1;transform:none}

/* ── Laag 3: scroll-gestuurd ────────────────────────────────── */
@supports (animation-timeline: view()) {

  /* Iets stijgt in beeld terwijl je er naartoe scrollt. */
  @keyframes lv-stijg{
    from{opacity:0;transform:translateY(calc(var(--ev-reveal-afstand) * 2))}
    to{opacity:1;transform:none}
  }
  .lv-stijg{
    animation:lv-stijg linear both;
    animation-timeline:view();
    animation-range:entry 4% cover 26%;
  }

  /* Het ontwikkelbad: het beeld komt van onder naar boven op,
     met een warme lichtrand op de grens. */
  @keyframes lv-ontwikkel{
    from{clip-path:inset(0 0 100% 0);filter:brightness(.3) saturate(.6)}
    60%{filter:brightness(.9) saturate(.95)}
    to{clip-path:inset(0 0 0 0);filter:none}
  }
  .lv-ontwikkel{
    animation:lv-ontwikkel linear both;
    animation-timeline:view();
    animation-range:entry 0% cover 42%;
  }

  /* Drift: trage tegenbeweging binnen een kader. Parallax zonder script. */
  @keyframes lv-drift{from{transform:translateY(7%) scale(1.12)}to{transform:translateY(-7%) scale(1.12)}}
  .lv-drift img,img.lv-drift{
    animation:lv-drift linear both;
    animation-timeline:view();
    animation-range:cover 0% cover 100%;
  }

  /* De zin die woord voor woord oplicht, gestuurd door de scrollpositie
     van de ZIN — niet van het losse woord. Zonder de benoemde tijdlijn
     staan alle woorden op vrijwel dezelfde hoogte en vuren ze tegelijk. */
  .lv-zin{view-timeline-name:--lv-zin;view-timeline-axis:block}
  @keyframes lv-woord{
    from{color:var(--ev-color-ink-on-dark-muted);opacity:.32}
    to{color:var(--ev-color-ink-on-dark);opacity:1}
  }
  .lv-zin .w{
    display:inline-block;
    animation:lv-woord linear both;
    animation-timeline:--lv-zin;
  }
  .lv-zin .w:nth-child(1){animation-range:cover 12% cover 22%}
  .lv-zin .w:nth-child(2){animation-range:cover 15% cover 25%}
  .lv-zin .w:nth-child(3){animation-range:cover 18% cover 28%}
  .lv-zin .w:nth-child(4){animation-range:cover 21% cover 31%}
  .lv-zin .w:nth-child(5){animation-range:cover 24% cover 34%}
  .lv-zin .w:nth-child(6){animation-range:cover 27% cover 37%}
  .lv-zin .w:nth-child(7){animation-range:cover 30% cover 40%}
  .lv-zin .w:nth-child(8){animation-range:cover 33% cover 43%}
  .lv-zin .w:nth-child(9){animation-range:cover 36% cover 46%}
  .lv-zin .w:nth-child(10){animation-range:cover 39% cover 49%}
  .lv-zin .w:nth-child(11){animation-range:cover 42% cover 52%}
  .lv-zin .w:nth-child(12){animation-range:cover 45% cover 55%}
  .lv-zin .w:nth-child(13){animation-range:cover 48% cover 58%}
  .lv-zin .w:nth-child(14){animation-range:cover 51% cover 61%}
  .lv-zin .w:nth-child(15){animation-range:cover 54% cover 64%}
  .lv-zin .w:nth-child(16){animation-range:cover 57% cover 67%}
  .lv-zin .w:nth-child(n+17){animation-range:cover 60% cover 70%}
  /* Het goudwoord licht op maar houdt zijn gradient — kleur animeren
     zou de background-clip ongedaan maken, dus alleen de dekking. */
  .lv-zin .w.goudwoord{animation-name:lv-woord-goud}
  @keyframes lv-woord-goud{from{opacity:.24}to{opacity:1}}

  /* De hero: het licht opent zich terwijl je de eerste schermhoogte
     verlaat. Gekoppeld aan de documentscroll, niet aan zichtbaarheid —
     de hero staat al in beeld bij het laden, dus view() heeft daar
     geen bruikbaar bereik. */
  @keyframes lv-hero-doek{
    from{transform:scale(1.06) translateY(0);filter:brightness(1)}
    to{transform:scale(1) translateY(-4%);filter:brightness(.55)}
  }
  @keyframes lv-hero-tekst{
    from{opacity:1;transform:none}
    to{opacity:0;transform:translateY(calc(var(--ev-space-8) * -1))}
  }
  @keyframes lv-hero-gloed{
    from{opacity:.55;transform:scale(.7)}
    to{opacity:1;transform:scale(1.25)}
  }
  .lv-hero-doek{animation:lv-hero-doek linear both;animation-timeline:scroll(root block);animation-range:0 100vh}
  .lv-hero-tekst{animation:lv-hero-tekst linear both;animation-timeline:scroll(root block);animation-range:10vh 78vh}
  .lv-hero-gloed{animation:lv-hero-gloed linear both;animation-timeline:scroll(root block);animation-range:0 90vh}

  /* Sticky scene: de wisselende doeken. Het hoge blok is de tijdlijn,
     de plakkende laag is het toneel. */
  /* ── De plakkende scene ──────────────────────────────────────
     De bereiken lopen tot 78% en niet tot 100%, en dat getal is
     berekend, niet gekozen. De scene is 4,16x de schermhoogte; het
     `cover`-bereik van een element van H hoog is H + 1 scherm, dus
     5,16x. De plakkende laag laat los zodra de onderkant van de
     scene het scherm bereikt, en dat is op 4,16/5,16 = 80,6% van dat
     bereik. Alles wat na dat punt geanimeerd wordt, gebeurt terwijl
     het toneel al wegrolt: gemeten liepen de laatste twee overgangen
     buiten beeld af. Beide getallen staan in vh, dus de verhouding —
     en dus deze 78% — is onafhankelijk van de schermhoogte.
     Verandert `--ev-motion-scene-height` of de factor in galerij.css,
     dan verschuift dit punt mee en moeten deze bereiken opnieuw. */
  .lv-scene{view-timeline-name:--lv-scene;view-timeline-axis:block}
  @keyframes lv-plaat{
    0%{opacity:0;transform:scale(1.08);filter:brightness(.4)}
    14%{opacity:1;transform:scale(1);filter:none}
    78%{opacity:1;transform:scale(1);filter:none}
    100%{opacity:0;transform:scale(.96);filter:brightness(.4)}
  }
  /* De laatste plaat fadet niet uit: het toneel verdwijnt zelf al. */
  @keyframes lv-plaat-slot{
    0%{opacity:0;transform:scale(1.08);filter:brightness(.4)}
    14%{opacity:1;transform:scale(1);filter:none}
    100%{opacity:1;transform:scale(1);filter:none}
  }
  .lv-plaat{animation:lv-plaat linear both;animation-timeline:--lv-scene}
  .lv-plaat:nth-child(1){animation-range:cover 4% cover 26%}
  .lv-plaat:nth-child(2){animation-range:cover 22% cover 44%}
  .lv-plaat:nth-child(3){animation-range:cover 40% cover 62%}
  .lv-plaat:nth-child(4){animation-name:lv-plaat-slot;animation-range:cover 58% cover 78%}

  /* Het onderschrift wisselt mee met de plaat erachter. */
  .lv-plaat-tekst{animation:lv-plaat linear both;animation-timeline:--lv-scene}
  .lv-plaat-tekst:nth-child(1){animation-range:cover 5% cover 26%}
  .lv-plaat-tekst:nth-child(2){animation-range:cover 23% cover 44%}
  .lv-plaat-tekst:nth-child(3){animation-range:cover 41% cover 62%}
  .lv-plaat-tekst:nth-child(4){animation-name:lv-plaat-slot;animation-range:cover 59% cover 78%}

  /* De galerijbaan: verticaal scrollen wordt horizontaal lopen.
     De eindwaarde is met de hand uitgerekend uit de baanbreedte in
     de galerij-module (10 doeken x 40vw + 9 x 1.6vw tussenruimte =
     414,4vw; het rechterkader landt op 94vw, dus 94 - 414,4 = -320vw). Verandert het
     aantal doeken, dan verandert dit getal mee — het staat daarom
     hier, naast de maat, en niet in het script. */
  @keyframes lv-baan{from{transform:translateX(6vw)}to{transform:translateX(-320vw)}}
  /* Zelfde rekensom als bij de scene: de baan is 3,9x de schermhoogte,
     het cover-bereik 4,9x, dus de plakkende laag laat los op
     3,9/4,9 = 79,6%. Gemeten met een bereik tot 94% stonden de laatste
     twee doeken pas in beeld nadat het toneel al omhoog schoof — die
     twee beelden zag niemand ooit. */
  .lv-baan-spoor{
    animation:lv-baan linear both;
    animation-timeline:--lv-baan;
    animation-range:cover 7% cover 78%;
  }
  .lv-baan{view-timeline-name:--lv-baan;view-timeline-axis:block}

  /* De loep: inzoomen op het oog terwijl je scrolt. Geen voor/na-
     schuif — daarvoor zou een 'onbewerkte' versie van Esthers werk
     verzonnen moeten worden, en een nagemaakt bronbestand is precies
     het soort nep-artefact dat de eerlijkheidspoort moet uitsluiten.
     Dit zoomt in op het echte bestand en bewijst daarmee een ware
     bewering: het detail is er. */
  @keyframes lv-loep{
    from{transform:scale(1);filter:none}
    to{transform:scale(2.6);filter:contrast(1.04)}
  }
  .lv-loep img{
    transform-origin:50% 38%; /* het oog van het portret; per beeld te overschrijven op de pagina */
    animation:lv-loep linear both;
    animation-timeline:view();
    animation-range:entry 60% exit 40%;
  }

  /* Voortgangslijn van de tijdlijn: vult met het goudlicht. */
  .lv-tijdlijn{view-timeline-name:--lv-tijdlijn;view-timeline-axis:block}
  @keyframes lv-vullen{from{transform:scaleY(0)}to{transform:scaleY(1)}}
  .lv-vulling{
    transform-origin:top center;
    animation:lv-vullen linear both;
    animation-timeline:--lv-tijdlijn;
    animation-range:cover 18% cover 82%;
  }

  /* Leesvoortgang bovenaan de pagina. */
  @keyframes lv-voortgang{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  .lv-leeslijn{
    transform-origin:left center;
    animation:lv-voortgang linear both;
    animation-timeline:scroll(root block);
  }
}

/* ── Zonder scroll-tijdlijnen: dezelfde bestemming, andere weg ── */
@supports not (animation-timeline: view()) {
  /* De reveal-laag neemt het over; deze elementen krijgen .rv erbij
     in de markup, dus hier hoeft alleen de eindstand vast te staan. */
  /* De plaatsing van de scene-platen staat in de galerij-module, waar
     ook de tegenhanger voor deze tak staat: zonder tijdlijnen worden ze
     een raster in plaats van een stapel. Hier alleen het motion-deel. */
  .lv-zin .w{display:inline-block}
  .lv-vulling{transform:scaleY(1)}
  .lv-leeslijn{display:none}
}

/* ── Gereduceerde motion ────────────────────────────────────── */
/* Bewust per effect, niet met één blanket-regel. Een generieke
   "zet alle animaties op 0,001ms" springt naar de EINDstand — en
   voor de galerijbaan is de eindstand 308vw naar links, dus dan
   staat de hele baan buiten beeld. Een vluchtige regel die het
   ontwerp sloopt op precies de plek waar iemand hem het minst
   controleert. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .rv,.rv.zichtbaar{opacity:1;transform:none;transition:none}
  .doek img,.pijl,.knop,.kaart{transition:none}
  .doek:hover img{transform:none}
  .bijschrift{opacity:1;transform:none;transition:none}
  .lv-spot::before{display:none}

  .lv-stijg,.lv-ontwikkel,.lv-drift img,img.lv-drift,
  .lv-hero-doek,.lv-hero-tekst,.lv-hero-gloed,
  .lv-zin .w,.lv-plaat,.lv-plaat-tekst,
  .lv-baan-spoor,.lv-vulling,.lv-leeslijn,.lv-loep img{
    animation:none;
  }
  .lv-loep img{transform:none;filter:none}
  .lv-ontwikkel{clip-path:none;filter:none}
  .lv-drift img,img.lv-drift{transform:none}
  .lv-hero-doek{transform:none;filter:none}
  .lv-hero-tekst{opacity:1;transform:none}
  .lv-hero-gloed{opacity:1;transform:none}
  .lv-zin .w{color:var(--ev-color-ink-on-dark);opacity:1}
  .lv-vulling{transform:scaleY(1)}
  .lv-leeslijn{display:none}
  .lv-baan-spoor{transform:none}
}

/* ── module: header ── */
/* ============================================================
   HEADER — transparant boven de hero, vast bij scroll.
   ============================================================ */
.hdr{
  position:fixed;inset-block-start:0;inset-inline:0;z-index:60;
  view-transition-name:ev-hdr;
  transition:background var(--ev-dur-fast) var(--ev-ease),
             box-shadow var(--ev-dur-fast) var(--ev-ease),
             padding var(--ev-dur-fast) var(--ev-ease);
}
.hdr .balk{
  display:flex;align-items:center;gap:var(--ev-space-6);
  max-width:var(--ev-layout-wide);margin-inline:auto;
  padding:var(--ev-space-5);
  transition:padding var(--ev-dur-fast) var(--ev-ease);
}
.hdr.vast{
  background:color-mix(in srgb, var(--ev-color-surface-dark) 88%, transparent);
  backdrop-filter:blur(10px);
  box-shadow:0 1px 0 var(--ev-color-border-on-dark);
}
.hdr.vast .balk{padding-block:var(--ev-space-3)}

/* Leesvoortgang als haarlijn onder de balk. */
.leeslijn-baan{position:absolute;inset-block-end:0;inset-inline:0;height:2px;overflow:hidden;pointer-events:none}
.lv-leeslijn{height:100%;background:var(--ev-signature-gradient)}

.logo{
  display:flex;flex-direction:column;gap:2px;text-decoration:none;
  color:var(--ev-color-ink-on-dark);font-family:var(--ev-font-head);
  font-size:var(--ev-text-lg);letter-spacing:.01em;line-height:1.05;
  margin-inline-end:auto;flex:none;
}
.logo b{font-weight:var(--ev-weight-bold)}
.logo span{
  color:var(--ev-color-brand-accent);font-size:10px;
  font-family:var(--ev-font-body);font-weight:var(--ev-weight-bold);
  letter-spacing:.32em;text-transform:uppercase;
}

.nav-desktop{display:flex;align-items:center;gap:var(--ev-space-6)}
.nav-desktop a{
  position:relative;color:var(--ev-color-ink-on-dark-soft);text-decoration:none;
  font-weight:var(--ev-weight-semibold);font-size:var(--ev-text-sm);
  letter-spacing:.02em;padding-block:var(--ev-space-2);
  transition:color var(--ev-dur-fast) var(--ev-ease);
}
.nav-desktop a::after{
  content:"";position:absolute;inset-inline:0;inset-block-end:0;height:1px;
  background:var(--ev-signature-gradient);
  transform:scaleX(0);transform-origin:left center;
  transition:transform var(--ev-dur-base) var(--ev-ease);
}
.nav-desktop a:hover{color:var(--ev-color-ink-on-dark)}
.nav-desktop a:hover::after{transform:scaleX(1)}
.nav-desktop a[aria-current="page"]{color:var(--ev-color-brand-accent)}
.nav-desktop a[aria-current="page"]::after{transform:scaleX(1)}

.hdr-cta{flex:none;padding:var(--ev-space-3) var(--ev-space-5);font-size:var(--ev-text-sm)}

.hamburger{
  display:none;background:transparent;border:1px solid var(--ev-color-border-on-dark);
  color:var(--ev-color-ink-on-dark);border-radius:var(--ev-radius-sm);
  /* 44x44: tapdoel-ondergrens, niet 24 — poort 1 meet dit. */
  inline-size:44px;block-size:44px;padding:10px;cursor:pointer;flex:none;
}
.hamburger svg{inline-size:100%;block-size:100%}

@media (max-width:1080px){
  .nav-desktop,.hdr-cta{display:none}
  .hamburger{display:block}
}
@media (prefers-reduced-motion: reduce){
  .hdr,.hdr .balk,.nav-desktop a,.nav-desktop a::after{transition:none}
}

/* ── module: mobiel-menu ── */
/* ============================================================
   MOBIEL OFF-CANVAS MENU — niet onderhandelbaar in de shell.
   De meeste bezoekers van Esther kijken op hun telefoon.
   ============================================================ */
.oc-overlay{
  position:fixed;inset:0;z-index:70;
  background:color-mix(in srgb, var(--ev-color-zwart) 62%, transparent);
  backdrop-filter:blur(2px);
  opacity:0;visibility:hidden;
  transition:opacity var(--ev-dur-base) var(--ev-ease),visibility var(--ev-dur-base);
}
body.menu-open .oc-overlay{opacity:1;visibility:visible}

.oc{
  position:fixed;inset-block:0;inset-inline-end:0;z-index:80;
  inline-size:min(88vw, 400px);
  background:var(--ev-color-surface-dark-2);
  border-inline-start:1px solid var(--ev-color-border-on-dark);
  transform:translateX(100%);
  transition:transform var(--ev-dur-base) var(--ev-ease);
  display:flex;flex-direction:column;
  padding:var(--ev-space-5);
  overflow-y:auto;
  visibility:hidden;
}
body.menu-open .oc{transform:none;visibility:visible}
body.menu-open{overflow:hidden}

.oc-kop{display:flex;align-items:center;justify-content:space-between;gap:var(--ev-space-4);margin-bottom:var(--ev-space-7)}
.oc-sluit{
  background:transparent;border:1px solid var(--ev-color-border-on-dark);
  color:var(--ev-color-ink-on-dark);border-radius:var(--ev-radius-sm);
  inline-size:44px;block-size:44px;font-size:var(--ev-text-xl);line-height:1;cursor:pointer;
}
.oc nav ul{display:flex;flex-direction:column}
.oc nav a{
  display:block;padding-block:var(--ev-space-4);
  font-family:var(--ev-font-head);font-size:var(--ev-text-2xl);
  color:var(--ev-color-ink-on-dark);text-decoration:none;
  border-bottom:1px solid var(--ev-color-border-on-dark);
  transition:color var(--ev-dur-fast) var(--ev-ease),padding-inline-start var(--ev-dur-fast) var(--ev-ease);
}
.oc nav a:hover{color:var(--ev-color-brand-accent);padding-inline-start:var(--ev-space-2)}
.oc nav a[aria-current="page"]{color:var(--ev-color-brand-accent)}

/* De duimzone: bellen en boeken staan onderaan, waar de duim is. */
.oc-voet{margin-block-start:auto;padding-block-start:var(--ev-space-7);display:grid;gap:var(--ev-space-4)}
.oc-voet .knop{inline-size:100%}
.oc-voet .tel{
  display:flex;align-items:center;justify-content:center;gap:var(--ev-space-3);
  min-block-size:44px;
  color:var(--ev-color-ink-on-dark-soft);text-decoration:none;
  font-weight:var(--ev-weight-semibold);
}
.oc-voet .tel:hover{color:var(--ev-color-brand-accent)}

@media (prefers-reduced-motion: reduce){
  .oc,.oc-overlay,.oc nav a{transition:none}
}

/* ── module: paginakop ── */
/* ============================================================
   PAGINAKOP — de donkere kop van elke subpagina.
   Bestaat zodat de transparante header overal op donker start;
   zonder deze band zou de balk op een lichte sectie onleesbaar
   beginnen.
   ============================================================ */
.paginakop{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block:calc(var(--ev-layout-header) + var(--ev-space-9)) var(--ev-space-9);
  background:var(--ev-color-surface-dark);
  border-bottom:1px solid var(--ev-color-border-on-dark);
}
.paginakop-beeld{position:absolute;inset:0;z-index:0}
.paginakop-beeld img{inline-size:100%;block-size:100%;object-fit:cover;opacity:.3}
.paginakop-beeld::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(
    to right,
    var(--ev-color-surface-dark) 12%,
    color-mix(in srgb, var(--ev-color-surface-dark) 55%, transparent) 62%,
    color-mix(in srgb, var(--ev-color-surface-dark) 85%, transparent) 100%);
}
.paginakop-inhoud{position:relative;z-index:2}
.paginakop h1{font-size:var(--ev-text-display);font-weight:var(--ev-weight-bold);max-width:16ch}
.paginakop .lead{margin-block-start:var(--ev-space-5)}

.kruimels{
  display:flex;flex-wrap:wrap;gap:var(--ev-space-2);
  font-size:var(--ev-text-xs);color:var(--ev-color-ink-on-dark-muted);
  margin-block-end:var(--ev-space-5);letter-spacing:.06em;
}
.kruimels a{color:var(--ev-color-ink-on-dark-muted);text-decoration:none;display:inline-block;padding-block:var(--ev-space-2)}
.kruimels a:hover{color:var(--ev-color-brand-accent)}
.kruimels span[aria-hidden]{opacity:.45}

/* ── module: hero ── */
/* ============================================================
   HERO — het eerste scherm. Eén belofte, één knop, één beeld.
   ============================================================ */
.hero{
  position:relative;
  min-block-size:100svh;
  display:flex;align-items:center;
  padding-block:calc(var(--ev-layout-header) + var(--ev-space-9)) var(--ev-space-9);
  overflow:hidden;
  isolation:isolate;
}
.hero-gloed{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:var(--ev-signature-glow);
  transform-origin:68% 38%;
}
.hero-raster{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(color-mix(in srgb, var(--ev-color-wit) 3.5%, transparent) 1px,transparent 1px),
    linear-gradient(90deg,color-mix(in srgb, var(--ev-color-wit) 3.5%, transparent) 1px,transparent 1px);
  background-size:72px 72px;
  mask-image:radial-gradient(70% 60% at 50% 40%, var(--ev-color-ink-on-dark), transparent 72%);
}
.hero-grid{
  position:relative;z-index:2;
  display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:var(--ev-space-9);align-items:center;
  max-width:var(--ev-layout-wide);margin-inline:auto;padding-inline:var(--ev-space-5);
  inline-size:100%;
}
.hero h1{font-size:var(--ev-text-display);font-weight:var(--ev-weight-bold);margin-bottom:var(--ev-space-5);max-width:14ch}
.hero .lead{margin-bottom:var(--ev-space-7)}

/* Het doek in de hero: staand kader met het portret, gloed erachter.
   De wikkel bestaat omdat de badge half BUITEN het kader hoort te steken
   en het kader zelf overflow:hidden nodig heeft voor de afgeronde hoek.
   Zonder wikkel knipt datzelfde overflow de badge af — gemeten op 1440px:
   de sterren waren weg en de kaart begon midden in zijn eigen rand. */
.hero-doek-wikkel{position:relative}
.hero-doek{
  position:relative;
  aspect-ratio:4/5;
  border-radius:var(--ev-radius-lg);
  overflow:hidden;
  border:1px solid color-mix(in srgb, var(--ev-color-brand-accent) 26%, transparent);
  box-shadow:var(--ev-shadow-card-hover), var(--ev-shadow-glow);
}
.hero-doek img{inline-size:100%;block-size:100%;object-fit:cover;object-position:52% 32%}
.hero-doek::after{content:"";position:absolute;inset:0;background:var(--ev-signature-vignette);pointer-events:none}

/* Zwevende badge, half buiten het kader — asymmetrie boven symmetrie. */
.hero-badge{
  position:absolute;inset-block-end:var(--ev-space-7);inset-inline-start:calc(-1 * var(--ev-space-6));
  max-inline-size:19rem;
  z-index:3;
  background:var(--ev-color-surface-dark-2);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-md);
  box-shadow:var(--ev-shadow-card);
  padding:var(--ev-space-4) var(--ev-space-5);
  display:flex;align-items:center;gap:var(--ev-space-4);
  max-inline-size:19rem;
}
.hero-badge .sterren{color:var(--ev-color-star);letter-spacing:.12em;font-size:var(--ev-text-sm)}
.hero-badge strong{display:block;font-size:var(--ev-text-sm);color:var(--ev-color-ink-on-dark)}
.hero-badge span{display:block;font-size:var(--ev-text-xs);color:var(--ev-color-ink-on-dark-muted)}
/* De reviewlink in de badge erft de gedempte kleur; alleen de onderstreping
   verraadt dat hij klikbaar is — een felle linkkleur zou de badge domineren. */
.hero-badge a{color:inherit;text-decoration:underline;text-underline-offset:.15em}

/* Bewijscijfers onder de knoppen. */
.hero-cijfers{
  display:flex;flex-wrap:wrap;gap:var(--ev-space-7);
  margin-block-start:var(--ev-space-8);
  padding-block-start:var(--ev-space-6);
  border-top:1px solid var(--ev-color-border-on-dark);
}
.hero-cijfers > div{min-inline-size:8rem}
.hero-cijfers dt{
  font-family:var(--ev-font-head);font-size:var(--ev-text-3xl);
  font-weight:var(--ev-weight-bold);color:var(--ev-color-brand-accent);
  line-height:1;font-variant-numeric:tabular-nums;
}
.hero-cijfers dd{
  color:var(--ev-color-ink-on-dark-muted);font-size:var(--ev-text-sm);
  margin-block-start:var(--ev-space-2);max-inline-size:16ch;
}

/* Scroll-hint: een lijntje dat ademt. */
.hero-hint{
  position:absolute;inset-block-end:var(--ev-space-6);inset-inline-start:50%;
  translate:-50% 0;z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:var(--ev-space-3);
  color:var(--ev-color-ink-on-dark-muted);
  font-size:10px;letter-spacing:.28em;text-transform:uppercase;
}
.hero-hint i{display:block;inline-size:1px;block-size:var(--ev-space-8);background:linear-gradient(var(--ev-color-brand-accent),transparent);animation:hero-adem 2.6s var(--ev-ease) infinite}
@keyframes hero-adem{0%,100%{opacity:.25;transform:scaleY(.6)}50%{opacity:1;transform:scaleY(1)}}

@media (max-width:1080px){
  .hero-grid{grid-template-columns:1fr;gap:var(--ev-space-8)}
  .hero{min-block-size:auto;padding-block:calc(var(--ev-layout-header) + var(--ev-space-8)) var(--ev-space-8)}
  .hero-doek{aspect-ratio:5/4;order:-1}
  .hero-badge{inset-inline-start:auto;inset-inline-end:var(--ev-space-4);inset-block-end:var(--ev-space-4)}
  .hero-hint{display:none}
}
@media (max-width:720px){
  .hero h1{max-width:none}
  .hero-cijfers{gap:var(--ev-space-5)}
  .hero-cijfers dt{font-size:var(--ev-text-2xl)}
  .hero-badge{position:static;max-inline-size:none;margin-block-start:var(--ev-space-4)}
}
@media (prefers-reduced-motion: reduce){
  .hero-hint i{animation:none;opacity:.6}
}

/* ── module: kaarten ── */
/* ============================================================
   KAARTEN — het dragende blok voor alles wat groepeert.
   ============================================================ */
.kaart{
  position:relative;
  background:var(--ev-color-surface-dark-2);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-lg);
  padding:var(--ev-space-6);
  transition:transform var(--ev-dur-fast) var(--ev-ease),
             box-shadow var(--ev-dur-fast) var(--ev-ease),
             border-color var(--ev-dur-fast) var(--ev-ease);
}
.kaart h3{font-size:var(--ev-text-xl);margin-bottom:var(--ev-space-3)}
.kaart p{color:var(--ev-color-ink-on-dark-soft)}
a.kaart,.kaart-hover{cursor:pointer}
a.kaart:hover,.kaart-hover:hover{
  transform:translateY(-4px);
  box-shadow:var(--ev-shadow-card-hover);
  border-color:color-mix(in srgb, var(--ev-color-brand-accent) 38%, transparent);
}
.kaart-uit{background:transparent;border-color:color-mix(in srgb, var(--ev-color-brand-accent) 12%, transparent)}

.raster-2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ev-space-5)}
.raster-3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--ev-space-5)}
.raster-4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--ev-space-5)}
.raster-auto{display:grid;grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));gap:var(--ev-space-5)}

/* Ikoonkaart: een cirkel met een lijnicoon dat bij hover oplicht. */
.ikoon{
  inline-size:var(--ev-space-8);block-size:var(--ev-space-8);
  display:grid;place-items:center;
  border-radius:var(--ev-radius-pill);
  border:1px solid color-mix(in srgb, var(--ev-color-brand-accent) 30%, transparent);
  color:var(--ev-color-brand-accent);
  margin-bottom:var(--ev-space-5);
  transition:background var(--ev-dur-base) var(--ev-ease),transform var(--ev-dur-base) var(--ev-ease);
}
.ikoon svg{inline-size:20px;block-size:20px}
.kaart-hover:hover .ikoon,a.kaart:hover .ikoon{
  background:color-mix(in srgb, var(--ev-color-brand-accent) 14%, transparent);
  transform:rotate(-6deg);
}

/* USP-balk: vier korte bewijsregels op één lijn. */
.usp-balk{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:var(--ev-space-5);
  padding-block:var(--ev-space-6);
  border-block:1px solid var(--ev-color-border-on-dark);
}
/* Kindselector, niet nakomeling: `.usp-balk div` raakte ook de binnenste
   div en maakte die flex, waardoor het label en de omschrijving naast
   elkaar kwamen te staan in plaats van onder elkaar. Op desktop zag dat
   er nog plausibel uit; op 375px liep het uit elkaar. */
.usp-balk > div{display:flex;gap:var(--ev-space-4);align-items:flex-start}
.usp-balk svg{inline-size:20px;block-size:20px;color:var(--ev-color-brand-accent);flex:none;margin-block-start:3px}
.usp-balk strong{display:block;font-size:var(--ev-text-sm);color:var(--ev-color-ink-on-dark)}
.usp-balk span{display:block;font-size:var(--ev-text-xs);color:var(--ev-color-ink-on-dark-muted);margin-block-start:2px}

/* Reviewkaart. */
.review{display:flex;flex-direction:column;gap:var(--ev-space-4);block-size:100%}
.review .sterren{color:var(--ev-color-star);letter-spacing:.14em}
.review blockquote{
  font-family:var(--ev-font-head);font-size:var(--ev-text-lg);
  line-height:1.45;color:var(--ev-color-ink-on-dark);
}
.review figcaption{
  margin-block-start:auto;padding-block-start:var(--ev-space-4);
  border-top:1px solid var(--ev-color-border-on-dark);
  font-size:var(--ev-text-xs);color:var(--ev-color-ink-on-dark-muted);
  display:flex;align-items:center;justify-content:space-between;gap:var(--ev-space-3);
}
/* Het etiket dat zegt wat het is. Klein, maar niet weggemoffeld:
   een voorbeeldreview die zich voordoet als een echte is precies
   de vorm waarmee je het vertrouwen van de eindklant verspeelt. */
.voorbeeldmerk{
  font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ev-color-ink-on-dark-muted);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-pill);
  padding:2px var(--ev-space-3);flex:none;
}

@media (max-width:1080px){
  .raster-4{grid-template-columns:repeat(2,minmax(0,1fr))}
  .usp-balk{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ev-space-6)}
}
@media (max-width:720px){
  .raster-2,.raster-3,.raster-4{grid-template-columns:1fr}
  .usp-balk{grid-template-columns:1fr}
}

/* ── module: galerij ── */
/* ============================================================
   GALERIJ — het werk. Vier vormen, één grammatica.
   1. .werkraster  — het rustige raster (portfolio)
   2. .scene       — plakkende scene waarin doeken elkaar aflossen
   3. .lv-baan     — verticaal scrollen wordt horizontaal lopen
   4. .loep        — inzoomen op het detail
   ============================================================ */

/* ── 1. Werkraster ──────────────────────────────────────────── */
.werkraster{
  display:grid;
  grid-template-columns:repeat(12,minmax(0,1fr));
  gap:var(--ev-space-4);
}
/* Ritme in plaats van een uniform raster: een drieluik, dan twee paren.
   De periode is 7 en telt precies 36 kolommen = drie volle rijen:
       positie 1,2,3  -> span 4   (rij van 12)
       positie 4,5    -> span 6   (rij van 12)
       positie 6,7    -> span 6   (rij van 12)
   Dat is geen esthetische keuze maar een rekensom. De eerdere regel
   (elke 5e en 8e span 6) liet per rij 2 van de 12 kolommen leeg —
   gemeten op 1440px: zeven van de acht rijen hadden een gat van 247px,
   en een 478px. Binnen een rij hebben alle tegels nu dezelfde span, dus
   ook dezelfde hoogte; een rij met een brede en een smalle tegel laat
   onder de smalle altijd lucht staan.
   17 portretten = 7 + 7 + 3, en die staart valt op positie 1,2,3 —
   dus opnieuw een volle rij. Verandert het aantal beelden, controleer
   dan of de staart nog uitkomt. `dense` vangt de rest af, en is nodig
   zodra het filter tegels verbergt: nth-child telt die dan nog wel mee. */
.werkraster{grid-auto-flow:dense}
.werkraster .doek{grid-column:span 4;aspect-ratio:4/3}
.werkraster .doek:nth-child(7n+4),
.werkraster .doek:nth-child(7n+5),
.werkraster .doek:nth-child(7n+6),
.werkraster .doek:nth-child(7n+7){grid-column:span 6;aspect-ratio:3/2}

.werkkop-rij{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:var(--ev-space-6);flex-wrap:wrap;margin-bottom:var(--ev-space-7);
}
.filterrij{display:flex;flex-wrap:wrap;gap:var(--ev-space-3);margin-bottom:var(--ev-space-6)}
.doek[hidden]{display:none}

/* ── 2. Plakkende scene ─────────────────────────────────────── */
.scene{position:relative}
.scene-plak{
  position:sticky;inset-block-start:0;
  block-size:100svh;
  display:grid;place-items:center;
  overflow:hidden;
  padding-block:var(--ev-layout-header) var(--ev-space-7);
}
/* 3:2 en niet 16:10: alle bronbeelden zijn 3:2, dus dit kader snijdt
   niets weg — gemeten sneed 16:10 de oren van de bulldog af. */
.scene-stapel{
  position:relative;
  inline-size:min(92vw, 58rem);
  aspect-ratio:3/2;
  border-radius:var(--ev-radius-lg);
  overflow:hidden;
  border:1px solid var(--ev-color-border-on-dark);
  box-shadow:var(--ev-shadow-card-hover);
}
.scene-stapel img{inline-size:100%;block-size:100%;object-fit:cover}
.scene-onderschrift{
  position:relative;
  margin-block-start:var(--ev-space-6);
  min-block-size:5.5rem;
  inline-size:min(92vw, 42rem);
  text-align:center;
}
.lv-plaat-tekst{inset-inline:0}
.lv-plaat-tekst h3{font-size:var(--ev-text-2xl);margin-bottom:var(--ev-space-2)}
.lv-plaat-tekst p{color:var(--ev-color-ink-on-dark-soft);font-size:var(--ev-text-base)}

@supports (animation-timeline: view()){
  .scene{block-size:calc(var(--ev-motion-scene-height) * 1.6)}
  .lv-plaat{position:absolute;inset:0}
  .lv-plaat-tekst{position:absolute;inset-block-start:0}
}
/* Zonder scroll-tijdlijnen wordt de scene een net raster. Niet de
   ervaring, wel een af ontwerp — en dat is het verschil tussen een
   fallback en een gat. */
@supports not (animation-timeline: view()){
  .scene{block-size:auto}
  .scene-plak{position:static;block-size:auto;padding-block:0}
  .scene-stapel{inline-size:100%;aspect-ratio:auto;border:0;box-shadow:none;overflow:visible;
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ev-space-5)}
  .lv-plaat{position:relative;border-radius:var(--ev-radius-md);overflow:hidden;border:1px solid var(--ev-color-border-on-dark)}
  .scene-onderschrift{position:static;inline-size:100%;min-block-size:0;text-align:start;
    display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ev-space-5);margin-block-start:var(--ev-space-5)}
  .lv-plaat-tekst{position:static}
}

/* ── 3. De baan ─────────────────────────────────────────────── */
.lv-baan{position:relative}
.baan-plak{
  position:sticky;inset-block-start:0;
  block-size:100svh;
  display:flex;flex-direction:column;justify-content:center;
  overflow:hidden;
}
.baan-kop{
  max-width:var(--ev-layout-wide);margin-inline:auto;inline-size:100%;
  padding-inline:var(--ev-space-5);margin-block-end:var(--ev-space-7);
}
.lv-baan-spoor{display:flex;gap:1.6vw;will-change:transform}
/* 40vw met 3:2 gaf op een viewport van 900px doeken van 384px hoog: de
   scène oogde half leeg. 4:3 op dezelfde breedte houdt de baanlengte
   (en dus de handmatig berekende eindtranslatie in lichtval.css) gelijk. */
.lv-baan-spoor .doek{inline-size:40vw;flex:none;aspect-ratio:4/3}

@supports (animation-timeline: view()){
  .lv-baan{block-size:calc(var(--ev-motion-scene-height) * 1.5)}
}
@supports not (animation-timeline: view()){
  .lv-baan{block-size:auto}
  .baan-plak{position:static;block-size:auto;padding-block:var(--ev-space-8)}
  .lv-baan-spoor{overflow-x:auto;scroll-snap-type:x mandatory;padding-inline:var(--ev-space-5);padding-block-end:var(--ev-space-4)}
  .lv-baan-spoor .doek{inline-size:min(78vw,26rem);scroll-snap-align:center}
}
@media (max-width:900px){
  .lv-baan{block-size:auto}
  .baan-plak{position:static;block-size:auto;padding-block:var(--ev-space-8)}
  .lv-baan-spoor{overflow-x:auto;scroll-snap-type:x mandatory;padding-inline:var(--ev-space-5);padding-block-end:var(--ev-space-4);animation:none;transform:none}
  .lv-baan-spoor .doek{inline-size:min(78vw,22rem);scroll-snap-align:center}
}

/* ── 4. De loep ─────────────────────────────────────────────── */
.loep{
  position:relative;overflow:hidden;
  border-radius:var(--ev-radius-lg);
  border:1px solid var(--ev-color-border-on-dark);
  aspect-ratio:3/2;
}
.loep img{inline-size:100%;block-size:100%;object-fit:cover;will-change:transform}
.loep::after{content:"";position:absolute;inset:0;background:var(--ev-signature-vignette);pointer-events:none}
.loep-label{
  position:absolute;z-index:2;inset-block-end:var(--ev-space-4);inset-inline-start:var(--ev-space-4);
  background:color-mix(in srgb, var(--ev-color-surface-dark) 78%, transparent);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-pill);
  padding:var(--ev-space-2) var(--ev-space-4);
  font-size:var(--ev-text-xs);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ev-color-ink-on-dark-soft);
}

@media (max-width:900px){
  .werkraster{grid-template-columns:repeat(6,minmax(0,1fr))}
  .werkraster .doek{grid-column:span 3;aspect-ratio:4/3}
  .werkraster .doek:nth-child(7n+4),.werkraster .doek:nth-child(7n+5),
  .werkraster .doek:nth-child(7n+6),.werkraster .doek:nth-child(7n+7){grid-column:span 6;aspect-ratio:3/2}
  /* De scene degradeert op mobiel volledig: een plakkende scene die
     niet plakt laat de platen los van hun tijdlijn en levert een
     leeg vlak op dat er niet als fout uitziet. Daarom hier dezelfde
     rasteruitkomst als de tak zonder tijdlijn-ondersteuning.
     Deze module staat NA lichtval in site.yaml — anders wint de
     animation-regel daar en verandert er niets. */
  .scene{block-size:auto}
  .scene-plak{position:static;block-size:auto;padding-block:var(--ev-space-7)}
  .scene-stapel{inline-size:100%;aspect-ratio:auto;border:0;box-shadow:none;overflow:visible;
    display:grid;grid-template-columns:1fr;gap:var(--ev-space-4)}
  .lv-plaat{position:relative;animation:none;opacity:1;transform:none;filter:none;
    border-radius:var(--ev-radius-md);overflow:hidden;border:1px solid var(--ev-color-border-on-dark)}
  .scene-onderschrift{position:static;inline-size:100%;min-block-size:0;text-align:start;
    display:grid;gap:var(--ev-space-5);margin-block-start:var(--ev-space-5)}
  .lv-plaat-tekst{position:static;animation:none;opacity:1;transform:none;filter:none}
}
@media (max-width:600px){
  .werkraster{grid-template-columns:1fr;gap:var(--ev-space-4)}
  .werkraster .doek,.werkraster .doek:nth-child(7n+4),.werkraster .doek:nth-child(7n+5),
  .werkraster .doek:nth-child(7n+6),.werkraster .doek:nth-child(7n+7){grid-column:span 1;aspect-ratio:3/2}
}

/* ── module: tijdlijn ── */
/* ============================================================
   TIJDLIJN — de beleving van start tot nazorg.
   Dit is het onderscheidende deel van de site: niet wat Esther
   maakt, maar hoe het is om het te laten maken. De vorm is
   daarom een reis met voortgang, geen lijst met vinkjes.
   ============================================================ */
.lv-tijdlijn{position:relative}

.tl-baan{
  position:absolute;inset-block:0;inset-inline-start:calc(var(--ev-space-8) - 1px);
  inline-size:2px;
  background:color-mix(in srgb, var(--ev-color-brand-accent) 14%, transparent);
}
.lv-vulling{inline-size:100%;block-size:100%;background:var(--ev-signature-gradient)}

.tl-stap{
  position:relative;
  display:grid;grid-template-columns:var(--ev-space-9) minmax(0,1fr);
  gap:var(--ev-space-6);
  padding-block:var(--ev-space-8);
}
.tl-stap:first-child{padding-block-start:0}
.tl-stap:last-child{padding-block-end:0}

.tl-punt{
  position:relative;z-index:2;
  inline-size:var(--ev-space-8);block-size:var(--ev-space-8);
  border-radius:var(--ev-radius-pill);
  display:grid;place-items:center;
  background:var(--ev-color-surface-dark);
  border:1px solid color-mix(in srgb, var(--ev-color-brand-accent) 40%, transparent);
  font-family:var(--ev-font-head);font-weight:var(--ev-weight-bold);
  color:var(--ev-color-brand-accent);
  font-variant-numeric:tabular-nums;
  transition:background var(--ev-dur-base) var(--ev-ease),color var(--ev-dur-base) var(--ev-ease);
}
.tl-stap.zichtbaar .tl-punt{background:var(--ev-color-brand-accent);color:var(--ev-color-surface-dark)}

.tl-inhoud h3{font-size:var(--ev-text-2xl);margin-bottom:var(--ev-space-3)}
.tl-fase{
  display:block;font-size:var(--ev-text-xs);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ev-color-ink-on-dark-muted);margin-bottom:var(--ev-space-2);
  font-weight:var(--ev-weight-bold);
}
.tl-inhoud p{color:var(--ev-color-ink-on-dark-soft);max-width:56ch}
.tl-detail{
  margin-block-start:var(--ev-space-5);
  display:flex;flex-wrap:wrap;gap:var(--ev-space-3);
}
.tl-beeld{
  margin-block-start:var(--ev-space-5);
  border-radius:var(--ev-radius-md);overflow:hidden;
  border:1px solid var(--ev-color-border-on-dark);
  aspect-ratio:16/9;max-inline-size:34rem;
}
.tl-beeld img{inline-size:100%;block-size:100%;object-fit:cover}

/* De nazorg-stap krijgt zichtbaar meer gewicht: dat is de belofte
   die de meeste concurrenten helemaal niet doen. */
.tl-stap-nazorg .tl-inhoud{
  background:var(--ev-color-surface-dark-2);
  border:1px solid color-mix(in srgb, var(--ev-color-brand-accent) 24%, transparent);
  border-radius:var(--ev-radius-lg);
  padding:var(--ev-space-6);
}

@media (max-width:720px){
  .tl-baan{inset-inline-start:calc(var(--ev-space-6) - 1px)}
  .tl-stap{grid-template-columns:var(--ev-space-7) minmax(0,1fr);gap:var(--ev-space-4);padding-block:var(--ev-space-7)}
  .tl-punt{inline-size:var(--ev-space-7);block-size:var(--ev-space-7);font-size:var(--ev-text-sm)}
  .tl-inhoud h3{font-size:var(--ev-text-xl)}
}

/* ── module: pakketten ── */
/* ============================================================
   PAKKETTEN — bento in plaats van drie gelijke kolommen.
   Eén cel draagt beeld en gewicht; de rest staat ernaast.
   ============================================================ */
/* Drie cellen op één rij, de uitgelichte breder. Eerdere vorm was
   `grid-row: span 2` op de featured cel: dan is rij 2 in de andere twee
   kolommen leeg en staat de uitgelichte cel als enige twee rijen hoog
   naast twee halve. Onbedoeld, en op een screenshot pas te zien. */
.bento{
  display:grid;
  grid-template-columns:1.35fr 1fr 1fr;
  gap:var(--ev-space-5);
  align-items:stretch;
}
.cel{display:flex;flex-direction:column;gap:var(--ev-space-4);padding:var(--ev-space-7)}
.cel-feature{
  position:relative;isolation:isolate;overflow:hidden;
  padding-block-start:0;
  border-color:color-mix(in srgb, var(--ev-color-brand-accent) 34%, transparent);
}
/* Het beeld krijgt een eigen band bovenin in plaats van als achtergrond
   onder de tekst te liggen. Als achtergrond deed het niets: het werd voor
   85% weggegradeerd en concurreerde op de rest met de kop. */
.cel-feature-beeld{
  position:relative;
  margin-inline:calc(-1 * var(--ev-space-7));
  block-size:11rem;overflow:hidden;
}
.cel-feature-beeld img{inline-size:100%;block-size:100%;object-fit:cover;object-position:50% 34%}
.cel-feature-beeld::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(
    to bottom,
    color-mix(in srgb, var(--ev-color-surface-dark) 18%, transparent) 0%,
    color-mix(in srgb, var(--ev-color-surface-dark-2) 62%, transparent) 58%,
    var(--ev-color-surface-dark-2) 100%);
}
.cel-breed{grid-column:span 2}

.pakketkop{display:flex;align-items:baseline;justify-content:space-between;gap:var(--ev-space-4);flex-wrap:wrap}
.pakketkop .prijs{text-align:end}
.pakketkop h3{font-size:var(--ev-text-2xl);margin:0}
.prijs{
  font-family:var(--ev-font-head);font-size:var(--ev-text-3xl);
  font-weight:var(--ev-weight-bold);color:var(--ev-color-brand-accent);
  line-height:1;font-variant-numeric:tabular-nums;
}
.prijs small{display:block;font-family:var(--ev-font-body);font-size:var(--ev-text-xs);
  font-weight:var(--ev-weight-medium);color:var(--ev-color-ink-on-dark-muted);
  letter-spacing:.06em;margin-block-start:var(--ev-space-2)}

.pakketlijst{display:grid;gap:var(--ev-space-3);margin-block:var(--ev-space-2) auto}
.pakketlijst li{
  display:grid;grid-template-columns:var(--ev-space-5) minmax(0,1fr);
  gap:var(--ev-space-3);align-items:start;
  color:var(--ev-color-ink-on-dark-soft);font-size:var(--ev-text-sm);
}
.pakketlijst svg{inline-size:14px;block-size:14px;color:var(--ev-color-brand-accent);margin-block-start:6px}
.pakketlijst li em{font-style:normal;color:var(--ev-color-ink-on-dark)}

/* Het etiket staat IN de stroom, niet erboven. In de absolute vorm lag
   het over de prijs heen — precies over het getal waarop iemand kiest. */
.badge{align-self:flex-start;margin-block-start:calc(-1 * var(--ev-space-4));z-index:3}

/* Vergelijkingstabel — voor wie doorleest in plaats van kiest. */
.vergelijk{inline-size:100%;border-collapse:collapse;font-size:var(--ev-text-sm)}
.vergelijk caption{text-align:start;color:var(--ev-color-ink-on-dark-muted);font-size:var(--ev-text-xs);padding-block-end:var(--ev-space-4)}
.vergelijk th,.vergelijk td{
  padding:var(--ev-space-4);text-align:start;
  border-bottom:1px solid var(--ev-color-border-on-dark);
  vertical-align:top;
}
.vergelijk thead th{
  color:var(--ev-color-brand-accent);font-family:var(--ev-font-head);
  font-size:var(--ev-text-lg);font-weight:var(--ev-weight-semibold);
}
.vergelijk tbody th{color:var(--ev-color-ink-on-dark);font-weight:var(--ev-weight-semibold)}
.vergelijk td{color:var(--ev-color-ink-on-dark-soft)}
.vergelijk-wikkel{overflow-x:auto}

@media (max-width:1080px){
  .bento{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cel-feature{grid-column:span 2}
  .cel-breed{grid-column:span 2}
}
@media (max-width:720px){
  .bento{grid-template-columns:1fr}
  .cel-feature,.cel-breed{grid-column:span 1}
  .cel{padding:var(--ev-space-6)}
}

/* ── module: faq ── */
/* ============================================================
   FAQ — <details>, geen script. Werkt zonder JavaScript en is
   toegankelijk zonder ARIA-constructie.
   ============================================================ */
.faq{display:grid;gap:var(--ev-space-3)}
.faq details{
  background:var(--ev-color-surface-dark-2);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-md);
  transition:border-color var(--ev-dur-fast) var(--ev-ease);
}
.faq details[open]{border-color:color-mix(in srgb, var(--ev-color-brand-accent) 36%, transparent)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:var(--ev-space-5);
  padding:var(--ev-space-5) var(--ev-space-6);
  cursor:pointer;list-style:none;
  font-family:var(--ev-font-head);font-size:var(--ev-text-lg);
  color:var(--ev-color-ink-on-dark);
  min-block-size:44px;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";flex:none;inline-size:12px;block-size:12px;
  border-inline-end:2px solid var(--ev-color-brand-accent);
  border-block-end:2px solid var(--ev-color-brand-accent);
  rotate:45deg;
  transition:rotate var(--ev-dur-fast) var(--ev-ease);
}
.faq details[open] summary::after{rotate:225deg}
.faq .antwoord{padding:0 var(--ev-space-6) var(--ev-space-6);color:var(--ev-color-ink-on-dark-soft);max-width:68ch}
.faq .antwoord p + p{margin-block-start:var(--ev-space-4)}
.vlak-licht .faq details{background:color-mix(in srgb, var(--ev-color-wit) 55%, transparent);border-color:var(--ev-color-border-on-light)}
.vlak-licht .faq summary{color:var(--ev-color-ink-on-light)}
.vlak-licht .faq summary::after{border-color:var(--ev-color-brand-action)}
.vlak-licht .faq .antwoord{color:var(--ev-color-ink-on-light-soft)}
@media (prefers-reduced-motion: reduce){.faq summary::after{transition:none}}

/* ── module: formulier ── */
/* ============================================================
   FORMULIER — contact. Alle veldstates, plus de vertrouwens-
   zijkolom: wie het formulier invult wil weten wat er dan
   gebeurt.
   ============================================================ */
/* ── Statusmeldingen na het verzenden ──────────────────────────────────────
   Verborgen tot het fragment in de URL ernaar wijst (`contact.html#status-…`).
   `verstuur.php` stuurt de bezoeker terug met zo'n fragment.

   `:target` en niet JavaScript, om twee redenen. De ruststand van dit ontwerp is
   bewust scriptloos, en een melding die alleen met JS verschijnt is onzichtbaar
   voor een deel van de bezoekers — precies op het moment dat ze willen weten of
   hun bericht is aangekomen. En een fragment wordt nooit op de pagina geëchood,
   dus er is geen enkele weg waarlangs bezoekersinvoer de HTML bereikt. Met een
   `?status=`-parameter was dat er wél: een aanvaller linkt rechtstreeks naar
   `contact.html?status=<img src=x onerror=…>` en komt nooit langs het formulier. */
.melding{
  display:none;
  gap:var(--ev-space-4);
  align-items:flex-start;
  padding:var(--ev-space-5) var(--ev-space-6);
  margin-block-end:var(--ev-space-7);
  border-radius:var(--ev-radius-md);
  border:1px solid var(--ev-color-border-on-dark);
  background:var(--ev-color-surface-dark-2);
  /* Zodat de vaste header de melding niet afdekt bij het springen. */
  scroll-margin-block-start:calc(var(--ev-layout-header) + var(--ev-space-6));
}
.melding:target{display:flex}
.melding strong{display:block;margin-block-end:var(--ev-space-2)}
.melding p{margin:0;font-size:var(--ev-text-sm);color:var(--ev-color-ink-on-dark-soft)}
.melding svg{flex:none;margin-block-start:2px}
.melding-goed svg{color:var(--ev-color-brand-accent-bright)}
.melding-fout svg{color:var(--ev-color-error)}

.form-grid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.75fr);gap:var(--ev-space-8)}
.veldrij{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ev-space-5)}
.veld{display:grid;gap:var(--ev-space-2);margin-block-end:var(--ev-space-5)}
.veld label{font-size:var(--ev-text-sm);font-weight:var(--ev-weight-semibold);color:var(--ev-color-ink-on-dark)}
.veld .hint{font-size:var(--ev-text-xs);color:var(--ev-color-ink-on-dark-muted)}
.veld input,.veld select,.veld textarea{
  font-family:var(--ev-font-body);font-size:var(--ev-text-base);
  color:var(--ev-color-ink-on-dark);
  background:var(--ev-color-surface-dark);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-sm);
  padding:var(--ev-space-4);
  min-block-size:48px;
  inline-size:100%;
  transition:border-color var(--ev-dur-fast) var(--ev-ease),background var(--ev-dur-fast) var(--ev-ease);
}
.veld textarea{min-block-size:9rem;resize:vertical}
.veld input::placeholder,.veld textarea::placeholder{color:var(--ev-color-ink-on-dark-muted)}
.veld input:hover,.veld select:hover,.veld textarea:hover{border-color:color-mix(in srgb, var(--ev-color-brand-accent) 40%, transparent)}
.veld input:focus-visible,.veld select:focus-visible,.veld textarea:focus-visible{
  border-color:var(--ev-color-focus);
  background:var(--ev-color-surface-dark-2);
}
.veld input:disabled,.veld textarea:disabled{opacity:.5;cursor:not-allowed}
.veld .fout{color:var(--ev-color-error);font-size:var(--ev-text-sm);display:flex;align-items:center;gap:var(--ev-space-2)}
.veld[data-staat="fout"] input,.veld[data-staat="fout"] textarea{border-color:var(--ev-color-error)}

.keuzerij{display:flex;flex-wrap:wrap;gap:var(--ev-space-3)}
.keuze{position:relative}
.keuze input{position:absolute;opacity:0;inline-size:0;block-size:0}
.keuze span{
  display:inline-flex;align-items:center;min-block-size:44px;
  padding:var(--ev-space-3) var(--ev-space-5);
  border:1px solid var(--ev-color-border-on-dark);
  border-radius:var(--ev-radius-pill);
  color:var(--ev-color-ink-on-dark-soft);font-size:var(--ev-text-sm);
  cursor:pointer;
  transition:border-color var(--ev-dur-fast) var(--ev-ease),color var(--ev-dur-fast) var(--ev-ease),background var(--ev-dur-fast) var(--ev-ease);
}
.keuze input:checked + span{
  background:color-mix(in srgb, var(--ev-color-brand-accent) 16%, transparent);
  border-color:var(--ev-color-brand-accent);
  color:var(--ev-color-brand-accent);
}
.keuze input:focus-visible + span{outline:2px solid var(--ev-color-focus);outline-offset:3px}

.akkoord{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--ev-space-3);align-items:start;font-size:var(--ev-text-sm);color:var(--ev-color-ink-on-dark-soft)}
.akkoord input{inline-size:24px;block-size:24px;min-block-size:0;margin-block-start:3px;accent-color:var(--ev-color-brand-accent)}

/* Wat er gebeurt nadat je op verzenden drukt — de belangrijkste
   twijfel wegnemen op de plek waar hij ontstaat. */
.vertrouwen{display:grid;gap:var(--ev-space-5);align-content:start}
.vertrouwen ol{display:grid;gap:var(--ev-space-4);counter-reset:v}
.vertrouwen ol li{
  display:grid;grid-template-columns:var(--ev-space-6) minmax(0,1fr);gap:var(--ev-space-4);
  color:var(--ev-color-ink-on-dark-soft);font-size:var(--ev-text-sm);
}
.vertrouwen ol li::before{
  counter-increment:v;content:counter(v);
  inline-size:var(--ev-space-6);block-size:var(--ev-space-6);
  display:grid;place-items:center;border-radius:var(--ev-radius-pill);
  background:color-mix(in srgb, var(--ev-color-brand-accent) 16%, transparent);
  color:var(--ev-color-brand-accent);font-size:var(--ev-text-xs);font-weight:var(--ev-weight-bold);
}
.direct-contact{display:grid;gap:var(--ev-space-3)}
.direct-contact a{
  display:flex;align-items:center;gap:var(--ev-space-4);min-block-size:48px;
  color:var(--ev-color-ink-on-dark);text-decoration:none;font-weight:var(--ev-weight-semibold);
}
.direct-contact a:hover{color:var(--ev-color-brand-accent)}
.direct-contact svg{inline-size:18px;block-size:18px;color:var(--ev-color-brand-accent);flex:none}

@media (max-width:900px){
  .form-grid{grid-template-columns:1fr;gap:var(--ev-space-7)}
  .veldrij{grid-template-columns:1fr;gap:0}
}

/* ── module: footer ── */
/* ============================================================
   FOOTER
   ============================================================ */
.voet{
  background:var(--ev-color-surface-dark-2);
  border-top:1px solid var(--ev-color-border-on-dark);
  padding-block:var(--ev-space-9) var(--ev-space-6);
}
.voet-grid{
  display:grid;grid-template-columns:1.4fr repeat(3,minmax(0,1fr));
  gap:var(--ev-space-8);
}
.voet h3{
  font-family:var(--ev-font-body);font-size:var(--ev-text-xs);
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--ev-color-brand-accent);margin-bottom:var(--ev-space-5);
  font-weight:var(--ev-weight-bold);
}
/* Gemeten op 1440px: de footerlinks waren 19px hoog. Dat is geen inline
   link in een zin maar een lijst met navigatiedoelen, dus de uitzondering
   van WCAG 2.5.8 geldt er niet voor. Met padding halen ze 35px, op mobiel 43. */
.voet ul{display:grid;gap:var(--ev-space-2)}
.voet a{color:var(--ev-color-ink-on-dark-soft);text-decoration:none;font-size:var(--ev-text-sm)}
.voet ul a{display:inline-block;padding-block:var(--ev-space-2)}
@media (max-width:720px){.voet ul a{padding-block:var(--ev-space-3)}}
.voet a:hover{color:var(--ev-color-brand-accent)}
.voet p{color:var(--ev-color-ink-on-dark-soft);font-size:var(--ev-text-sm)}
.voet-slot{
  margin-block-start:var(--ev-space-8);padding-block-start:var(--ev-space-5);
  border-top:1px solid var(--ev-color-border-on-dark);
  display:flex;flex-wrap:wrap;gap:var(--ev-space-4);justify-content:space-between;
  color:var(--ev-color-ink-on-dark-muted);font-size:var(--ev-text-xs);
}
/* De juridische links staan in de slotregel en niet in een eigen kolom: het zijn
   verplichte verwijzingen, geen navigatie. Wie ze zoekt weet waar ze staan; wie
   ze niet zoekt hoeft er niet langs. Wél als aparte groep, zodat ze bij smalle
   schermen bij elkaar blijven in plaats van los tussen de copyright-regel en de
   voorbeeldmelding te vallen. */
.voet-juridisch{display:flex;flex-wrap:wrap;gap:var(--ev-space-4)}
.voet-juridisch a{
  color:var(--ev-color-ink-on-dark-muted);text-decoration:underline;
  text-underline-offset:.25em;text-decoration-thickness:1px;
  transition:color var(--ev-dur-fast) var(--ev-ease);
}
.voet-juridisch a:hover,.voet-juridisch a:focus-visible{
  color:var(--ev-color-ink-on-dark);
}

.sociaal{display:flex;gap:var(--ev-space-3)}
.sociaal a{
  inline-size:44px;block-size:44px;display:grid;place-items:center;
  border:1px solid var(--ev-color-border-on-dark);border-radius:var(--ev-radius-pill);
  color:var(--ev-color-ink-on-dark-soft);
  transition:color var(--ev-dur-fast) var(--ev-ease),border-color var(--ev-dur-fast) var(--ev-ease);
}
.sociaal a:hover{color:var(--ev-color-brand-accent);border-color:var(--ev-color-brand-accent)}
.sociaal svg{inline-size:18px;block-size:18px}

/* Slot-CTA boven de footer: de laatste kans om contact te leggen. */
.slot-cta{position:relative;isolation:isolate;overflow:hidden;text-align:center}
.slot-cta .container{position:relative;z-index:2}
.slot-cta h2{font-size:var(--ev-text-5xl);max-width:22ch;margin-inline:auto;margin-bottom:var(--ev-space-5)}
.slot-cta .lead{margin-inline:auto;margin-bottom:var(--ev-space-7);text-align:center}
.slot-cta .knop-rij{justify-content:center}

@media (max-width:1080px){.voet-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--ev-space-7)}}
@media (max-width:600px){.voet-grid{grid-template-columns:1fr}}
