/* ==========================================================================
   Het Merklokaal, designsysteem
   Kleuren uit de Figma-variabelen (Color Brand), typografie en maten
   gemeten op de live site. Breekpunten één op één overgenomen: 810 en 1200.
   ========================================================================== */

:root {
  /* ---------------------------------------------------------- kleuren */
  /* De negen merkkleuren. Lichtblauw en oranje heetten in Figma nog
     "Voorlopig"; die zijn op 1 okt 2026 definitief verklaard. */
  --ml-zwart: #0f111e;
  --ml-wit: #ffffff;
  --ml-blauw: #025af0;
  --ml-grijs: #efefef;
  --ml-abrikoos: #fddbc2;
  --ml-geel: #fac800;
  --ml-groen: #05aa12;
  --ml-lichtblauw: #7ec7ff;
  --ml-oranje: #ec9000;

  /* Semantisch. Tekst is zwart #0f111e, niet puur zwart: dat is wat de
     live site doet en wat Color Brand/zwart voorschrijft. */
  --ml-ink: var(--ml-zwart);
  --ml-paper: var(--ml-wit);
  /* Welke tekstkleur hoort bij het vlak waarop je staat. Handig voor
     onderdelen die niet de kleur van hun buur moeten volgen maar die
     van het vlak, zoals de getekende streep onder een gekleurde kop. */
  --ml-op-vlak: var(--ml-zwart);
  --ml-accent: var(--ml-blauw);

  /* ------------------------------------------------------- typografie */
  /* Inter Tight voor koppen, Inter voor tekst. Beide vrij via Google
     Fonts, dus geen licentiekwestie. */
  --ml-font-kop: "Inter Tight", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --ml-font-tekst: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Gemeten op de live site op 390, 810, 1000, 1200, 1512, 1920 en 2200.
     De displaymaat springt op 810 van 62 naar 120 en blijft daarna
     gelijk; hij schaalt dus niet vloeiend mee. Vanaf H2 is de grootte
     overal gelijk en verandert alleen de regelafstand. */
  /* De schaal komt uit de fase 2-PDF, uitgelezen op puntgrootte en niet
     van een afbeelding geschat. De pagina daarin is 2268 breed voor een
     ontwerp van 1512, dus alles is door 1,5 gedeeld.

     Fase 2 heeft de tekst op een paar plekken bewust kleiner gemaakt om
     de pagina leesbaarder te krijgen. Dat zit niet in de lopende tekst,
     die blijft 42, maar in de koppen en de opsommingen:

       "Waarmee we je kunnen helpen"   live 80  ->  fase 2 42
       de kleine items met icoon       live 30  ->  fase 2 20
       het label boven een case        live 18  ->  fase 2 12

     Twee dingen gingen juist omhoog: de tekst rechtsonder in de kop van
     20 naar 22, en de dienstenlijst van 16 naar 20.

     De namen zijn maten, geen kopniveaus. Dat moet wel, want "Cases" en
     "Waarmee we je kunnen helpen" zijn allebei een H2 en staan op 80 en
     op 42. */
  /* Mobiel eerst. Opgemeten op de live site op 390 breed: de paginakop
     staat daar op 62/59 en álles wat op desktop 80 is, staat op 42. De
     maten hieronder zijn dus de telefoonmaten; de mediaregel verderop
     zet ze op de desktopmaat.

     Hier zat de fout die koppen op een telefoon onleesbaar maakte: kop-xl
     stond vast op 80, ook op 390 breed. Een artikeltitel, "Meer cases" en
     "Het prikbord" vulden daarmee het halve scherm. */
  --ml-display: 2.625rem;               /*  42  paginakop; vanaf 810: 120 */
  --ml-kop-xl: 1.875rem;                /*  30  Cases, Het prikbord; vanaf 810: 80 */
  --ml-kop-l: 1.875rem;                 /*  30  de belofte; vanaf 810: 64 */
  --ml-kop-m: 1.875rem;                 /*  30  sectiekoppen en grote tekst; vanaf 810: 42 */
  --ml-kop-s: 1.5rem;                   /*  24  balken, quotes, tussenkoppen; vanaf 810: 30 */
  --ml-lead: 1.375rem;                  /*  22  de tekst onder de kop */
  --ml-tekst: 1.25rem;                  /*  20  lopende tekst */
  --ml-ui: 1.125rem;                    /*  18  menu, knoppen, footer */
  --ml-label: 0.875rem;                 /*  14 */
  --ml-micro: 0.75rem;                  /*  12  label boven een case */

  /* Regelafstanden, uit de regelafstand in de PDF gedeeld door de maat:
     120/114, 64/64, 42/48, 30/32, 22/29, 20/26. */
  --ml-lh-display: 0.95;
  --ml-lh-kop: 1.1;    /* op telefoon 30/33; vanaf 810 wordt dit 42/48 */
  --ml-lh-kop-s: 1.2;  /* op telefoon 24/29; vanaf 810 wordt dit 30/32 */
  /* Lopende tekst op 1.5, op verzoek van design (6 oktober 2026). Dat
     wijkt bewust af van de live site, die 20/26 aanhoudt, oftewel 1.3.
     Deze variabele geldt voor alle lopende tekst; koppen houden hun
     eigen, strakkere regelafstanden. */
  --ml-lh-tekst: 1.5;

  /* Inter staat op de live site overal 0,3 pixel strakker. Inter Tight
     krijgt géén tracking: dat zou de grote koppen dichtknijpen. */
  --ml-ls-tekst: -0.3px;

  /* ------------------------------------------------------------ maten */
  /* Zijmarge 20px, inhoud maximaal 1460 breed. Op het ontwerpframe van
     1512 blijft er dan 26px aan weerszijden over. */
  --ml-marge: 20px;       /* vanaf 1200 wordt dit 70, zie hieronder */
  --ml-max: 1460px;
  --ml-sectie-y: 50px;
  --ml-radius: 32px;      /* knoppen zijn pills */
  --ml-radius-vlak: 16px;

  --ml-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ml-duur: 0.4s;
}

/* Vanaf tablet meer lucht tussen de secties, en vanaf 1200 een bredere
   zijmarge. Gemeten: op 390, 810 en 1000 staat de tekst op 20 van de
   rand, op 1200 en 1512 op 70, en vanaf 1600 loopt de inhoud niet verder
   dan 1460 breed. Daarboven schuift de marge dus vanzelf mee. */
@media (min-width: 810px)  { :root {
  --ml-sectie-y: 70px;
  --ml-kop-l: 4rem;
  --ml-kop-m: 2.625rem; --ml-lh-kop: 1.14;
  --ml-kop-s: 1.875rem; --ml-lh-kop-s: 1.07;
} }
@media (min-width: 1200px) { :root { --ml-sectie-y: 100px; --ml-marge: 70px; } }

/* ------------------------------------------------------------- basis */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ml-paper);
  color: var(--ml-ink);
  font-family: var(--ml-font-tekst);
  font-size: var(--ml-tekst);
  line-height: var(--ml-lh-tekst);
  letter-spacing: var(--ml-ls-tekst);
  -webkit-font-smoothing: antialiased;
}

/* Plate laadt zelf application.css (normalize). Het enige dat daaruit
   lekt is font-family: sans-serif op formulierelementen. */
button, input, select, textarea { font: inherit; color: inherit; }

img, svg, video { max-width: 100%; height: auto; display: block; }

a { color: inherit; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--ml-font-kop);
  font-weight: 700;
  line-height: var(--ml-lh-kop);
  letter-spacing: normal;
  margin: 0;
  text-wrap: balance;
}
/* De grote kop staat een graad lichter dan de rest: SemiBold tegenover
   Bold. Op 120 pixels zou Bold te zwaar uitpakken. */
h1 { font-weight: 600; }

h1 { font-size: var(--ml-display); }
h2 { font-size: var(--ml-kop-m); }
h3 { font-size: var(--ml-kop-s); line-height: var(--ml-lh-kop-s); }
h4 { font-size: var(--ml-kop-s); line-height: var(--ml-lh-kop-s); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

/* De hele grote kop uit de header, los van de koprangorde. */
.ml-display {
  font-family: var(--ml-font-kop);
  font-size: var(--ml-display);
  line-height: var(--ml-lh-display);
  letter-spacing: normal;
  font-weight: 600;
  margin: 0;
  /* Vangnet voor een woord dat zelfs dan niet past: liever een nette
     afbreking met een koppelteken dan een harde knip in het woord. */
  hyphens: auto;
  overflow-wrap: break-word;
}

/* De grote tekstmaat: Inter Tight Bold op 42, dezelfde maat als een H2.
   Op de live site staat de lopende tekst in de bovenste blokken in deze
   maat, niet in de leesmaat van 18. Dat bepaalt sterk hoe de pagina
   oogt, dus het is een eigen stijl en geen uitzondering per sectie. */
.ml-grote-tekst {
  font-family: var(--ml-font-kop);
  font-size: var(--ml-kop-m);
  line-height: var(--ml-lh-kop);
  letter-spacing: normal;
  font-weight: 700;
}
.ml-grote-tekst p { margin: 0 0 0.5em; }

/* De tussenmaat onder de koppen: Inter 20/26. */
.ml-lead { font-size: var(--ml-lead); line-height: var(--ml-lh-tekst); font-weight: 500; }

/* --------------------------------------------------------- opmaakhulp */

.ml-container {
  width: 100%;
  max-width: calc(var(--ml-max) + 2 * var(--ml-marge));
  margin-inline: auto;
  padding-inline: var(--ml-marge);
}

/* De displaymaat springt op 810 in één stap omhoog. */
@media (min-width: 810px) { :root { --ml-display: 7.5rem; --ml-kop-xl: 5rem; } }

.ml-sectie { padding-block: var(--ml-sectie-y); }

/* Vlakken in een merkkleur. Alle merkkleuren zijn licht genoeg voor
   zwarte tekst, behalve blauw: daar gaat de tekst wit. */
/* Elke vlakklasse zet zijn kleur ook in --ml-vlak-kleur. Een getekende
   rand haalt zijn vulling daaruit, zodat één klasse het vlak én de
   vulling van de bobbellijn bepaalt. */
/* Een licht vlak zet de tekstkleur expliciet op zwart. Zonder dat erft
   een licht kaartje binnen een donkere baan de witte tekst van die baan,
   en dat gebeurde: abrikoos op groen werd wit op abrikoos. */
/* Het hidden-attribuut moet altijd winnen.

   De browser zet er `display: none` op, maar dat is een regel met de
   laagste voorrang. Elke eigen regel die een element op flex of grid zet,
   wint daarvan. Dat ging twee keer mis: een weggefilterde kaart in een
   overzicht bleef staan, en de pijlen van de quotecarrousel bleven
   zichtbaar terwijl er maar één quote was en het script ze netjes op
   hidden had gezet.

   Eén regel met !important hoort hier wél: hidden betekent weg, zonder
   uitzondering. */
[hidden] { display: none !important; }

.ml-vlak--wit        { --ml-vlak-kleur: var(--ml-wit);        background: var(--ml-vlak-kleur); color: var(--ml-zwart); --ml-op-vlak: var(--ml-zwart); }
.ml-vlak--grijs      { --ml-vlak-kleur: var(--ml-grijs);      background: var(--ml-vlak-kleur); color: var(--ml-zwart); --ml-op-vlak: var(--ml-zwart); }
.ml-vlak--abrikoos   { --ml-vlak-kleur: var(--ml-abrikoos);   background: var(--ml-vlak-kleur); color: var(--ml-zwart); --ml-op-vlak: var(--ml-zwart); }
.ml-vlak--geel       { --ml-vlak-kleur: var(--ml-geel);       background: var(--ml-vlak-kleur); color: var(--ml-zwart); --ml-op-vlak: var(--ml-zwart); }
.ml-vlak--groen      { --ml-vlak-kleur: var(--ml-groen);      background: var(--ml-vlak-kleur); color: var(--ml-wit); --ml-op-vlak: var(--ml-wit); }
.ml-vlak--lichtblauw { --ml-vlak-kleur: var(--ml-lichtblauw); background: var(--ml-vlak-kleur); color: var(--ml-zwart); --ml-op-vlak: var(--ml-zwart); }
.ml-vlak--oranje     { --ml-vlak-kleur: var(--ml-oranje);     background: var(--ml-vlak-kleur); color: var(--ml-zwart); --ml-op-vlak: var(--ml-zwart); }
.ml-vlak--blauw      { --ml-vlak-kleur: var(--ml-blauw);      background: var(--ml-vlak-kleur); color: var(--ml-wit); --ml-op-vlak: var(--ml-wit); }
.ml-vlak--zwart      { --ml-vlak-kleur: var(--ml-zwart);      background: var(--ml-vlak-kleur); color: var(--ml-wit); --ml-op-vlak: var(--ml-wit); }

/* ------------------------------------------------------------ knoppen */

.ml-knop {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 59px;
  padding: 18px 32px;
  border: 0;
  border-radius: var(--ml-radius);
  background: var(--ml-blauw);
  color: var(--ml-wit);
  font-size: var(--ml-ui);
  font-weight: 700;
  line-height: var(--ml-lh-tekst);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--ml-duur) var(--ml-ease),
              transform var(--ml-duur) var(--ml-ease);
}
.ml-knop:hover { background: var(--ml-zwart); transform: translateY(-2px); }

.ml-knop--licht { background: var(--ml-wit); color: var(--ml-blauw); }
.ml-knop--licht:hover { background: var(--ml-grijs); color: var(--ml-zwart); }

.ml-knop--rand {
  background: transparent;
  color: var(--ml-ink);
  box-shadow: inset 0 0 0 1px currentColor;
}
.ml-knop--rand:hover { background: var(--ml-ink); color: var(--ml-wit); }

/* ------------------------------------------------- toegankelijkheid */

:focus-visible { outline: 3px solid var(--ml-blauw); outline-offset: 2px; }

.ml-visueel-verborgen {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ========================================================== navigatie */

.ml-skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  padding: 1rem 1.5rem; background: var(--ml-zwart); color: var(--ml-wit);
}
.ml-skip:focus { left: 0; }

/* De balk heeft op de live site een eigen vlak in dezelfde kleur als de
   kop eronder: op de home blauw, op de andere pagina's wit. Daarom is de
   kleur een keuze in het CMS en niet iets dat over de kop heen hangt.
   Gemeten hoogte 171, met het logo op 40 van boven. */
/* Geen eigen achtergrond: die komt van de ml-vlak-klasse die het
   template meegeeft. Zou hij hier staan, dan wint hij van die klasse,
   want hij staat verderop in dit bestand bij gelijke zwaarte. */
.ml-nav { position: relative; z-index: 50; }
.ml-nav__balk {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1.5rem; min-height: 171px; padding-block: 40px 5px;
}
/* Menu en knop staan niet op het midden van het logo maar op het midden
   van de knop zelf, zoals op de live site: 59 hoog, bovenkant op 40. */
.ml-nav__menu, .ml-nav__schakelaar { align-self: flex-start; }

@media (max-width: 809.98px) {
  .ml-nav__balk { min-height: 124px; padding-block: 20px 5px; }
}

/* Het beeldmerk, 110 bij 126 op de live site. Het volgt currentColor,
   dus wit op het blauwe vlak en zwart op wit, uit hetzelfde bestand. */
.ml-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.ml-logo { display: block; flex: none; text-decoration: none; align-self: flex-start; }
.ml-logo__mark { width: auto; height: 126px; color: inherit; fill: currentColor; }

@media (max-width: 809.98px) { .ml-logo__mark { height: 84px; } }

/* De overlaytekst over de video krimpt mee, net als de kop. */
.ml-video__overlay { font-size: var(--ml-display); }

.ml-nav__menu { display: none; align-items: center; gap: 2rem; }
.ml-nav__lijst {
  display: flex; align-items: center; gap: 2rem;
  list-style: none; margin: 0; padding: 0;
}
.ml-nav__lijst a {
  text-decoration: none; font-size: var(--ml-ui); font-weight: 700;
  padding-block: 0.25rem;
  border-bottom: 2px solid transparent;
  transition: border-color var(--ml-duur) var(--ml-ease);
}
.ml-nav__lijst a:hover,
.ml-nav__lijst a[aria-current="page"] { border-bottom-color: var(--ml-blauw); }

.ml-knop--donker { background: var(--ml-zwart); color: var(--ml-wit); }
.ml-knop--donker:hover { background: var(--ml-blauw); }

.ml-nav__schakelaar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  background: none; border: 0; cursor: pointer; color: inherit;
}

@media (min-width: 1200px) {
  .ml-nav__menu { display: flex; }
  .ml-nav__schakelaar { display: none; }
}

/* Het uitklapmenu schuift open. Een hoogte van auto is niet te animeren,
   een grid-rij van 0fr naar 1fr wel. minmax(0, …) is daarbij nodig, want
   een fr-track houdt anders een ondergrens ter grootte van de padding. */
.ml-nav__paneel {
  display: grid;
  grid-template-rows: minmax(0, 0fr);
  visibility: hidden;
  border-top: 1px solid transparent;
  background: var(--ml-paper);
  /* Eigen tekstkleur, want het paneel heeft een eigen achtergrond. Op de
     home staat de balk erboven op blauw en die zet color: wit; zonder
     deze regel erft het paneel dat en staan er witte letters op een wit
     vlak. Op de andere pagina's viel het niet op, want daar is de balk
     zelf al wit. */
  color: var(--ml-zwart);
  transition: grid-template-rows 0.34s var(--ml-ease),
              border-color 0.34s var(--ml-ease),
              visibility 0s linear 0.34s;
}
.ml-nav__paneel > * { overflow: hidden; min-height: 0; padding-block: 1rem 2rem; }
.ml-nav__paneel[data-open="true"] {
  grid-template-rows: minmax(0, 1fr);
  visibility: visible;
  border-top-color: var(--ml-grijs);
  transition: grid-template-rows 0.34s var(--ml-ease),
              border-color 0.34s var(--ml-ease), visibility 0s;
}
.ml-nav__paneel ul { list-style: none; margin: 0; padding: 0; }
.ml-nav__paneel li + li { border-top: 1px solid var(--ml-grijs); }
.ml-nav__paneel a {
  display: block; padding: 0.9rem 0;
  font-family: var(--ml-font-kop); font-size: var(--ml-kop-s);
  font-weight: 600; text-decoration: none;
  opacity: 0; transform: translateY(-8px);
  transition: opacity 0.3s var(--ml-ease), transform 0.3s var(--ml-ease);
}
.ml-nav__paneel[data-open="true"] a { opacity: 1; transform: none; }
.ml-nav__paneel[data-open="true"] li:nth-child(1) a { transition-delay: 0.08s; }
.ml-nav__paneel[data-open="true"] li:nth-child(2) a { transition-delay: 0.12s; }
.ml-nav__paneel[data-open="true"] li:nth-child(3) a { transition-delay: 0.16s; }
.ml-nav__paneel[data-open="true"] li:nth-child(4) a { transition-delay: 0.20s; }
.ml-nav__paneel[data-open="true"] li:nth-child(n+5) a { transition-delay: 0.24s; }

/* Het icoon draait naar een kruisje. Elke streep draait om zijn eigen
   midden; met één gedeeld draaipunt zwaaien de buitenste strepen naar
   buiten en komt het kruisje scheef te staan. Het vak is vierkant omdat
   een streep van 24 schuin ook 24 hoog wordt. */
.ml-nav__streep { transform-box: view-box; transition: transform 0.32s var(--ml-ease), opacity 0.18s var(--ml-ease); }
.ml-nav__streep--1 { transform-origin: 12px 5px; }
.ml-nav__streep--2 { transform-origin: 12px 12px; }
.ml-nav__streep--3 { transform-origin: 12px 19px; }
[aria-expanded="true"] .ml-nav__streep--1 { transform: translateY(7px) rotate(45deg); }
[aria-expanded="true"] .ml-nav__streep--2 { opacity: 0; transform: scaleX(0.1); }
[aria-expanded="true"] .ml-nav__streep--3 { transform: translateY(-7px) rotate(-45deg); }

/* ============================================================= footer */
/* Gemeten in fase 2: kop op 70 in twee regels van 120, rechterkolom op
   1117, onderste regel helemaal onderaan het vlak. */

.ml-footer { padding-block: 100px 48px; }
.ml-footer__inner {
  display: grid;
  gap: 64px 48px;
  grid-template-columns: 1fr;
  grid-template-areas: "links" "rechts" "onder";
}
@media (min-width: 960px) {
  .ml-footer__inner {
    grid-template-columns: minmax(0, 1047fr) 325fr;   /* 70..1117 en 1117..1442 */
    grid-template-areas: "links rechts" "onder onder";
  }
}
.ml-footer__links  { grid-area: links; }
.ml-footer__rechts { grid-area: rechts; display: grid; gap: 32px; align-content: start; }
.ml-footer__onder  { grid-area: onder; }

.ml-footer__kop {
  position: relative;
  /* Genoeg ruimte voor de streep eronder plus lucht tot het contactblok:
     64 erboven, 48 voor de streep zelf en 56 eronder. */
  margin: 0 0 168px;
  font-family: var(--ml-font-kop); font-weight: 600;
  font-size: var(--ml-display); line-height: var(--ml-lh-display);
  letter-spacing: normal;
  max-width: 11ch;
}
/* De getekende streep onder de kop. Dit is de echte vorm uit Figma,
   766 bij 44, en niet het staartje van het logo dat ik er eerst voor
   gebruikte; dat is een ander teken en werd bij het oprekken ook nog
   plat getrokken.

   De verhouding blijft nu kloppen: de breedte volgt de kop en de hoogte
   volgt daaruit via aspect-ratio. Hij ligt als masker over de
   tekstkleur, dus hij kleurt mee met de kop. */
.ml-footer__streep {
  /* Onder de kop, niet eroverheen. De streep is 48 hoog bij een kop van
     831 breed, dus hij moet onder de tekst beginnen en niet eronder
     eindigen; met bottom als anker liep hij over de laatste regel heen. */
  /* De regelhoogte van de kop is 114 bij een korps van 120, dus de
     regelbox snijdt onder de staarten van de letters door. Meten vanaf
     die box geeft daardoor minder lucht dan je ziet. Vandaar een ruime
     maat: een halve regel onder de kop. */
  position: absolute; left: 0; top: calc(100% + 64px);
  display: block;
  width: 100%;
  aspect-ratio: 766 / 44;
  /* Niet currentColor: de kop is abrikoos, de streep is in het ontwerp
     wit. Hij volgt dus de tekstkleur van het vlak en niet die van de
     kop waar hij in hangt. */
  background: var(--ml-op-vlak, currentColor);
  -webkit-mask: url("../img/streep.svg") left top / 100% 100% no-repeat;
          mask: url("../img/streep.svg") left top / 100% 100% no-repeat;
}

.ml-footer__contact { display: flex; align-items: center; gap: 16px; }
.ml-footer__portret { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; flex: none; }
.ml-footer__contacttekst { display: grid; gap: 2px; }
.ml-footer__contacttekst a { font-size: var(--ml-ui); text-decoration: none; }
.ml-footer__contacttekst a:hover { text-decoration: underline; }
.ml-footer__notitie { font-size: var(--ml-label); opacity: 0.85; }

.ml-footer__groepkop {
  font-family: var(--ml-font-tekst); font-weight: 700;
  font-size: var(--ml-ui); line-height: var(--ml-lh-tekst);
  letter-spacing: var(--ml-ls-tekst);
  margin: 0 0 4px;
}
.ml-footer__adres { font-style: normal; font-size: var(--ml-ui); }
.ml-footer__adres p, .ml-footer__social p { margin: 0; }
.ml-footer__social { font-size: var(--ml-ui); display: grid; gap: 2px; }
.ml-footer a { color: inherit; }
.ml-footer__social a { text-decoration: none; }
.ml-footer__social a:hover { text-decoration: underline; }

/* De nieuwsbriefregel is een link met een pijl, met een lijn eronder
   over de volle breedte van de kolom. */
.ml-footer__nieuwsbrief {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid color-mix(in srgb, currentColor 55%, transparent);
  font-size: var(--ml-ui); text-decoration: none;
}
.ml-footer__nieuwsbrief .ml-pijl { width: 30px; height: 30px; transition: translate var(--ml-duur) var(--ml-ease); }
.ml-footer__nieuwsbrief:hover .ml-pijl { translate: 4px 0; }

.ml-footer__onder {
  display: flex; flex-wrap: wrap; gap: 12px 32px;
  align-items: baseline; justify-content: space-between;
  margin-top: 64px;
  font-size: var(--ml-ui);
}
.ml-footer__copyright { margin: 0; }
.ml-footer__juridisch { display: flex; flex-wrap: wrap; gap: 32px; }
.ml-footer__juridisch p { margin: 0; }
.ml-footer__juridisch a { text-decoration: none; }
.ml-footer__juridisch a:hover { text-decoration: underline; }

@media (max-width: 809.98px) {
  .ml-footer { padding-block: 56px 32px; }
  /* Op een telefoon staat alles onder elkaar: de juridische links links
     uitgelijnd onder LinkedIn met een kleine tussenruimte, en het
     copyright helemaal onderaan. De rijruimte van het raster gaat daarom
     omlaag; de ruimte tussen de kop en het rechterblok houden we met een
     eigen marge op 64. */
  .ml-footer__inner { row-gap: 24px; }
  .ml-footer__rechts { margin-top: 40px; }
  .ml-footer__onder {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 12px;
    margin-top: 0;
  }
  .ml-footer__juridisch { order: 1; flex-direction: column; gap: 12px; }
  .ml-footer__copyright { order: 2; margin-top: 40px; }
  /* Op een telefoon is de kop kleiner, dus de streep hangt er ook dichter
     onder; de verhouding blijft gelijk. */
  .ml-footer__streep { top: calc(100% + 28px); }
  .ml-footer__kop { margin-bottom: 96px; max-width: none; }
}

/* ========================================================= formulieren */
/* De velden zijn lijnen, geen vakjes: dat is wat de live site doet. Ze
   erven de tekstkleur van het vlak waarop ze staan, zodat hetzelfde
   formulier op wit én op blauw werkt. In Plate kan de redactie zelf
   velden toevoegen, dus de opmaak hangt aan het soort veld en niet aan
   een vaste lijst. */

.ml-form { display: grid; gap: 1.75rem; }
.ml-form__rij { display: grid; gap: 1.75rem; }
@media (min-width: 810px) { .ml-form__rij--twee { grid-template-columns: 1fr 1fr; } }

.ml-form label {
  display: block;
  font-size: var(--ml-micro);
  margin-bottom: 0.35rem;
  color: color-mix(in srgb, currentColor 70%, transparent);
}

.ml-form input[type="text"],
.ml-form input[type="email"],
.ml-form input[type="tel"],
.ml-form input[type="url"],
.ml-form input[type="number"],
.ml-form input[type="date"],
.ml-form select,
.ml-form textarea {
  width: 100%;
  padding: 0 0 0.6rem;
  background: transparent;
  color: inherit;
  font-size: var(--ml-tekst);
  border: 0;
  border-bottom: 1px solid color-mix(in srgb, currentColor 45%, transparent);
  border-radius: 0;
  transition: border-color var(--ml-duur) var(--ml-ease);
}
.ml-form textarea { min-height: 100px; resize: vertical; }
.ml-form ::placeholder { color: color-mix(in srgb, currentColor 55%, transparent); }
.ml-form :is(input, select, textarea):focus {
  outline: none;
  border-bottom-color: currentColor;
  border-bottom-width: 2px;
}
.ml-form :is(input, select, textarea):focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

/* Aankruisvakjes en keuzerondjes houden wel een zichtbare rand. */
.ml-form input[type="checkbox"],
.ml-form input[type="radio"] { width: 1.1em; height: 1.1em; accent-color: var(--ml-blauw); }
.ml-form__keuze { display: flex; gap: 0.6rem; align-items: flex-start; font-size: var(--ml-ui); }

.ml-form__fout { color: var(--ml-oranje); font-size: var(--ml-micro); margin-top: 0.3rem; }
.ml-form__bevestiging { padding: 1rem 1.25rem; background: var(--ml-groen); color: var(--ml-wit); }

/* Op een blauw of zwart vlak staan de lijnen in wit, doordat ze
   currentColor volgen. Geen aparte regels nodig. */

/* ====================================================== handgeschreven */
/* Het woord met de handgetekende ovaal eromheen. De vorm komt van de
   live site, bijgesneden tot waar de inkt staat, en ligt als masker over
   de tekstkleur. Zo rekt hij mee met de woordbreedte en volgt hij de
   kleur van de kop: geen tweede bestand voor een andere achtergrond.

   De ovaal ligt vóór de letters, want hij is ook op de live site over de
   tekst heen getekend. */
/* De ovaal is altijd zwart, ook op een blauw vlak: hij is een getekende
   notitie over de kop heen en niet een deel van de letters. En hij ligt
   eronder, niet erover, zodat de tekst leesbaar blijft waar de lijn
   kruist. Dat is wat een potlood op papier ook doet als je het woord al
   had opgeschreven.

   Het woord krijgt een eigen stapelvlak, want een laag met een negatieve
   z-index zou anders achter de achtergrond van de sectie verdwijnen. */
.ml-markering { position: relative; display: inline-block; isolation: isolate; }
.ml-markering::after {
  content: "";
  position: absolute; left: 50%; top: 50%;
  translate: -50% -50%;
  z-index: -1;
  width: 114%; height: 1.08em;
  background: var(--ml-zwart);
  -webkit-mask: url("../img/doodle-cirkel.svg") center / 100% 100% no-repeat;
          mask: url("../img/doodle-cirkel.svg") center / 100% 100% no-repeat;
  pointer-events: none;
}
/* De kleur van de ovaal, te kiezen in de tekst met ~woord|groen~. */
.ml-markering--wit::after        { background: var(--ml-wit); }
.ml-markering--grijs::after      { background: var(--ml-grijs); }
.ml-markering--abrikoos::after   { background: var(--ml-abrikoos); }
.ml-markering--geel::after       { background: var(--ml-geel); }
.ml-markering--groen::after      { background: var(--ml-groen); }
.ml-markering--lichtblauw::after { background: var(--ml-lichtblauw); }
.ml-markering--oranje::after     { background: var(--ml-oranje); }
.ml-markering--blauw::after      { background: var(--ml-blauw); }
.ml-markering--zwart::after      { background: var(--ml-zwart); }

/* ============================================================= header */

/* Gemeten op de live site: het blauwe kopblok is 611 hoog, de kop begint
   25 onder de navigatiebalk, en de onderste regel staat 70 boven de
   onderkant. De kop staat in twee regels met elk een eigen kleur. */
.ml-header { padding-block: 25px 70px; }
.ml-header__kop { margin-bottom: 0; }
.ml-header__kop + .ml-header__kop { margin-bottom: 0; }
.ml-header__koppen { margin-bottom: 210px; }
.ml-header__onder {
  display: flex; flex-wrap: wrap; gap: 1.5rem 3rem;
  align-items: flex-end; justify-content: space-between;
}

@media (max-width: 809.98px) {
  .ml-header { padding-block: 15px 40px; }
  .ml-header__koppen { margin-bottom: 90px; }
}
/* Gemeten op de live site: 20/26 in bold, in een kolom van ruim 320. */
.ml-header__tekst { max-width: 323px; font-size: var(--ml-lead); font-weight: 700; }

/* De tweede regel van de kop in een eigen merkkleur. */
.ml-kop--wit        { color: var(--ml-wit); }
.ml-kop--abrikoos   { color: var(--ml-abrikoos); }
.ml-kop--geel       { color: var(--ml-geel); }
.ml-kop--groen      { color: var(--ml-groen); }
.ml-kop--blauw      { color: var(--ml-blauw); }
.ml-kop--lichtblauw { color: var(--ml-lichtblauw); }
.ml-kop--oranje     { color: var(--ml-oranje); }
.ml-kop--zwart      { color: var(--ml-zwart); }

/* ========================================================== tweekolom */
/* Kop links, tekst rechts. Onder 810 valt de kop boven de tekst. */

/* De kolomverhouding is van de live site: op 1512 staat de kop op 70 in
   een kolom tot 519, en begint de tekst op 544 met een breedte van 898.
   Dat is ongeveer een op twee met 25 pixels ertussen. */
.ml-tweekolom__inner { display: grid; gap: 1.5rem; }
.ml-tweekolom__kop { font-size: var(--ml-kop-m); }
.ml-tweekolom__tekst p + p { margin-top: 1em; }

@media (min-width: 810px) {
  /* Dezelfde verhouding als de hulp- en dienstensectie. Met 1fr/2fr begon
     de rechterkolom op 544 en bij die twee op 537, en dan loopt de pagina
     zeven pixels uit de pas. 441/906 is de maat uit de fase 2-PDF: de
     rechterkolom begint daar op 537 binnen een container van 1372. */
  .ml-tweekolom__inner { grid-template-columns: minmax(12rem, 441fr) 906fr; column-gap: 25px; }
}

/* In de leesmaat blijft de regel op leeslengte; in de grote maat niet,
   want daar is de kolombreedte zelf al de begrenzing. */
.ml-tweekolom__tekst:not(.ml-grote-tekst) { max-width: 62ch; }

/* De knop staat onder de tekst, op de linkerlijn van de tekstkolom.
   Gemeten in fase 2: 56 ruimte erboven. */
.ml-tweekolom__actie { margin: 56px 0 0; }

.ml-tekst--blauw      { color: var(--ml-blauw); }
.ml-tekst--groen      { color: var(--ml-groen); }
.ml-tekst--oranje     { color: var(--ml-oranje); }
.ml-tekst--lichtblauw { color: var(--ml-lichtblauw); }

/* ============================================================ belofte */

/* Gemeten in fase 2 op een vlak van 1512 bij 657:
     de lichtblauwe vorm loopt van 1073 tot buiten de rechterrand
     de ster staat op 1050 tot 1141, 113 van boven
     het portret staat rechts op de onderrand, 1247 tot 1512
     de kop begint op 70 en eindigt 87 boven de onderkant

   De decoratie staat achter de tekst en loopt bewust door tot buiten het
   vlak; daarom snijdt de sectie af met overflow: clip. Dat maakt, anders
   dan hidden, geen scrollvak van de sectie. */
.ml-belofte {
  position: relative;
  overflow: clip;
  min-height: 657px;
  padding-block: 70px 87px;
  /* De kop hoort onderin. Dat gaat hier met een raster van twee rijen
     waarvan de bovenste alle ruimte opslokt, en niet met flex-end.

     Reden: met flex-end hing het ervan af dat de kop het enige element
     in de stroom is. In de editor zet Plate er nog iets bij, en dan
     schoot de kop terug naar boven. Lokaal zag je dat niet, op staging
     wel. Met een vaste rij voor de kop kan dat niet meer gebeuren. */
  display: grid;
  grid-template-rows: 1fr auto;
}
.ml-belofte > .ml-belofte__inner { grid-row: 2; }

.ml-belofte__decor { position: absolute; inset: 0; pointer-events: none; }

/* De vorm is een losse PNG met doorzichtige achtergrond. Hij ligt als
   masker over de kleur, zodat lichtblauw één keer in de tokens staat en
   hier niet nog eens in een bestand zit. */
.ml-belofte__vorm {
  position: absolute; top: 0; bottom: 0; right: 0;
  width: 29%;            /* 1512 - 1073 = 439, oftewel 29 procent */
  min-width: 300px;
  background: var(--ml-lichtblauw);
  -webkit-mask: url("../img/vorm-blauw.png") right top / auto 100% no-repeat;
          mask: url("../img/vorm-blauw.png") right top / auto 100% no-repeat;
}

.ml-belofte__ster {
  position: absolute;
  top: 17%; right: 24.5%;
  width: 91px; aspect-ratio: 228 / 265;
  background: var(--ml-zwart);
  -webkit-mask: url("../img/ster.png") center / contain no-repeat;
          mask: url("../img/ster.png") center / contain no-repeat;
}

/* Het portret staat op de onderrand van het vlak, niet erin zwevend. */
.ml-belofte__portret {
  position: absolute; right: 0; bottom: 0;
  width: 17.5%; min-width: 190px;
  margin: 0;
  display: flex; align-items: flex-end;
}
.ml-belofte__portret img { width: 100%; height: auto; display: block; }

.ml-belofte__inner { position: relative; z-index: 1; width: 100%; }
.ml-belofte__kop {
  margin: 0;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-l); line-height: 1;
  letter-spacing: normal;
  /* De breedste regel in het ontwerp loopt tot 1202, dus tot net voor
     de lichtblauwe vorm. Daarmee komt de kop op vier regels uit. */
  max-width: 1210px;
}

@media (max-width: 1199.98px) {
  .ml-belofte { min-height: 0; padding-block: 56px 64px; }
  .ml-belofte__kop { font-size: var(--ml-kop-m); max-width: 68%; }
}
/* Op een telefoon is er geen ruimte naast de tekst. De vorm blijft als
   accent in de hoek staan, het portret en de ster gaan weg: een half
   afgesneden gezicht achter de tekst leest slechter dan geen gezicht. */
@media (max-width: 809.98px) {
  .ml-belofte__portret, .ml-belofte__ster { display: none; }
  .ml-belofte__vorm { width: 55%; opacity: 0.5; }
  .ml-belofte__kop { max-width: none; }
}

/* =============================================================== hulp */

.ml-hulp__inner { display: grid; gap: 1.5rem 3rem; }
.ml-hulp__kop { font-size: var(--ml-kop-m); }
/* Let op de structuur. Plate zet tussen de sectie en de elementen nog
   een container, een rij en een kolom:

     .ml-hulp__inhoud > .plate--container > .plate--row > .plate--column
       > .plate--element > de balk zelf

   Het raster moet dus op die kolom staan en niet op .ml-hulp__inhoud,
   anders krijgt de kolom één cel en staan alle elementen onder elkaar.
   Dit is dezelfde val als eerder bij het andere project; hij is niet
   zichtbaar in de HTML die je schrijft, alleen in wat Plate eromheen
   zet. */
.ml-hulp__inhoud .plate--column { display: grid; gap: 18px; }

@media (min-width: 810px) {
  .ml-hulp__inhoud .plate--column { grid-template-columns: 1fr 1fr; column-gap: 24px; }
  /* De balken lopen over de volle breedte, de kleine items twee per rij. */
  .ml-hulp__inhoud .plate--element__ml_hulp_balk { grid-column: 1 / -1; }
}

/* Lucht tussen de balken en de kleine items eronder. */
@supports selector(:nth-child(1 of .plate--element)) {
  .ml-hulp__inhoud :nth-child(1 of .plate--element__ml_hulp_item) { margin-top: 24px; }
  @media (min-width: 810px) {
    .ml-hulp__inhoud :nth-child(2 of .plate--element__ml_hulp_item) { margin-top: 24px; }
  }
}

/* Gemeten in fase 2: de kop staat op 70, de balken lopen van 537 tot
   1443. Binnen een container van 1372 is dat 441 en 906 met 25 ertussen. */
@media (min-width: 810px) {
  .ml-hulp__inner { grid-template-columns: minmax(12rem, 441fr) 906fr; column-gap: 25px; }
}

/* De gekleurde balken. Gemeten in de fase 2-PDF: ze lopen van 537 tot
   1443, hebben rechte hoeken, een getekend icoon van ongeveer 126 links
   en de getekende pijl rechts. De tekst begint overal op 768, dus het
   icoonvak houdt zijn breedte ook als er geen icoon in staat.

   Zonder eigen kleurkeuze wisselen ze af in de merkvolgorde, zodat een
   rij er ook ongevuld goed uitziet. */
.ml-balk {
  display: flex; align-items: center; gap: 82px;
  min-height: 150px;
  padding: 12px 32px 12px 24px;
  border-radius: 0;
  text-decoration: none;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-s); line-height: var(--ml-lh-kop-s);
  transition: transform var(--ml-duur) var(--ml-ease);
}
.ml-balk:hover { transform: translateX(4px); }
.ml-balk__tekst { flex: 1; }
.ml-balk__icoon {
  flex: none;
  display: grid; place-items: center;
  width: 126px; height: 126px;
}
.ml-balk__icoon img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.ml-balk__pijl { width: 46px; height: 46px; }

@media (max-width: 809.98px) {
  .ml-balk { gap: 20px; min-height: 0; padding: 20px; }
  .ml-balk__icoon { width: 72px; height: 72px; }
}

/* Zonder eigen kleurkeuze krijgt elke balk een kleur uit de reeks.
   Let op de structuur: Plate zet tussen de sectie en het element nog een
   container, een rij en een kolom, dus een selector met > op de sectie
   raakt niets. En omdat in dezelfde kolom ook andere elementtypes staan,
   telt een gewone nth-child verkeerd; `of` telt alleen de balken mee.
   Browsers zonder `of` houden de terugval hieronder. */
.ml-balk:not([class*="ml-vlak--"]) { background: var(--ml-geel); }

@supports selector(:nth-child(1 of .plate--element)) {
  .ml-hulp :nth-child(3n+1 of .plate--element__ml_hulp_balk) .ml-balk:not([class*="ml-vlak--"]) { background: var(--ml-oranje); }
  .ml-hulp :nth-child(3n+2 of .plate--element__ml_hulp_balk) .ml-balk:not([class*="ml-vlak--"]) { background: var(--ml-geel); }
  .ml-hulp :nth-child(3n+3 of .plate--element__ml_hulp_balk) .ml-balk:not([class*="ml-vlak--"]) { background: var(--ml-abrikoos); }
}
/* Oranje en geel zijn te licht voor witte tekst; de balken houden dus
   zwarte tekst, ook als de redactie zelf een kleur kiest. Alleen blauw
   en zwart keren om, en dat regelt ml-vlak zelf. */

/* De kleinere items eronder, twee per rij vanaf tablet. In fase 2 staan
   ze op 20, waar de live site ze nog op 30 had: dat is een van de
   plekken waar het ontwerp bewust is teruggebracht. */
.ml-hulpitem {
  display: flex; align-items: center; gap: 24px;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-tekst); line-height: var(--ml-lh-tekst);
  text-decoration: none;
}
.ml-hulpitem__icoon {
  flex: none;
  display: grid; place-items: center;
  width: 86px; height: 86px;
}
.ml-hulpitem__icoon img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.ml-hulpitem__tekst { flex: 1; }

/* ============================================================== video */
/* Op de home ligt de film direct onder de blauwe header, over de volle
   breedte en zonder tussenruimte: het blauwe vlak en het beeld raken
   elkaar. De verhouding is op de live site gemeten op 16:9, en die blijft
   op elke breedte gelijk: 1512x850, 1200x675, 810x456, 390x219. */

.ml-video { position: relative; }
/* Alles behalve de volle breedte krijgt de gewone sectieruimte. */
.ml-video:not(.ml-video--breed) { padding-block: var(--ml-sectie-y); }
/* De breedte komt van de container eromheen, niet van een max-width
   hier. Die stond op 1600 terwijl een gewoon scherm 1512 is, dus hij
   liep alsnog van rand tot rand en de keuze "binnen de marges" leek
   niets te doen. */
.ml-video:not(.ml-video--breed) .ml-video__kader {
  border-radius: var(--ml-radius-vlak);
  overflow: hidden;
}

.ml-video__kader {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--ml-zwart);
  overflow: hidden;
}

.ml-video__poster {
  width: 100%; height: 100%;
  object-fit: cover;
}
.ml-video__poster--leeg { background: var(--ml-zwart); }

/* De film vervangt de hele inhoud van het kader zodra er geklikt is. */
.ml-video__kader iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0;
}

/* Het woord over het beeld, linksonder, binnen dezelfde zijmarge als de
   rest van de pagina. */
.ml-video__overlay {
  position: absolute; left: 0; right: 0; bottom: 0;
  width: 100%;
  max-width: calc(var(--ml-max) + 2 * var(--ml-marge));
  margin: 0 auto;
  padding: var(--ml-marge) var(--ml-marge) clamp(1rem, 3vw, 2.5rem);
  color: var(--ml-wit);
  text-shadow: 0 2px 24px rgb(15 17 30 / 0.35);
  pointer-events: none;
}

/* De afspeelknop: een witte cirkel in het midden. De driehoek staat een
   paar pixels naar rechts, anders lijkt hij uit het midden te vallen. */
.ml-video__knop {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 88px; height: 88px; padding: 0 0 0 6px;
  border: 0; border-radius: 50%;
  background: rgb(255 255 255 / 0.9);
  color: var(--ml-zwart);
  cursor: pointer;
  transition: background var(--ml-duur) var(--ml-ease),
              transform var(--ml-duur) var(--ml-ease);
}
.ml-video__knop:hover {
  background: var(--ml-wit);
  transform: translate(-50%, -50%) scale(1.08);
}
.ml-video__knop svg { width: 26px; height: 30px; }

.ml-video__melding {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  margin: 0; padding: 0.75rem 1.25rem;
  background: var(--ml-wit); color: var(--ml-zwart);
  font-size: var(--ml-ui);
}


/* ============================================== tekst uit de editor */
/* De opmaak-editor van Plate levert alinea's, vet, lijstjes en links.
   Hier staat één keer hoe die zich gedragen binnen onze tekstvlakken,
   zodat de redactie kan opmaken zonder dat de bladspiegel verschuift. */

.ml-header__tekst p:last-child,
.ml-vraag__lead p:last-child,
.ml-quote__tekst p:last-child,
.ml-footer__adres p:last-child,
.ml-footer__social p:last-child { margin-bottom: 0; }

.ml-quote__tekst p { margin: 0 0 0.5em; }
.ml-quote__tekst strong,
.ml-header__tekst strong,
.ml-vraag__lead strong { font-weight: 700; }

/* In de grote tekstmaat is vet het verschil tussen 700 en 800, want de
   hele alinea staat al in bold. */
.ml-grote-tekst strong { font-weight: 800; }

/* Lijstjes houden de inspringing binnen de kolom. */
.ml-prose ul, .ml-grote-tekst ul,
.ml-prose ol, .ml-grote-tekst ol { margin: 0 0 1em; padding-left: 1.2em; }
.ml-prose li + li, .ml-grote-tekst li + li { margin-top: 0.3em; }

/* Een link in lopende tekst blijft herkenbaar als link. Een knop niet:
   die is al als knop te herkennen. Zonder deze uitzondering wint de
   onderstreping, want ".ml-grote-tekst a" weegt zwaarder dan ".ml-knop",
   en dan staat elke knop in een tekstblok onderstreept. */
.ml-prose a:not(.ml-knop),
.ml-grote-tekst a:not(.ml-knop),
.ml-vraag__lead a:not(.ml-knop),
.ml-header__tekst a:not(.ml-knop) {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

/* En voor de zekerheid: een knop is nooit onderstreept, waar hij ook
   staat, en houdt zijn eigen maat ongeacht de tekst eromheen. */
.ml-knop, .ml-knop:hover, .ml-knop:focus-visible {
  text-decoration: none;
}

/* ========================================================== beweging */
/* De uitgangspunten: beweging mag opvallen als je erop let, maar nooit
   als je gewoon leest. Alles duurt kort, komt één keer, en verschuift
   hooguit een centimeter.

   De verborgen begintoestand hangt aan `data-beweging="aan"`, dat het
   script op <html> zet. Het script weegt daar drie dingen af: of er
   JavaScript is, of we binnen de editor zitten, en of de bezoeker om
   minder beweging heeft gevraagd. Staat het attribuut er niet, dan is er
   ook niets onzichtbaars.

   Let op: kijk hier niet zelf naar `data-editor`. Plate zet dat attribuut
   al zodra iemand ingelogd is, ook buiten de editor, en dan staat de
   animatie uit voor precies de mensen die hem moeten beoordelen. Dat
   heeft op 3 oktober 2026 een dag zoeken gekost. */

/* 40 pixels in 0,6 s, opgemeten op de live site: daar staat
   `transform: translateY(40px)` met `opacity: 0` op elk blok dat opkomt,
   en de drempel ligt op 78 procent van de schermhoogte. */
[data-beweging="aan"] [data-onthul] {
  opacity: 0;
  translate: 0 40px;
  transition: opacity 0.6s var(--ml-ease), translate 0.6s var(--ml-ease);
  transition-delay: var(--ml-vertraging, 0ms);
}
[data-beweging="aan"] [data-onthul].is-zichtbaar {
  opacity: 1;
  translate: none;
}

/* De ovaal wordt getekend in plaats van ingevuld: een veeg van links
   naar rechts leest als een hand die hem zet. Hij begint pas als het
   woord zelf er staat, vandaar de kleine wachttijd. */
/* De ovaal werd eerder met een clip-path van links naar rechts
   weggeveegd. Nu tekent het script hem echt, als streep met een vaste
   dikte; die veeg is daarmee overbodig. Gaat het script niet af, dan
   staat de ovaal er gewoon als masker. */

/* Het beeld in de videosectie komt tot rust in plaats van stil te staan:
   een trage uitzoom van een paar procent terwijl het blok verschijnt. */
[data-beweging="aan"] .ml-video__poster {
  scale: 1.06;
  transition: scale 1.4s var(--ml-ease);
}
[data-beweging="aan"] .ml-video__kader.is-zichtbaar .ml-video__poster {
  scale: 1;
}

/* De afspeelknop ademt heel licht, zodat het oog hem vindt zonder dat
   het blok onrustig wordt. Hij stopt zodra je hem aanwijst. */
@media (prefers-reduced-motion: no-preference) {
  .ml-video__knop::before {
    content: "";
    position: absolute; inset: 0;
    border-radius: 50%;
    box-shadow: 0 0 0 0 rgb(255 255 255 / 0.45);
    animation: ml-adem 2.8s var(--ml-ease) infinite;
  }
  .ml-video__knop:hover::before,
  .ml-video__knop:focus-visible::before { animation: none; }
}
@keyframes ml-adem {
  0%   { box-shadow: 0 0 0 0 rgb(255 255 255 / 0.4); }
  70%  { box-shadow: 0 0 0 22px rgb(255 255 255 / 0); }
  100% { box-shadow: 0 0 0 0 rgb(255 255 255 / 0); }
}

/* Een link in het menu krijgt zijn streep van links naar rechts, en
   verliest hem weer naar rechts: dat leest natuurlijker dan een streep
   die in het midden uit elkaar valt. */
.ml-nav__lijst a {
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  border-bottom: 0;
  transition: background-size 0.3s var(--ml-ease);
}
.ml-nav__lijst a:hover,
.ml-nav__lijst a[aria-current="page"] { background-size: 100% 2px; }

/* De gekleurde balken schuiven niet alleen op, hun pijl loopt vooruit. */
.ml-balk__pijl { transition: translate 0.35s var(--ml-ease); }
.ml-balk:hover .ml-balk__pijl { translate: 6px 0; }


/* ============================================================ pijltje */
/* Eén vorm voor alle pijltjes: in de gekleurde balken, in de carrousel
   en in de footer. Als masker over de tekstkleur, dus zwart op geel en
   wit op blauw zonder een tweede bestand. */
.ml-pijl {
  display: block; flex: none;
  width: 40px; height: 40px;
  background: currentColor;
  -webkit-mask: url("../img/pijl-carrousel.png") center / contain no-repeat;
          mask: url("../img/pijl-carrousel.png") center / contain no-repeat;
}
.ml-pijl--terug { rotate: 180deg; }

/* ============================================================== iconen */
/* De getekende merkiconen. Ze liggen als masker over de tekstkleur in
   plaats van als plaatje: zo worden de twee verschillende zwarten waarin
   ze zijn aangeleverd één kleur, en wordt een icoon op een blauw of
   zwart vlak vanzelf wit.

   Ze zijn vierkant aangeleverd, dus contain houdt ze heel. */
.ml-icoon {
  display: block;
  width: 100%; height: 100%;
  background: currentColor;
  -webkit-mask: var(--ml-icoon) center / contain no-repeat;
          mask: var(--ml-icoon) center / contain no-repeat;
}
.ml-icoon--raket        { --ml-icoon: url("../img/iconen/raket.png"); }
.ml-icoon--diamant      { --ml-icoon: url("../img/iconen/diamant.png"); }
.ml-icoon--gezicht      { --ml-icoon: url("../img/iconen/gezicht.png"); }
.ml-icoon--cursor       { --ml-icoon: url("../img/iconen/cursor.png"); }
.ml-icoon--megafoon     { --ml-icoon: url("../img/iconen/megafoon.png"); }
.ml-icoon--kleurcirkels { --ml-icoon: url("../img/iconen/kleurcirkels.png"); }
.ml-icoon--dossier      { --ml-icoon: url("../img/iconen/dossier.png"); }


/* ======================================================== schetsrand */
/* De bobbelige rand ligt als SVG over het vlak heen en levert zelf de
   vulling, zodat er geen rechte hoek onder de getekende lijn uit piept.
   Hij steekt een paar pixels buiten het blok, want de bobbels lopen tot
   net buiten de lijn. */
/* Let op de selector: `svg.ml-schetsrand` en niet `.ml-schetsrand`.
   Plate's eigen stylesheet, die vóór de onze geladen wordt, bevat
   `svg:not(:root) { overflow: hidden }`. Dat weegt zwaarder dan een losse
   klasse, dus onze `overflow: visible` verloor en de bobbels werden op de
   rand afgeknipt: de kaders zagen er weer kaarsrecht uit. Met het
   element-deel erbij wegen ze even zwaar en wint de onze, omdat hij later
   komt. */
svg.ml-schetsrand {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible;      /* de bobbels van de lijn mogen eruit steken */
  pointer-events: none;
}

/* =================================================== vraag met rand */

.ml-vraag__blok {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 2rem 3rem;
  align-items: center; justify-content: space-between;
  min-height: 313px;          /* gemeten op de live site */
  padding: 70px 116px;
  background: none;           /* de getekende rand levert de vulling */
}
/* Alles binnen het blok ligt boven de getekende laag. */
.ml-vraag__blok > *:not(.ml-schetsrand) { position: relative; z-index: 1; }

.ml-vraag__kop { font-size: var(--ml-kop-m); margin-bottom: 1rem; }
.ml-vraag__lead { font-size: var(--ml-tekst); max-width: 44ch; }
.ml-vraag__actie { display: flex; align-items: center; gap: 2rem; }
.ml-vraag__pijl { display: block; width: 162px; color: var(--ml-zwart); flex: none; }
.ml-vraag__pijl svg { width: 100%; height: auto; }

/* De tekst en de knop horen naast elkaar. Ze pasten niet: samen 1006 in
   een ruimte van 907, dus brak de rij af en belandde de knop eronder.
   Met basis 0 pakt de tekstkolom alleen de restruimte en blijven ze op
   één regel; de kop valt dan over twee regels.

   Alleen vanaf 1200, want daaronder is het blok smaller (binnenruimte 48
   in plaats van 116) en knijpt diezelfde regel de tekst tot één woord per
   regel. Daar hoort de knop gewoon onder de tekst, en dat gebeurt vanzelf
   doordat de rij afbreekt.

   Dit blok staat bewust ná de losse regels hierboven. Het stond er eerst
   vóór, en toen won `.ml-vraag__pijl { width: 162px }` het alsnog van de
   120 hieronder: een mediaregel weegt niet zwaarder, alleen later. */
@media (min-width: 1200px) {
  .ml-vraag__tekst { flex: 1 1 0; min-width: 0; }
  /* De knop lijnt uit met de onderkant van de tekst, niet met het midden
     van het blok. De regelhoogte van de rij is die van de tekstkolom, dus
     flex-end zet hem precies op de onderste tekstregel. */
  .ml-vraag__actie { flex: none; align-self: flex-end; }
  /* Wat meer ruimte voor de tekst: de pijl iets korter en de twee gaten
     wat krapper, samen goed voor zo'n 70 px extra tekstbreedte. */
  /* De rij mag niet uitrekken tot de volle blokhoogte, anders ligt de
     onderkant van de rij op de bodem van het blok en niet op de laatste
     tekstregel. Met align-content houdt de rij zijn eigen hoogte en komt
     hij als geheel in het midden. */
  .ml-vraag__blok { column-gap: 2rem; align-content: center; }
  .ml-vraag__actie { gap: 1.5rem; }
  .ml-vraag__pijl { width: 120px; }
}

@media (max-width: 1199.98px) { .ml-vraag__blok { padding: 48px; } }
@media (max-width: 809.98px) {
  .ml-vraag__blok { padding: 32px 28px; }
  .ml-vraag__pijl { display: none; }   /* wijst dan nergens naar */
}

/* ====================================================== cijferblokken */
/* Twaalf kolommen, twee rijen. De plaatsing hangt aan de volgorde van de
   elementen, zodat de redactie niets over kolommen hoeft te weten.

   Let op: Plate zet tussen de sectie en de elementen een container, een
   rij en een kolom, dus het raster staat op .plate--column. */

.ml-cijfers__raster .plate--column {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(2, 236px);  /* rij 236 hoog, gemeten in fase 2 */
  /* Belangrijk: de rijen staan vást op twee. In de editor hangt Plate nog
     een eigen hulpelement in dezelfde kolom, en met grid-auto-rows kreeg
     dat een eigen rij van 236 pixels. Dat gaf een gat van een halve
     schermhoogte onder de sectie, dat alleen in de editor te zien was.
     Een impliciete rij is nu nul hoog. */
  grid-auto-rows: 0;
}
/* De elementlaag van Plate zit tussen het raster en het blok in. Die moet
   zijn cel helemaal vullen, anders krimpt het vlak tot de tekst. */
.ml-cijfers__raster .plate--element { display: flex; min-height: 0; }
.ml-cijfers__raster .plate--element > * { flex: 1; min-width: 0; }

@supports selector(:nth-child(1 of .plate--element)) {
  .ml-cijfers__raster :nth-child(1 of .plate--element) { grid-column: 1 / 7;   grid-row: 1 / 3; }
  .ml-cijfers__raster :nth-child(2 of .plate--element) { grid-column: 7 / 11;  grid-row: 1 / 3; }
  .ml-cijfers__raster :nth-child(3 of .plate--element) { grid-column: 11 / 13; grid-row: 1; }
  /* Het vierde blok schuift half over het tweede en derde heen. */
  .ml-cijfers__raster :nth-child(4 of .plate--element) { grid-column: 9 / 13;  grid-row: 2; z-index: 2; }
}

.ml-cijfer {
  position: relative;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 30px;
  min-height: 0;
  overflow: hidden;
}
/* Het blok met de getekende rand mag juist niet afsnijden, want de
   bobbels lopen tot buiten het vlak. */
.ml-cijfer--schets { overflow: visible; background: none; }
.ml-cijfer > *:not(.ml-schetsrand) { position: relative; z-index: 1; }

.ml-cijfer__getal {
  margin: 0;
  font-family: var(--ml-font-kop);
  font-weight: 600;
  font-size: var(--ml-kop-xl);
  line-height: 0.95;
  letter-spacing: normal;
}
/* Geen tabellarische cijfers. Die lijken handig tijdens het tellen, maar
   ze maken een 1 en een 0 even breed en daarmee "100+" bijna honderd
   pixels breder dan in het ontwerp. Het getal staat links uitgelijnd, dus
   tijdens het tellen beweegt alleen de rechterkant, en dat duurt
   anderhalve seconde. */
.ml-cijfer__label {
  margin: 0;
  font-family: var(--ml-font-kop);
  font-weight: 700;
  font-size: var(--ml-lead);
  line-height: var(--ml-lh-tekst);
  /* "Wervingscampagnes" past niet naast het groene blok dat eroverheen
     schuift. Afbreken met een koppelteken is wat het ontwerp ook doet:
     daar staat "Wervings-" en "campagnes" onder elkaar. */
  hyphens: auto;
  overflow-wrap: break-word;
}

/* Het tweede blok wordt rechtsonder half afgedekt door het vierde. Het
   label houdt daarom afstand tot die rand, anders loopt het eronder. */
@supports selector(:nth-child(1 of .plate--element)) {
  @media (min-width: 810px) {
    .ml-cijfers__raster :nth-child(2 of .plate--element) .ml-cijfer__label { max-width: 44%; }
  }
}

/* De maten uit fase 2: 240, 170, 95 en 120. Ze horen bij de plek in het
   raster, niet bij het getal zelf. */
@supports selector(:nth-child(1 of .plate--element)) {
  @media (min-width: 810px) {
    .ml-cijfers__raster :nth-child(1 of .plate--element) .ml-cijfer__getal { font-size: 15rem;    }  /* 240 */
    .ml-cijfers__raster :nth-child(2 of .plate--element) .ml-cijfer__getal { font-size: 10.625rem; }  /* 170 */
    .ml-cijfers__raster :nth-child(3 of .plate--element) .ml-cijfer__getal { font-size: 5.9375rem; }  /*  95 */
    .ml-cijfers__raster :nth-child(4 of .plate--element) .ml-cijfer__getal { font-size: 7.5rem;    }  /* 120 */
  }
}

/* Onder 810 passen vier naast elkaar niet. Dan worden het twee rijen van
   twee, allemaal even groot, en vervalt de overlap. */
@media (max-width: 809.98px) {
  .ml-cijfers__raster .plate--column {
    grid-template-columns: 1fr 1fr;
    grid-auto-rows: minmax(170px, auto);
  }
  .ml-cijfers__raster .plate--element { grid-column: auto !important; grid-row: auto !important; }
  /* Vaste maat, niet via kop-l. De cijfers mogen eruit springen en staan
     daarom op het plafond van 42, net als de kop in de header. */
  .ml-cijfer__getal { font-size: 2.625rem; }  /* 42 */
}

/* ========================================================== quotes */
/* Een pak kaarten in plaats van een rij. De bovenste ligt recht, de
   kaarten eronder liggen een paar pixels lager en staan een halve graad
   gedraaid, zodat er een randje van onder uit piept.

   Zonder JavaScript staat .ml-quotes__houder gewoon in stroom en liggen
   de kaarten onder elkaar: alles blijft leesbaar. De stapelstand wordt
   pas gezet als het script er is, via de klasse js op <html>. */

/* De wegvegende kaart schiet links buiten beeld. overflow-x: clip snijdt
   dat af zonder een scrollbalk te maken, en laat de bobbels van de rand
   boven en onder wel gewoon uitsteken. */
.ml-quotes { overflow-x: clip; }

.ml-quotes__kop {
  font-size: var(--ml-kop-s);
  line-height: var(--ml-lh-kop-s);
  text-align: center;
  margin-bottom: 72px;
}

.ml-quotes__houder {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  align-items: center;
  gap: 24px;
}
.ml-quotes__stapel { position: relative; max-width: 1140px; margin-inline: auto; width: 100%; }

/* Zonder script: gewoon onder elkaar, met lucht ertussen. */
.ml-quotes__stapel .plate--column { display: grid; gap: 24px; }

.ml-quote {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "tekst logo" "bron logo";
  align-content: center;
  gap: 24px 48px;
  min-height: 430px;
  margin: 0;
  padding: 72px 93px;
  background: none;            /* de getekende rand levert de vulling */
}
.ml-quote > *:not(.ml-schetsrand) { position: relative; z-index: 1; }

.ml-quote__tekst {
  grid-area: tekst;
  margin: 0;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-s); line-height: var(--ml-lh-kop-s);
  letter-spacing: normal;
  max-width: 24ch;
}
/* De uitspraak zelf staat in abrikoos op blauw; op een licht vlak zou
   dat niet leesbaar zijn, dus daar blijft hij gewoon de tekstkleur. */
.ml-vlak--blauw .ml-quote__tekst,
.ml-vlak--zwart .ml-quote__tekst,
.ml-vlak--groen .ml-quote__tekst { color: var(--ml-abrikoos); }

.ml-quote__bron { grid-area: bron; display: grid; gap: 2px; font-size: var(--ml-tekst); font-weight: 700; }
.ml-quote__logo {
  grid-area: logo; align-self: center;
  display: grid; place-items: center;
  width: 198px; height: 190px;
  padding: 20px;
  background: var(--ml-wit);
}
.ml-quote__logo img { max-width: 100%; max-height: 100%; width: auto; height: auto; }

/* De knoppen staan links en rechts buiten de kaart, op de rand van de
   container. Dezelfde pijl, die voor "vorige" een halve slag draait. */
.ml-quotes__knop {
  position: absolute; top: 50%; translate: 0 -50%;
  z-index: 3;
  display: grid; place-items: center;
  width: 56px; height: 56px; padding: 0;
  border: 0; background: none; color: var(--ml-zwart);
  cursor: pointer;
  transition: translate var(--ml-duur) var(--ml-ease);
}
.ml-quotes__knop--vorige   { left: 0;  }
.ml-quotes__knop--volgende { right: 0; }
.ml-quotes__knop--vorige:hover   { translate: -4px -50%; }
.ml-quotes__knop--volgende:hover { translate: 4px -50%; }

/* ---- vanaf hier alleen met script: de echte stapel ---- */
/* Alle kaarten liggen in dezelfde rastercel. Dat is beter dan ze
   absoluut te plaatsen: de cel wordt vanzelf zo hoog als de langste
   kaart, en er is geen kaart nodig die de hoogte vasthoudt. Die zou
   namelijk zelf ook door de stapel heen schuiven, en dan verspringt het
   hele blok bij elke klik. */
.js .ml-quotes__stapel .plate--column { display: grid; gap: 0; }
.js .ml-quotes__stapel .plate--element {
  grid-area: 1 / 1;
  transition: translate 0.5s var(--ml-ease), rotate 0.5s var(--ml-ease),
              opacity 0.4s var(--ml-ease);
}

.js .ml-quotes__stapel .plate--element[data-diepte="0"] { z-index: 3; translate: 0 0;    rotate: 0deg;    }
.js .ml-quotes__stapel .plate--element[data-diepte="1"] { z-index: 2; translate: -4px 14px; rotate: -0.35deg; }
.js .ml-quotes__stapel .plate--element[data-diepte="2"] { z-index: 1; translate: -8px 28px; rotate: -0.7deg;  }
.js .ml-quotes__stapel .plate--element[data-diepte="3"] { z-index: 0; translate: -10px 36px; rotate: -0.9deg; opacity: 0; }

/* De kaart die wegveegt. Hij draait mee weg, zodat het leest als een
   kaart die je van de stapel schuift en niet als een dia. */
.js .ml-quotes__stapel .plate--element[data-weg="links"]  { z-index: 4; translate: -120% 0; rotate: -7deg; opacity: 0; }
.js .ml-quotes__stapel .plate--element[data-weg="rechts"] { z-index: 4; translate: 120% 0;  rotate: 7deg;  opacity: 0; }
/* Terugleggen onderop gebeurt zonder animatie, anders zie je hem vliegen. */
.js .ml-quotes__stapel .plate--element[data-stil] { transition: none; }

@media (max-width: 1199.98px) {
  .ml-quote { padding: 48px; min-height: 0; }
  .ml-quotes__stapel { max-width: calc(100% - 128px); }
}
@media (max-width: 809.98px) {
  .ml-quote {
    grid-template-columns: 1fr;
    grid-template-areas: "logo" "tekst" "bron";
    padding: 32px 28px; gap: 20px;
  }
  .ml-quote__logo { width: 140px; height: 134px; justify-self: start; }
  /* De knoppen passen op een telefoon niet links en rechts naast de
     kaart. Ze komen eronder, naast elkaar en gecentreerd. De houder
     wordt daarvoor een flexrij: de stapel pakt de volle breedte en
     duwt de twee knoppen naar de regel eronder. */
  .ml-quotes__houder {
    display: flex; flex-wrap: wrap;
    justify-content: center; align-items: center;
    gap: 16px;
  }
  .ml-quotes__stapel { max-width: 100%; flex: 1 0 100%; }
  .ml-quotes__knop { position: static; translate: none; margin-top: 8px; }
  .ml-quotes__knop--vorige:hover   { translate: -4px 0; }
  .ml-quotes__knop--volgende:hover { translate: 4px 0; }
  .ml-quotes__houder { grid-template-columns: auto 1fr auto; }
  .ml-quotes__houder .ml-quotes__stapel { grid-column: 1 / -1; order: -1; }
}


/* ======================================================= dienstenlijst */
/* Kop links in dezelfde kolom als bij de hulpsectie, lijst rechts in
   drie kolommen. De kolommen beginnen in fase 2 op 536, 846 en 1157 en
   de regels staan 46 uit elkaar. */

.ml-diensten__inner { display: grid; gap: 1.5rem; }
.ml-diensten__kop { font-size: var(--ml-kop-m); }

@media (min-width: 810px) {
  .ml-diensten__inner { grid-template-columns: minmax(12rem, 441fr) 906fr; column-gap: 25px; }
}

/* Weer de structuur van Plate: het raster hoort op de kolom, niet op de
   wikkel eromheen. */
.ml-diensten__lijst .plate--column {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px 10px;
}
@media (min-width: 560px) { .ml-diensten__lijst .plate--column { grid-template-columns: 1fr 1fr; } }
@media (min-width: 810px) { .ml-diensten__lijst .plate--column { grid-template-columns: repeat(3, 1fr); } }

.ml-dienst {
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-tekst); line-height: var(--ml-lh-tekst);
  letter-spacing: normal;
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size 0.3s var(--ml-ease);
}
a.ml-dienst:hover { background-size: 100% 2px; }


/* ========================================================== logoband */

.ml-logos { overflow: clip; }
.ml-logos__kop {
  font-size: var(--ml-kop-s);
  line-height: var(--ml-lh-kop-s);
  text-align: center;
  margin-bottom: 56px;
}

/* De band loopt bewust van rand tot rand, dus buiten de container om.

   De logo's moeten naast elkaar staan, maar Plate hangt er container,
   rij en kolom tussen, en in de editor soms nog een laag extra. Elke
   tussenlaag een eigen flex geven werkt dus niet: je weet niet hoeveel
   lagen er zijn en hoe ze heten.

   display: contents haalt die tussenlagen uit de opmaak. De logo's
   worden daardoor rechtstreeks kind van de band, en één flex op de band
   regelt alles. Dat werkt ongeacht hoe diep Plate ze wegstopt. */
/* Let op de nul-gap. Met een gap tussen de logo's zou de tweede helft
   van de band één tussenruimte verder beginnen dan de eerste, en dan
   springt hij zichtbaar op het moment dat de animatie terugspoelt. De
   ruimte zit daarom in de logo's zelf, zodat beide helften exact even
   breed zijn en -50% precies op de naad valt. */
.ml-logos__spoor { display: flex; align-items: center; gap: 0; width: max-content; }
.ml-logos__spoor > *,
.ml-logos__spoor .plate--container,
.ml-logos__spoor .plate--row,
.ml-logos__spoor .plate--column { display: contents; }

/* Plate zet op elk element een order, afgeleid van data-plate-position.
   In de band staan drie kopieën van dezelfde reeks, dus daar komt elke
   order drie keer voor en vlecht flexbox de kopieën door elkaar: je zag
   elk logo drie keer vlak achter elkaar. Binnen de band bepaalt de
   volgorde in de HTML het, en niets anders. */
.ml-logos__spoor .plate--element { order: 0; }

.ml-logo-item { display: block; flex: none; margin-right: var(--ml-logo-ruimte, 110px); }
/* Alleen zichtbaar in de editor: een logo zonder beeld. */
.ml-logo-item--leeg {
  display: grid; place-items: center;
  min-width: 140px; height: 62px; padding: 0 16px;
  border: 1px dashed color-mix(in srgb, currentColor 40%, transparent);
  font-size: var(--ml-micro);
  text-align: center;
  opacity: 0.7;
}
.ml-logo-item img {
  max-height: 62px; width: auto; height: auto;
  /* De logo's komen in allerlei kleuren binnen; in het ontwerp staan ze
     allemaal in hetzelfde grijszwart, zodat de rij rustig blijft. */
  filter: grayscale(1) contrast(1.15);
  opacity: 0.85;
  transition: opacity var(--ml-duur) var(--ml-ease), filter var(--ml-duur) var(--ml-ease);
}
a.ml-logo-item:hover img { filter: none; opacity: 1; }

/* Alleen met script, en alleen als er geen rust gevraagd is. */
@media (prefers-reduced-motion: no-preference) {
  /* De duur wordt door het script gezet, zodat de band altijd even snel
     loopt of er nu acht of twintig logo's in staan. */
  .js .ml-logos__spoor[data-loopt] {
    animation: ml-band var(--ml-bandduur, 40s) linear infinite;
    will-change: transform;
  }
  /* --ml-bandstap is de breedte van één reeks, uitgedrukt in procenten
     van de hele band. Het script zet hem, want hoeveel kopieën er nodig
     zijn hangt af van de schermbreedte. */
  .js .ml-logos__spoor[data-loopt]:hover { animation-play-state: paused; }
}
/* transform en niet translate: dat loopt op meer browsers vloeiend en
   wordt betrouwbaar op de grafische kaart afgehandeld. */
@keyframes ml-band {
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-1 * var(--ml-bandstap, 50%))); }
}

/* Zonder script blijft de rij staan en kun je er langs vegen. */
.ml-logos__spoor:not([data-loopt]) { width: 100%; overflow-x: auto; }


/* ========================================================= overzicht */
/* Cases en het prikbord. Kop gecentreerd op 80, daaronder drie kaarten
   en een knop in het midden. */

.ml-overzicht__kop {
  font-size: var(--ml-kop-xl); line-height: 1;
  text-align: center; margin: 0;
}
.ml-overzicht__subkop {
  text-align: center; margin: 12px 0 0;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-tekst);
}
.ml-overzicht__actie { margin: 48px 0 0; text-align: center; }

.ml-overzicht__kaarten { margin-top: 56px; }
/* De automatisch gevulde rij en de kolom van Plate krijgen hetzelfde
   raster, zodat een handmatige kaart er precies zo uitziet als een
   kaart die uit een case of bericht komt. */
.ml-overzicht__rij,
.ml-overzicht__kaarten .plate--column {
  display: grid; gap: 40px 24px;
  grid-template-columns: 1fr;
  align-items: start;      /* kaarten mogen ongelijk hoog zijn */
}
@media (min-width: 640px) {
  .ml-overzicht__rij,
  .ml-overzicht__kaarten .plate--column { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 960px) {
  .ml-overzicht__rij,
  .ml-overzicht__kaarten .plate--column { grid-template-columns: repeat(3, 1fr); }
}

.ml-kaart { display: grid; gap: 10px; text-decoration: none; }
.ml-kaart__beeld { display: block; position: relative; margin-bottom: 6px; }
.ml-kaart__beeld img { width: 100%; height: auto; display: block; }
/* Het label boven een kaart: op een case de schoolnaam, op een bericht
   de rubriek. Blauw, zoals op de live site. */
.ml-kaart__label {
  font-size: var(--ml-micro); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--ml-blauw);
}
/* Op een gekleurd vlak zou blauw wegvallen, daar volgt het label de tekst. */
.ml-vlak--blauw .ml-kaart__label,
.ml-vlak--groen .ml-kaart__label,
.ml-vlak--zwart .ml-kaart__label { color: inherit; }
.ml-kaart__titel {
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-tekst); line-height: var(--ml-lh-tekst);
  letter-spacing: normal;
}
a.ml-kaart .ml-kaart__beeld img { transition: scale 0.5s var(--ml-ease); }
a.ml-kaart:hover .ml-kaart__beeld img { scale: 1.02; }
.ml-kaart__beeld { overflow: hidden; }

/* Het prikbord: elk briefje hangt met een stukje plakband. Puur
   decoratie, dus het staat in de CSS en niet in de inhoud. Daar zat bij
   het overnemen van de live site eerder de fout: het plakbandje kwam als
   kaartbeeld mee, want het ligt in de HTML vóór het echte beeld.

   Opgemeten op de live site, en op 1512 en 390 gelijk: het plaatje is
   150 × 150 en hangt 75 px boven de bovenrand van het beeld, zodat de
   strook precies op die rand ligt. Het bestand is 300 × 301 met de
   strook in het midden en de scheve hoek er al in getekend, dus
   vierkant tonen en niet zelf draaien. Hier stond eerder een verhouding
   van 300/160 met 16 px overlap; dan wordt de strook platgedrukt tot een
   postzegeltje middenin het beeld.

   Drie plekken, één vorm: de kaarten in een prikbordoverzicht, de
   kaarten op de overzichtspagina zelf, en het eerste beeld van een
   artikel. */
.ml-overzicht--prikbord .ml-kaart__beeld,
body.article .ml-lijst .ml-kaart__beeld { overflow: visible; }
body.article .ml-vrij .plate--element__ml_beeld .ml-beeld { position: relative; }
.ml-overzicht--prikbord .ml-kaart__beeld::before,
body.article .ml-lijst .ml-kaart__beeld::before,
body.article .ml-vrij .plate--element__ml_beeld:first-child .ml-beeld::before {
  content: "";
  position: absolute; z-index: 1;
  top: -75px; left: 50%; translate: -50% 0;
  width: 150px; aspect-ratio: 1;
  background: url("../img/plakband.png") center / contain no-repeat;
}
.ml-overzicht--prikbord .ml-kaart__beeld img,
body.article .ml-lijst .ml-kaart__beeld img,
body.article .ml-vrij .plate--element__ml_beeld img { position: relative; }


/* ================================== hulpelementen van de editor */
/* Plate hangt in de editor een eigen element in elke kolom, de knop om
   iets toe te voegen. In een raster pakt dat gewoon een cel: dan staat
   de eerste dienst niet linksboven maar één plek verderop, en schuift de
   hele lijst op. Precies dat gebeurde in de dienstenlijst.
   
   Het is ook geen bug die je op de gepubliceerde site ziet, alleen in de
   editor, dus hij glipt er makkelijk doorheen.

   Oplossing: alles wat geen .plate--element is, gaat uit de stroom. Het
   blijft staan en blijft aanklikbaar, maar het telt niet meer mee in het
   raster. */
.ml-hulp__inhoud .plate--column,
.ml-diensten__lijst .plate--column,
.ml-cijfers__raster .plate--column,
.ml-overzicht__kaarten .plate--column,
.ml-quotes__stapel .plate--column { position: relative; }

.ml-hulp__inhoud .plate--column > :not(.plate--element),
.ml-diensten__lijst .plate--column > :not(.plate--element),
.ml-cijfers__raster .plate--column > :not(.plate--element),
.ml-overzicht__kaarten .plate--column > :not(.plate--element),
.ml-quotes__stapel .plate--column > :not(.plate--element) {
  position: absolute;
  top: 0; left: 0;
}

/* ===================================================== vrije secties */
/* De bouwstenen waarmee een contentbeheerder zelf een pagina samenstelt.
   De vrijheid zit in wat je plaatst en in welke volgorde; de maten,
   kleuren en afstanden komen uit dezelfde tokens als de ontworpen
   secties, dus je kunt er niet buiten stappen. */

/* De rijen en kolommen van Plate. Zonder deze regels staan kolommen
   onder elkaar in plaats van naast elkaar. */
/* De vrije sectie laat het kolommenstelsel van Plate zijn werk doen.

   Plate geeft elke kolom een `data-plate-col-xs/sm/md/lg` en zet daar
   zelf de breedte op, per breekpunt. Dat is precies wat de redactie in de
   editor versleept. Zet je daar een eigen `flex` of `max-width` overheen,
   dan staan de kolommen vast en doet slepen niets meer. Dat was hier even
   het geval en dat is teruggedraaid.

   De breedte is ook niet via de API te zetten: `grid`, `col_lg`, `columns`
   en `width` worden allemaal genegeerd, Plate kiest zelf. Nieuwe rijen
   komen er dus scheef in en worden in de editor rechtgetrokken. */
.ml-vrij .plate--row { row-gap: 24px; }
.ml-vrij .plate--element + .plate--element { margin-top: 24px; }

/* Plate werkt met een drietrap: de container krijgt 15 binnenruimte, de
   rij haalt die er met een negatieve marge weer af, en elke kolom zet 15
   terug. Samen levert dat een goot van 30 tussen de kolommen en een
   nette buitenrand.

   Binnen onze eigen container is die buitenste 15 dubbelop. Alle drie de
   stappen moeten dan mee, anders steekt de rij 30 buiten de pagina: dat
   gebeurde toen ik alleen de containerpadding weghaalde. De goot tussen
   de kolommen blijft, de buitenste kolommen staan weer op de rasterlijn. */
/* En Plate's container heeft zelf ook nog een max-width van 1200. Binnen
   onze container van 1372 kapt dat de inhoud af en zet het hem gecentreerd
   op 156, dus naast de rasterlijn. */
.ml-vrij__inhoud > .plate--container { padding-inline: 0; max-width: none; }
.ml-vrij .plate--row { margin-inline: 0; }
/* Een kolom mag kleiner worden dan zijn inhoud. Zonder dit duwt een breed
   element, zoals het gele kaartje, een smalle kolom open en krijgt de hele
   pagina een horizontale schuifbalk. De inhoud wordt dan krap, maar dat is
   een zichtbaar signaal om de kolom breder te slepen; een pagina die opzij
   schuift is dat niet. */
.ml-vrij .plate--column { min-width: 0; }
/* Een kolom met een negatieve breedte is rommel: die ontstaat als Plate
   bij het aanmaken via de API niet uitkomt op twaalf. Hij neemt geen
   ruimte in, zodat hij de rij niet laat afbreken, maar blijft in de
   editor zichtbaar zodat hij weggehaald kan worden. */
.ml-vrij .plate--column[data-plate-col-lg^="-"] { flex: 0 0 0; padding: 0; }
[data-editor="true"] .ml-vrij .plate--column[data-plate-col-lg^="-"] { flex: 0 0 40px; opacity: 0.4; }
.ml-vrij .plate--row > .plate--column:first-child { padding-left: 0; }
.ml-vrij .plate--row > .plate--column:last-child { padding-right: 0; }

/* Ruimte boven en onder een sectie, in vier stappen. */
.ml-boven--geen    { padding-top: 0; }
.ml-boven--klein   { padding-top: clamp(24px, 3vw, 40px); }
.ml-boven--normaal { padding-top: var(--ml-sectie-y); }
.ml-boven--groot   { padding-top: calc(var(--ml-sectie-y) * 1.8); }
.ml-onder--geen    { padding-bottom: 0; }
.ml-onder--klein   { padding-bottom: clamp(24px, 3vw, 40px); }
.ml-onder--normaal { padding-bottom: var(--ml-sectie-y); }
.ml-onder--groot   { padding-bottom: calc(var(--ml-sectie-y) * 1.8); }

/* ---- losse koppen ---- */
.ml-kop { margin: 0; letter-spacing: normal; font-family: var(--ml-font-kop); }
.ml-kop--maat-display { font-size: var(--ml-display); line-height: var(--ml-lh-display); font-weight: 600; }
.ml-kop--maat-xl      { font-size: var(--ml-kop-xl);  line-height: 1;    font-weight: 700; }
.ml-kop--maat-l       { font-size: var(--ml-kop-l);   line-height: 1;    font-weight: 700; }
.ml-kop--maat-m       { font-size: var(--ml-kop-m);   line-height: var(--ml-lh-kop);   font-weight: 700; }
.ml-kop--maat-s       { font-size: var(--ml-kop-s);   line-height: var(--ml-lh-kop-s); font-weight: 700; }
/* Twee kleine maten uit fase 2: de tussenkop boven een item in een
   raster, en het labelwoord boven een blok ("Het resultaat"). */
.ml-kop--maat-xs      { font-size: var(--ml-lead);    line-height: 1.25; font-weight: 700; }
/* Het blauwe labeltje boven een blok op een dienstpagina, zoals
   "Wat we doen:". Opgemeten op de live site: Inter bold op 18/23 met de
   tekst-tracking. Dus in het tekstlettertype en niet in het
   koplettertype. Stond hier op 14, en dat viel weg naast de tekst
   eronder. Op verzoek van Jeroen staat hij op 20, gelijk aan de lopende
   tekst, en dus net iets groter dan de 18 van de live site. */
.ml-kop--maat-label   { font-size: var(--ml-tekst); line-height: 1.3; font-weight: 700;
                        font-family: var(--ml-font-tekst); letter-spacing: var(--ml-ls-tekst); }

/* ---- losse tekstblokken ---- */
.ml-tekstblok { max-width: 62ch; }
.ml-tekstblok.ml-grote-tekst { max-width: 26ch; }
.ml-lijn--midden { text-align: center; margin-inline: auto; }
.ml-lijn--rechts { text-align: right; margin-inline-start: auto; }

/* ---- losse knop ---- */
.ml-knopblok { margin: 0; }

/* ---- los beeld ---- */
.ml-beeld { margin: 0; }
.ml-beeld img { width: 100%; height: auto; display: block; }
.ml-beeld--16-9 img { aspect-ratio: 16 / 9; object-fit: cover; }
.ml-beeld--4-3  img { aspect-ratio: 4 / 3;  object-fit: cover; }
.ml-beeld--1-1  img { aspect-ratio: 1 / 1;  object-fit: cover; }
.ml-beeld--3-4  img { aspect-ratio: 3 / 4;  object-fit: cover; }
/* Opgemeten op Over ons: 338 bij 428, net iets voller dan 3:4. */
.ml-beeld--staand img { aspect-ratio: 338 / 428; object-fit: cover; }
.ml-beeld__bijschrift { margin-top: 10px; font-size: var(--ml-label); }

/* ---- lege ruimte ---- */
.ml-ruimte--klein   { height: 24px; }
.ml-ruimte--normaal { height: 48px; }
.ml-ruimte--groot   { height: 96px; }

/* ===================================================== niet gevonden */
/* Een 404 is een doodlopend eind. Hij mag er daarom uitzien als een
   gewone pagina van het merk, met een weg terug in plaats van alleen een
   foutmelding. De knoppen staan naast elkaar en vallen onder elkaar als
   er geen ruimte is. */

.ml-niet-gevonden { padding-block: 100px 120px; }
.ml-niet-gevonden__kop { max-width: 14ch; margin: 0 0 32px; }
.ml-niet-gevonden__tekst { max-width: 46ch; font-size: var(--ml-lead); font-weight: 700; }
.ml-niet-gevonden__links {
  display: flex; flex-wrap: wrap; gap: 16px;
  list-style: none; margin: 48px 0 0; padding: 0;
}
/* Op blauw is de omlijnde knop wit, anders valt hij weg. */
.ml-vlak--blauw .ml-knop--rand { color: var(--ml-wit); }
.ml-vlak--blauw .ml-knop--rand:hover { background: var(--ml-wit); color: var(--ml-blauw); }

@media (max-width: 809.98px) {
  .ml-niet-gevonden { padding-block: 56px 72px; }
  .ml-niet-gevonden__links { flex-direction: column; align-items: flex-start; }
}


/* ================================================ half gekleurd vlak */
/* Sommige blokken liggen in het ontwerp op de grens tussen twee vlakken:
   bij de cijferblokken is de bovenste helft van de sectie grijs, bij het
   aandachtsblok de onderste. Daardoor lijkt het blok over de scheiding
   heen te steken.

   Dat is één achtergrond met een harde overgang op de helft, geen twee
   secties achter elkaar. Dat scheelt de redactie een lege sectie die ze
   per ongeluk kan verplaatsen, en de grens blijft altijd precies in het
   midden staan, ook als het blok van hoogte verandert. */
.ml-half--boven {
  background-image: linear-gradient(
    to bottom,
    var(--ml-half-kleur, var(--ml-grijs)) 0 50%,
    transparent 50% 100%);
}
.ml-half--onder {
  background-image: linear-gradient(
    to bottom,
    transparent 0 50%,
    var(--ml-half-kleur, var(--ml-grijs)) 50% 100%);
}

.ml-half-kleur--wit        { --ml-half-kleur: var(--ml-wit); }
.ml-half-kleur--grijs      { --ml-half-kleur: var(--ml-grijs); }
.ml-half-kleur--abrikoos   { --ml-half-kleur: var(--ml-abrikoos); }
.ml-half-kleur--geel       { --ml-half-kleur: var(--ml-geel); }
.ml-half-kleur--groen      { --ml-half-kleur: var(--ml-groen); }
.ml-half-kleur--lichtblauw { --ml-half-kleur: var(--ml-lichtblauw); }
.ml-half-kleur--oranje     { --ml-half-kleur: var(--ml-oranje); }
.ml-half-kleur--blauw      { --ml-half-kleur: var(--ml-blauw); }
.ml-half-kleur--zwart      { --ml-half-kleur: var(--ml-zwart); }


/* ================================================= overzichtspagina's */
/* De lijst met alle cases of alle berichten. Dezelfde kaarten als in de
   uitgelichte blokken op de home, zodat een bezoeker hetzelfde ziet op
   de plek waar hij doorklikt. */

/* Het overzicht is geen raster maar een kolomopmaak, zoals een krant.
   In een raster liggen de rijen vast: staat er een lage kaart naast een
   hoge, dan blijft daar een gat staan tot de volgende rij begint. Op de
   live site schuiven de kaarten gewoon door, en de volgorde loopt per
   kolom naar beneden: de eerste drie onder elkaar links, de volgende
   drie in het midden. Dat is precies wat CSS-kolommen doen.

   Niet van toepassing op de uitgelichte blokken op de home: daar staan
   er drie naast elkaar en is een raster juist wel goed. */
/* Masonry die van links naar rechts leest: het nieuwste bericht staat
   linksboven, daarna naar rechts, en pas daarna een rij lager. Dat is
   iets anders dan CSS-kolommen, want die vullen eerst de linkerkolom
   helemaal en lezen dus van boven naar beneden.

   De truc: een raster met heel lage rijen, waarbij elke kaart over zoveel
   rijen spant als hij hoog is. Het script meet dat op. Zonder script
   staat elke kaart op dezelfde spanne en zie je een gewoon raster, dus
   er valt niets weg. */
.ml-lijst__kaarten {
  display: grid;
  grid-template-columns: 1fr;
  grid-auto-rows: 8px;
  grid-auto-flow: row dense;
  column-gap: 24px;
}
.ml-lijst__kaarten .ml-kaart {
  align-self: start;
  grid-row-end: span var(--ml-spanne, 70);
  margin-bottom: 48px;
}
/* Zonder script is er niets gemeten; dan is een gewoon raster beter dan
   een masonry met gokhoogtes. */
html:not(.js) .ml-lijst__kaarten { grid-auto-rows: auto; }
html:not(.js) .ml-lijst__kaarten .ml-kaart { grid-row-end: auto; }
/* .ml-kaart is zelf een grid, en dat wint het van de browserregel voor
   het hidden-attribuut. Zonder deze regel blijft een weggefilterde kaart
   gewoon staan. */
.ml-lijst__kaarten .ml-kaart[hidden] { display: none; }

@media (min-width: 640px) { .ml-lijst__kaarten { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .ml-lijst__kaarten { grid-template-columns: repeat(3, 1fr); } }

.ml-paginering {
  display: flex; flex-wrap: wrap; gap: 12px 24px;
  align-items: center; justify-content: center;
  margin-top: 72px;
  font-size: var(--ml-ui); font-weight: 700;
}
.ml-paginering__lijst { display: flex; gap: 4px; list-style: none; margin: 0; padding: 0; }
.ml-paginering a, .ml-paginering__nu {
  display: grid; place-items: center;
  min-width: 44px; min-height: 44px; padding: 0 10px;
  border-radius: var(--ml-radius);
  text-decoration: none;
}
.ml-paginering a:hover { background: var(--ml-grijs); }
.ml-paginering__nu { background: var(--ml-zwart); color: var(--ml-wit); }
.ml-paginering__stap { padding-inline: 20px; box-shadow: inset 0 0 0 1px currentColor; }

/* ------------------------------------------- uit de designcheck, okt 2026 */

/* Compacte paginakop voor subpagina's. Op de live site staat de titel daar
   in de merkkleur op wit, met de ondertitel er direct onder in plaats van
   210 pixels lager. De hoge variant blijft die van de homepage. */
.ml-header--compact .ml-header__koppen { margin-bottom: 32px; }
.ml-header--compact { padding-block: 25px 100px; }
/* Staat er niets onder de kop, zoals op Over ons, dan hoort die honderd
   pixels er niet. Op de live site volgt het eerste blok daar vrijwel
   meteen op de kop; de ruimte eronder is voor de ondertitel, de labels
   en de knop. Zijn die er niet, dan sluit de pagina aan. */
.ml-header--compact:not(:has(.ml-header__onder > *)) { padding-bottom: 20px; }
.ml-header--compact:not(:has(.ml-header__onder > *)) .ml-header__koppen { margin-bottom: 0; }
.ml-header--compact .ml-header__onder { justify-content: flex-start; gap: 1.5rem 2rem; }
.ml-header--compact .ml-header__tekst { max-width: 56ch; font-size: var(--ml-tekst); font-weight: 400; }
/* Op een licht vlak is de kop blauw, zoals op de live site; op een donker
   vlak blijft hij wit. De tweede regel houdt zijn eigen accentkleur. */
.ml-header--compact .ml-header__kop:first-child { color: var(--ml-blauw); }
.ml-header--compact.ml-vlak--blauw .ml-header__kop:first-child,
.ml-header--compact.ml-vlak--zwart .ml-header__kop:first-child,
.ml-header--compact.ml-vlak--groen .ml-header__kop:first-child,
.ml-header--compact.ml-vlak--oranje .ml-header__kop:first-child { color: var(--ml-wit); }

/* Een vraagsectie zonder kop, tekst en knop hoort geen ruimte in te nemen.
   Verwijderen doet de tooling niet, dus een leeg blok vouwt zichzelf op.
   In de editor blijft hij zichtbaar, anders kan de redactie hem niet
   aanklikken om hem weg te halen. */
.ml-vraag--leeg { display: none; }
[data-editor="true"] .ml-vraag--leeg { display: block; opacity: 0.4; }

@media (max-width: 809.98px) {
  .ml-header--compact { padding-block: 15px 56px; }
  .ml-header--compact .ml-header__koppen { margin-bottom: 24px; }
}

/* De cijferblokken als gewone rij in plaats van de trapvorm van de home.
   De compositie is op maat gemaakt voor vier getallen van twee of drie
   tekens; een prijs als "6.450,-" liep daar buiten zijn vak. */
.ml-cijfers--rij .ml-cijfers__raster .plate--column {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  grid-template-rows: auto;
  grid-auto-rows: auto;
}
@supports selector(:nth-child(1 of .plate--element)) {
  .ml-cijfers--rij .ml-cijfers__raster :nth-child(n of .plate--element) {
    grid-column: auto; grid-row: auto; z-index: auto;
  }
  @media (min-width: 810px) {
    .ml-cijfers--rij .ml-cijfers__raster :nth-child(n of .plate--element) .ml-cijfer__getal {
      font-size: var(--ml-kop-xl);
    }
  }
}
.ml-cijfers--rij .ml-cijfer { min-height: 236px; }


/* ------------------------------------------------- filters en meer laden */
/* De overzichten van cases en het prikbord filteren in de browser. De
   knoppenrij staat boven de kaarten, "Alles" voorop. */

.ml-filter {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 0;
}
/* Gemeten op de live site: 40 hoog, zwarte tekst in een dun kadertje,
   de actieve knop gevuld in het merkzwart. Niet blauw: blauw is daar de
   kleur van de koppen en van een linkje, niet van een keuzeknop. */
.ml-filter__knop {
  appearance: none; cursor: pointer;
  min-height: 40px; padding: 8px 18px;
  border: 0; border-radius: var(--ml-radius);
  background: transparent; color: var(--ml-ink);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 30%, transparent);
  font-family: inherit; font-size: var(--ml-label); font-weight: 700;
  line-height: 1.3;
  transition: background var(--ml-duur) var(--ml-ease), color var(--ml-duur) var(--ml-ease),
              box-shadow var(--ml-duur) var(--ml-ease);
}
.ml-filter__knop:hover { box-shadow: inset 0 0 0 1px currentColor; }
.ml-filter__knop.is-aan {
  background: var(--ml-zwart); color: var(--ml-wit);
  box-shadow: none;
}

/* Gemeten op de live site: de eerste kaart begint 90 onder de knoppen. */
.ml-lijst__kaarten { margin-top: 90px; }
.ml-lijst__meer { margin: 56px 0 0; text-align: center; }
.ml-lijst__leeg { margin: 56px 0 0; text-align: center; opacity: 0.7; }

/* ---------------------------------------- de kop van een overzichtspagina

   Op de live site staat daar de titel links en de inleiding rechts op
   dezelfde hoogte, met de filterknoppen er vlak onder: titel tot 938,
   inleiding van 1008 tot 1442, knoppen 30 onder de titel. Bij ons stond
   de inleiding eronder en zat er 240 ruimte tussen de kop en de knoppen,
   wat een gat van een halve schermhoogte gaf.

   Alleen op een overzichtspagina, want een dienstpagina zet de ondertitel
   op de live site juist wél onder de titel. Vandaar de voorwaarde op de
   aanwezigheid van een lijst. */
body:has(.ml-lijst) .ml-header--compact { padding-bottom: 30px; }
body:has(.ml-lijst) .ml-lijst { padding-top: 0; }

@media (min-width: 1200px) {
  body:has(.ml-lijst) .ml-header--compact .ml-header__inner {
    display: grid;
    /* Gemeten op de live site: de inleiding loopt van 1008 tot 1442 binnen
       een container van 70 tot 1442, dus 434 breed. Met 441 brak de tekst
       net een woord later af dan in het ontwerp. */
    grid-template-columns: minmax(0, 913fr) 434fr;
    column-gap: 25px;
    /* Onderlangs uitlijnen, niet bovenlangs. Op de live site eindigen de
       titel en de inleiding allebei op dezelfde hoogte: beide op 335 bij
       een venster van 1512. De inleiding zakt dus mee met het aantal
       regels van de titel. */
    align-items: end;
  }
  body:has(.ml-lijst) .ml-header--compact .ml-header__koppen { margin-bottom: 0; }
  /* In de hoge kop staan hier een knop en een tekst naast elkaar, dus is
     dit een flexrij. Op een overzichtspagina staat er alleen tekst in, en
     die rij gaf de tekst twintig pixels speling onder zijn eigen vak.
     Een gewoon blok sluit wel precies aan. */
  body:has(.ml-lijst) .ml-header--compact .ml-header__onder { display: block; }
  /* wat de redactie zelf in de kop zet, loopt over de volle breedte */
  body:has(.ml-lijst) .ml-header--compact .ml-header__inner > .plate--container { grid-column: 1 / -1; }
}

@media (max-width: 809.98px) {
  .ml-lijst__kaarten { margin-top: 40px; }
}

/* Een vrije sectie zonder elementen laat anders een gat van 240 pixels
   vallen. Dat gebeurt vanzelf: Plate hangt bij elke nieuwe pagina een
   lege body-sectie aan, en verwijderen doet de tooling niet. In de
   editor blijft hij staan, anders kan de redactie hem niet aanklikken. */
.ml-vrij:not(:has(.plate--element)) { display: none; }
[data-editor="true"] .ml-vrij:not(:has(.plate--element)) { display: block; opacity: 0.4; }

/* ------------------------------------------------- een artikel leest smal

   Gemeten op de live site bij 1512, binnen een container van 70 tot 1442:

     titel en hoofdbeeld   303 tot 1209   = 906 breed, gecentreerd
     lopende tekst         421 tot 1091   = 670 breed, gecentreerd
     kaarten onderaan      70 tot 1442    = de volle 1372

   Drie breedtes dus, en de middelste is de leeskolom. Bij ons liep alles
   nog op de volle breedte mee, waardoor de regels veel te lang werden.
   Plate zet de post-soort als klasse op de body, vandaar `body.article`. */

body.article .ml-header--compact .ml-header__koppen,
body.article .ml-header--compact .ml-header__onder {
  max-width: 906px;
  margin-inline: auto;
}
/* De titel van een artikel staat op 80, niet op de displaymaat van 120.
   En zonder automatische afbreking: dat vangnet is er voor de kop van 120
   op een telefoon, waar "onderwijsmerken" anders niet past. Op 80 in een
   kolom van 906 is er ruimte zat en brak hij "campagne" nodeloos af. */
/* De titel van een artikel staat kleiner dan een gewone paginakop: op de
   live site 80/80 tegen 120/114, en op een telefoon 42/40 tegen 62/59.
   Niet op het prikbordoverzicht zelf: dat is een gewone paginakop en
   staat live ook op 120. Plate zet daar `is-overzicht` op de body, en de
   soort `article` staat er allebei op. */
body.article:not(.is-overzicht) .ml-header__kop { font-size: var(--ml-kop-xl); line-height: 1; hyphens: manual; }

/* Op desktop staat zo'n kop op 80/80, op de telefoon op 42/40. Deze
   mediaregel moet ná de regels staan die hierboven en eerder in het
   bestand regelafstand 1 zetten, anders verliest hij het op volgorde.
   Dat is dezelfde val als bij de artikelmarges. */
@media (max-width: 809.98px) {
  /* Op 30 hoort de ruimere regelafstand van de andere koppen van die maat
     (30/33); alleen de kop in de header staat op 42 en blijft strak. */
  .ml-overzicht__kop,
  .ml-kop--maat-xl { line-height: var(--ml-lh-kop); }
  body.article:not(.is-overzicht) .ml-header__kop { line-height: 0.95; }

  /* De gekleurde balken pasten niet op een telefoon: de pagina kreeg een
     horizontale schuifbalk van 42 px. Twee oorzaken.

     Eén: een rasteritem mag standaard niet smaller worden dan zijn eigen
     inhoud (`min-width: auto`). De balk met zijn gat van 82 px duwde de
     hele kolom breder dan het scherm, en omdat .ml-hulp__inhoud zelf ook
     een rasteritem is, kon die niet terugveren. Vandaar min-width: 0 op
     de hele keten.

     Twee: dat gat van 82 px en een icoon van 126 px laten op 350 px breed
     niets over voor de tekst. Op een telefoon dus kleiner.

     De tekst in de balk staat op 20, even groot als de tekst eronder. */
  .ml-hulp__inhoud,
  .ml-hulp__inhoud .plate--column,
  .ml-hulp__inhoud .plate--element { min-width: 0; }
  .ml-balk {
    gap: 14px;
    padding: 16px;
    min-height: 0;
    font-size: var(--ml-tekst); line-height: var(--ml-lh-tekst);
  }
  /* Icoon en pijl zo klein als nog netjes is, zodat de tekstkolom rond de
     200 px houdt. Met het icoon op 126 bleef er 148 over en liep één zin
     over zes regels. */
  .ml-balk__icoon { width: 56px; height: 56px; }
  .ml-balk__tekst { min-width: 0; }
  .ml-balk__pijl { flex: none; width: 32px; height: 32px; }

  /* 42 is op een telefoon het plafond en is voor de kop in de header.
     De titel van een artikel is ook zo'n kop, dus die houdt 42 terwijl
     --ml-kop-xl voor de sectiekoppen naar 30 zakt. */
  body.article:not(.is-overzicht) .ml-header__kop { font-size: var(--ml-display); }
}

body.article .ml-vrij .plate--element { max-width: 906px; margin-inline: auto; }
body.article .ml-vrij .ml-tekstblok { max-width: 670px; margin-inline: auto; }

/* De ruimte rond het eerste beeld van een artikel. Opgemeten op de live
   site: 90 px tussen de metaregel en het beeld, en 100 px van het beeld
   naar de lopende tekst. Op een telefoon allebei 50. Let op bij het
   nameten: Framer schuift het beeld 40 px omlaag zodra het plakbandje
   erboven is ingeladen, dus meet pas een paar seconden na het laden. Bij ons stapelden de onderruimte van de kop (100)
   en de bovenruimte van de artikelsectie (100) tot 200 px, terwijl het
   beeld er onderaan met 24 px tegenaan plakte. Hetzelfde euvel als op een
   case: twee blokken die allebei hun eigen ruimte meebrengen.

   De sectie laat zijn bovenruimte vallen zodra het eerste element een
   beeld is; de 90 px komt dan van de kop. Begint het artikel met tekst,
   dan blijft alles zoals het was. `.ml-beeld img` en niet `.ml-beeld`,
   want een leeg beeldelement telt niet mee. */
body.article:has(.ml-vrij .plate--row:first-child .plate--column:first-child > .plate--element:first-child .ml-beeld img) .ml-header--compact { padding-bottom: 90px; }
body.article .ml-vrij:has(.plate--row:first-child .plate--column:first-child > .plate--element:first-child .ml-beeld img) { padding-top: 0; }
body.article .ml-vrij .plate--column > .plate--element:first-child:has(.ml-beeld img) + .plate--element { margin-top: 100px; }
/* Op een telefoon is het boven en onder het beeld 50. Deze mediaregels
   staan hier en niet bij de andere telefoonregels hoger in het bestand,
   want die komen eerder en zouden het van de regels hierboven verliezen. */
@media (max-width: 809.98px) {
  body.article:has(.ml-vrij .plate--row:first-child .plate--column:first-child > .plate--element:first-child .ml-beeld img) .ml-header--compact { padding-bottom: 50px; }
  body.article .ml-vrij .plate--column > .plate--element:first-child:has(.ml-beeld img) + .plate--element { margin-top: 50px; }
}

/* De regel onder de titel: label klein erboven, waarde eronder. */
.ml-artikelmeta { display: flex; flex-wrap: wrap; gap: 12px 64px; }
.ml-artikelmeta > span { display: grid; gap: 2px; font-size: var(--ml-label); font-weight: 700; }
.ml-artikelmeta > span > span { font-weight: 400; opacity: 0.6; }

@media (max-width: 959.98px) {
  body.article .ml-header--compact .ml-header__koppen,
  body.article .ml-header--compact .ml-header__onder,
  body.article .ml-vrij .plate--element,
  body.article .ml-vrij .ml-tekstblok { max-width: none; }
}

/* ------------------------------------------- het gescheurde resultaatkaartje

   De vorm komt uit een PNG met gekartelde randen. Voor geel, de kleur uit
   het ontwerp, gebruiken we het plaatje zelf: daar zit de donkere omlijning
   al in. Voor een andere kleur dient hetzelfde plaatje als masker over een
   vlak in die kleur; dan vervalt de omlijning, maar de vorm klopt.

   De tekst ligt eroverheen en komt uit het CMS. De randen van de vorm
   lopen een stukje naar binnen, vandaar de royale binnenruimte. */

.ml-resultaat { position: relative; }
.ml-resultaat--geel {
  background: url("../img/kaart-gescheurd.png") center / 100% 100% no-repeat;
}
.ml-resultaat--abrikoos,
.ml-resultaat--groen,
.ml-resultaat--lichtblauw,
.ml-resultaat--wit {
  -webkit-mask: url("../img/kaart-gescheurd.png") center / 100% 100% no-repeat;
          mask: url("../img/kaart-gescheurd.png") center / 100% 100% no-repeat;
}
.ml-resultaat--abrikoos   { background-color: var(--ml-abrikoos); }
.ml-resultaat--groen      { background-color: var(--ml-groen); }
.ml-resultaat--lichtblauw { background-color: var(--ml-lichtblauw); }
.ml-resultaat--wit        { background-color: var(--ml-wit); }

.ml-resultaat__inhoud {
  display: grid; gap: 24px;
  /* ruim, want de gekartelde rand loopt aan alle kanten naar binnen */
  padding: 56px 48px 64px;
  color: var(--ml-zwart);
}
.ml-resultaat__kop {
  margin: 0;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-m); line-height: 1.05;
  letter-spacing: normal;
}
.ml-resultaat__tekst { font-size: var(--ml-tekst); line-height: 1.6; }
.ml-resultaat__tekst p { margin: 0; }
.ml-resultaat__tekst p + p { margin-top: 0.8em; }

.ml-resultaat__paren {
  display: flex; flex-wrap: wrap; gap: 16px 32px;
  margin: 8px 0 0;
}
.ml-resultaat__paren > div { display: grid; gap: 2px; }
.ml-resultaat__paren dt { font-size: var(--ml-label); font-weight: 700; }
.ml-resultaat__paren dd {
  margin: 0;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-s); line-height: 1.1;
}

/* De getekende pijl die in het ontwerp naar het kaartje wijst. Decoratie,
   dus verborgen voor voorleessoftware en weg op een smal scherm. */
.ml-resultaat::before {
  content: "";
  position: absolute; right: calc(100% + 8px); bottom: 34%;
  width: 134px; aspect-ratio: 268 / 175;
  background: url("../img/pijl-schuin.png") center / contain no-repeat;
  pointer-events: none;
}
@media (max-width: 1199.98px) {
  .ml-resultaat::before { display: none; }
}
@media (max-width: 809.98px) {
  .ml-resultaat__inhoud { padding: 44px 32px 52px; gap: 18px; }
}

/* ------------------------------------------- gecentreerde kop met labels

   Het stramien van een dienstpagina in fase 2: titel gecentreerd op de
   displaymaat, daaronder de ondertitel en een rij labelpillen. De
   homepage houdt zijn linkse kop; vandaar de keuze op de sectie. */

.ml-header--midden { text-align: center; }
/* De tekst in de kop blijft binnen de tweede marge, de liniaal op 186,5.
   Een lange titel liep anders van rand tot rand en werd daarmee breder
   dan alles eronder. 1139 is de inhoudsmaat tussen die twee linialen. */
.ml-header--midden .ml-header__koppen,
.ml-header--midden .ml-header__onder,
.ml-header--midden .ml-header__labels { max-width: 1139px; margin-inline: auto; }
.ml-header--midden .ml-header__koppen { margin-bottom: 28px; }
.ml-header--midden .ml-header__onder { justify-content: center; }
.ml-header--midden .ml-header__tekst {
  max-width: 62ch; margin-inline: auto;
  font-size: var(--ml-tekst); font-weight: 400;
}

.ml-header__labels {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin: 24px 0 0; padding: 0;
  list-style: none;
}
.ml-header--midden .ml-header__labels { justify-content: center; }
.ml-header__labels li {
  /* Gemeten in het ontwerp: ongeveer 36 hoog, een dun kadertje en een
     volledig ronde vorm. Dezelfde maat als de filterknoppen. */
  min-height: 36px;
  display: inline-flex; align-items: center;
  padding: 6px 16px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 35%, transparent);
  font-size: var(--ml-label); font-weight: 700; line-height: 1.3;
}

@media (max-width: 809.98px) {
  .ml-header--midden .ml-header__koppen { margin-bottom: 20px; }
  .ml-header__labels { margin-top: 18px; }
}

/* Een vrije sectie over de volle breedte: Plate hangt er zelf nog een
   container omheen die op 1512 een inspringing van 171 aan weerszijden
   geeft. Voor een illustratieband die van rand tot rand moet lopen, zet
   die hier uit. */
.ml-vrij__inhoud--vol > .plate--container {
  max-width: none; width: 100%;
  margin: 0; padding: 0;
}
.ml-vrij__inhoud--vol .plate--row { margin: 0; gap: 0; }
.ml-vrij__inhoud--vol .plate--column { padding: 0; }
.ml-vrij__inhoud--vol .ml-beeld img { width: 100%; display: block; }

/* Een beeld over de volle breedte raakt de randen van het scherm; dan
   hoort het de blokken erboven en eronder ook te raken. Met de gewone
   sectieruimte van 100 boven en onder ontstaan er twee stroken wit om
   een beeld dat juist van rand tot rand moet lopen.

   De regel geldt alleen als er echt een beeld in de volle baan zit. Een
   volle baan met een gekleurd vlak en tekst erin houdt zijn ruimte, want
   daar leest de tekst anders tegen de rand aan. */
.ml-sectie:has(> .ml-vrij__inhoud--vol .ml-beeld) { padding-block: 0; }

/* Plate laat bij het bewerken makkelijk een lege rij achter: een rij met
   een kolom zonder inhoud. Die is onzichtbaar maar niet hoogteloos, want
   de kolom heeft binnenruimte. Onder een beeld over de volle breedte zag
   je dat meteen als een strook wit.

   Zo'n rij neemt nu geen ruimte meer. In de editor blijft hij wel staan,
   anders kun je er niets meer in zetten en lijkt de rij verdwenen. */
.ml-vrij .plate--row:not(:has(.plate--element > *)) { display: none; }
[data-editor="true"] .ml-vrij .plate--row:not(:has(.plate--element > *)) {
  display: flex;
  opacity: 0.4;
}

/* Gecentreerde lopende tekst houdt de leesbreedte van 670 aan, dezelfde
   kolom als een artikel. Zonder die grens liep de inleiding over de
   volle 1170 en werden de regels veel te lang. */
.ml-tekstblok.ml-lijn--midden { max-width: 670px; }

/* ------------------------------------------------- de uitdagingsbaan

   Gemeten in fase 2 bij 1512: de baan loopt van rand tot rand, de vraag
   links begint op 180 en is ongeveer 520 breed, de rechterkolom begint op
   886 en is 474 breed. Het kaartje steekt met zijn getekende rand een
   stukje buiten die kolom; dat doet de rand zelf, niet de opmaak. */

.ml-uitdaging { padding-block: 72px; }
.ml-uitdaging__inner { display: grid; gap: 32px; }

@media (min-width: 960px) {
  .ml-uitdaging__inner {
    /* De linialen uit het Figma-bestand: guide 2 op 70 is de gewone
       containermarge, links van het logo. Guide 1 op 186,5 ligt er net
       rechts van en is de inspringing van deze banen. Gespiegeld geeft
       dat een inhoud van 1139 breed, gecentreerd: 1512 - 2 x 186,5.

       Als max-width plus de containermarge genoteerd, zodat de maat
       meeschuift met het breekpunt in plaats van op 1512 vast te staan. */
    max-width: calc(1139px + 2 * var(--ml-marge));
    grid-template-columns: minmax(0, 521fr) 433fr;
    column-gap: 185px;
    align-items: start;
  }
}

.ml-uitdaging__vraag {
  margin: 0;
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-m); line-height: 1.2;
  letter-spacing: normal;
  max-width: 18ch;
}

.ml-uitdaging__rechts { display: grid; gap: 56px; }
.ml-uitdaging__label {
  margin: 0 0 8px;
  font-size: var(--ml-label); font-weight: 700;
}
.ml-uitdaging__tekst { font-size: var(--ml-tekst); font-weight: 700; line-height: 1.3; }
.ml-uitdaging__tekst p { margin: 0; }
.ml-uitdaging__tekst p + p { margin-top: 0.6em; }

/* Het kaartje: de getekende rand ligt eronder als vulling én omlijning,
   de tekst ligt eroverheen. Vandaar position relative en een kaartinhoud
   met eigen ruimte. */
.ml-uitdaging__kaart { position: relative; }
.ml-uitdaging__kaartinhoud { position: relative; padding: 20px 24px 24px; }

@media (max-width: 959.98px) {
  .ml-uitdaging { padding-block: 48px; }
  .ml-uitdaging__vraag { max-width: none; }
  .ml-uitdaging__rechts { gap: 32px; }
}

/* Een cijfersectie waarin geen enkel blok nog inhoud heeft, valt weg.
   Zelfde reden als bij de vrije sectie: verwijderen doet de tooling niet,
   dus een leeggemaakt blok moet zichzelf opvouwen. In de editor blijft
   hij staan, anders kan de redactie hem niet aanklikken. */
.ml-cijfers:not(:has(.ml-cijfer)) { display: none; }
[data-editor="true"] .ml-cijfers:not(:has(.ml-cijfer)) { display: block; opacity: 0.4; }

/* De breedtetrap van het ontwerp, binnen de container gemeten bij 1512:

     marge          70 tot 1442, inhoud 1372   de eerste liniaal
     tweede marge   186,5 tot 1325,5, inhoud 1139   de tweede liniaal
     smal           inhoud 890, zoals het ervaringsraster

   Genoteerd als de inhoudsbreedte plus twee keer de containermarge,
   zodat de maat meeschuift met het breekpunt. */
.ml-vrij__inhoud--tweede,
.ml-breedte--tweede { max-width: calc(1139px + 2 * var(--ml-marge)); }
/* De tekstkolom van de pagina Over ons: 670 breed, gecentreerd binnen de
   tweede marge. Opgemeten op de live site; alle lopende tekst daar staat
   op deze maat. */
.ml-vrij__inhoud--tekstkolom,
.ml-breedte--tekstkolom { max-width: calc(670px + 2 * var(--ml-marge)); }

.ml-vrij__inhoud--smal,
.ml-breedte--smal   { max-width: calc(890px + 2 * var(--ml-marge)); }

/* Een leeggemaakt tweekolomsblok valt weg, net als de andere secties die
   de tooling niet kan verwijderen. */
.ml-tweekolom--leeg { display: none; }
[data-editor="true"] .ml-tweekolom--leeg { display: block; opacity: 0.4; }

/* Een quotesectie zonder kaarten valt ook weg. */
.ml-quotes:not(:has(.ml-quote)) { display: none; }
[data-editor="true"] .ml-quotes:not(:has(.ml-quote)) { display: block; opacity: 0.4; }


/* Vangnet voor een onmogelijke kolomwaarde. Plate kiest de breedte zelf
   bij het aanmaken via de API en komt daar soms op uit buiten 1 tot 12,
   bijvoorbeeld 14 en -2 voor twee kolommen. Dan past geen enkele regel
   van Plate en vallen de kolommen over elkaar heen.

   De uitzonderingsreeks hieronder raakt alleen zo'n kolom: staat er wél
   een geldige waarde, dan blijft Plate de baas en werkt het verslepen in
   de editor gewoon. */
.ml-vrij .plate--column:not([data-plate-col-lg="1"]):not([data-plate-col-lg="2"]):not([data-plate-col-lg="3"]):not([data-plate-col-lg="4"]):not([data-plate-col-lg="5"]):not([data-plate-col-lg="6"]):not([data-plate-col-lg="7"]):not([data-plate-col-lg="8"]):not([data-plate-col-lg="9"]):not([data-plate-col-lg="10"]):not([data-plate-col-lg="11"]):not([data-plate-col-lg="12"]) {
  flex: 1 1 0;
  max-width: none;
}

/* Verticale uitlijning van de kolommen in een vrije sectie. Plate laat
   de kolommen standaard even hoog worden; met align-items bepaalt de
   redactie waar de inhoud dan komt te staan. */

/* ------------------------------------------------ kleinere leesmaten */
/* Opgemeten op Over ons: de lopende tekst staat daar op 18 met een
   regelhoogte van 23,4 in een kolom van 675, en de smalle rechterkolom
   op 16 met 20,8. De rest van de site houdt 20 op 26 aan, dus deze maten
   staan los en zijn een keuze, geen nieuwe standaard. De maatregel voor
   de regellengte hangt eraan vast: met de 62ch van het basisblok zou de
   kolom op 18 smaller uitvallen dan op de live site. */
/* De maatvarianten zetten wel hun lettergrootte vast, maar niet hun
   regelafstand: die volgt --ml-lh-tekst, zodat één plek de regelafstand
   van alle lopende tekst bepaalt. Stond hier eerder hard op 1.3, en toen
   veranderde Over ons niet mee met de verhoging naar 1.5. */
.ml-prose--18 { font-size: 18px; line-height: var(--ml-lh-tekst); max-width: 675px; }
.ml-prose--16 { font-size: 16px; line-height: var(--ml-lh-tekst); max-width: none; }

/* De tekstballon houdt de maat van het ontwerp: 448 breed, gecentreerd
   in de kolom waar hij in staat. Zonder die grens rekt hij mee met de
   kolom en wordt de ballon plat. */
.ml-ballon { max-width: 448px; margin-inline: auto; }

/* De dienstenlijst kan een eigen tekstkleur krijgen, los van het vlak.
   Hij zet ook --ml-op-vlak, want daar hangen de kop, de scheidingslijnen
   en de knoppen in deze sectie aan vast; zonder dat zou alleen de
   lopende tekst meekleuren en de rest achterblijven. */
.ml-diensten--tekst-zwart      { color: var(--ml-zwart);      --ml-op-vlak: var(--ml-zwart); }
.ml-diensten--tekst-wit        { color: var(--ml-wit);        --ml-op-vlak: var(--ml-wit); }
.ml-diensten--tekst-blauw      { color: var(--ml-blauw);      --ml-op-vlak: var(--ml-blauw); }
.ml-diensten--tekst-groen      { color: var(--ml-groen);      --ml-op-vlak: var(--ml-groen); }
.ml-diensten--tekst-oranje     { color: var(--ml-oranje);     --ml-op-vlak: var(--ml-oranje); }
.ml-diensten--tekst-geel       { color: var(--ml-geel);       --ml-op-vlak: var(--ml-geel); }
.ml-diensten--tekst-abrikoos   { color: var(--ml-abrikoos);   --ml-op-vlak: var(--ml-abrikoos); }
.ml-diensten--tekst-lichtblauw { color: var(--ml-lichtblauw); --ml-op-vlak: var(--ml-lichtblauw); }

/* De kop en de losse diensten erven het nu, ook waar ze eerder een vaste
   kleur hadden. */
.ml-diensten[class*="ml-diensten--tekst-"] .ml-diensten__kop,
.ml-diensten[class*="ml-diensten--tekst-"] .ml-dienst,
.ml-diensten[class*="ml-diensten--tekst-"] .ml-dienst a { color: inherit; }

/* De breedte van een tekstblok, als keuze op het element.
   Standaard geldt de leesmaat: 62 tekens, 26 bij grote tekst, en
   gecentreerd 670. Dat houdt een alinea leesbaar, maar een korte
   uitspraak in 42 pixels breekt daardoor veel te vroeg af. Deze klassen
   gaan daaroverheen, en ze moeten zwaarder wegen dan die drie regels,
   vandaar de dubbele klasse. */
.ml-tekstblok.ml-tekstbreed--tekstkolom { max-width: 670px; }
.ml-tekstblok.ml-tekstbreed--smal       { max-width: 890px; }
.ml-tekstblok.ml-tekstbreed--tweede     { max-width: 1139px; }
.ml-tekstblok.ml-tekstbreed--kolom      { max-width: none; }

/* Op een casekop staan de klantnaam links en de diensten als pillen
   rechts, op dezelfde regel. Opgemeten op de live site: de naam begint op
   70 en de rij pillen eindigt op 1442, dus allebei op de containerrand.
   Wordt het te krap, dan zakken de pillen onder de naam. */
body.case .ml-header__onder {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px 32px;
}
body.case .ml-header__tekst {
  font-weight: 700;
  font-size: var(--ml-tekst);
}
body.case .ml-header__labels {
  margin: 0;
  justify-content: flex-end;
}
@media (max-width: 809.98px) {
  body.case .ml-header__labels { justify-content: flex-start; }
}

/* ========================================================== formulier */
/* Het contactformulier uit het ontwerp: geen kaders om de velden, maar
   een handgetekende streep eronder. Die streep is een masker over de
   tekstkleur, dus hij is wit op een blauw vlak en zwart op een licht
   vlak, uit één bestand. Dezelfde truc als bij de pijl en de iconen.

   Het label staat boven het veld en blijft staan; een placeholder die
   verdwijnt zodra je typt laat mensen raden wat ze invulden. */
.ml-formulier__kop {
  margin: 0 0 48px;
  font-size: var(--ml-kop-m);
  line-height: 1.1;
  color: var(--ml-op-vlak, var(--ml-zwart));
}
.ml-formulier__form { display: flex; flex-direction: column; gap: 36px; }

.ml-veld { position: relative; display: block; }
.ml-veld__label {
  display: block;
  margin-bottom: 10px;
  font-size: var(--ml-tekst);
  color: var(--ml-op-vlak, var(--ml-zwart));
}
.ml-veld__invoer {
  width: 100%;
  padding: 0 0 10px;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--ml-tekst);
  color: var(--ml-op-vlak, var(--ml-zwart));
  border-radius: 0;
  appearance: none;
}
.ml-veld__invoer:focus { outline: none; }
.ml-veld__invoer--tekst { resize: vertical; min-height: 120px; }

/* De streep. Hij hoort bij het veld en niet bij het label, dus hij hangt
   onderaan het veldblok. */
.ml-veld::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 8px;
  background: var(--ml-op-vlak, var(--ml-zwart));
  -webkit-mask: url("../img/veldlijn.svg") 0 100% / 100% 8px no-repeat;
          mask: url("../img/veldlijn.svg") 0 100% / 100% 8px no-repeat;
  pointer-events: none;
}
/* Bij toetsenbordfocus wordt de streep dikker; dat is de enige plek waar
   je het ziet, want de velden hebben verder geen kader. */
.ml-veld:focus-within::after { height: 12px; -webkit-mask-size: 100% 12px; mask-size: 100% 12px; }
.ml-veld--vink::after, .ml-veld__val::after { content: none; }

.ml-veldrij { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; }

.ml-veld--vink { display: flex; align-items: flex-start; gap: 14px; }
.ml-veld--vink label { font-size: var(--ml-tekst); color: var(--ml-op-vlak, var(--ml-zwart)); }
.ml-veld__vink {
  flex: none;
  width: 22px; height: 22px;
  margin: 2px 0 0;
  border: 0;
  border-radius: 3px;
  background: var(--ml-op-vlak, var(--ml-zwart));
  appearance: none;
  cursor: pointer;
}
.ml-veld__vink:checked {
  background: var(--ml-op-vlak, var(--ml-zwart));
  box-shadow: inset 0 0 0 4px var(--ml-vlak-kleur, #fff);
}
.ml-veld__vink:focus-visible { outline: 2px solid var(--ml-op-vlak, var(--ml-zwart)); outline-offset: 3px; }

/* De spamval hoort nergens te staan, ook niet voor een schermlezer. */
.ml-veld__val { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.ml-formulier__klein {
  font-size: var(--ml-ui);
  color: var(--ml-op-vlak, var(--ml-zwart));
}
.ml-formulier__klein p { margin: 0; }
.ml-formulier__actie { margin: 8px 0 0; }
.ml-formulier__melding { color: var(--ml-op-vlak, var(--ml-zwart)); }

/* Op een licht vlak hoort de knop donker in plaats van wit. */
.ml-formulier.ml-vlak--wit .ml-knop--licht,
.ml-formulier.ml-vlak--grijs .ml-knop--licht,
.ml-formulier.ml-vlak--geel .ml-knop--licht,
.ml-formulier.ml-vlak--abrikoos .ml-knop--licht,
.ml-formulier.ml-vlak--lichtblauw .ml-knop--licht {
  background: var(--ml-zwart);
  color: var(--ml-wit);
}

@media (max-width: 809.98px) {
  .ml-veldrij { grid-template-columns: 1fr; }
  .ml-formulier__form { gap: 28px; }
}

/* ========================================================= casepagina */
/* Opgemeten op de live case van International School Utrecht, bij 1512:
   de inhoudskolom is 800 breed en staat midden, op x=356. Een los beeld
   vult die kolom; vierkante beelden staan twee naast elkaar, 388 bij 388,
   met 24 ertussen en 32 tussen de rijen.

   Het raster ontstaat vanzelf: de kolom is een grid van twee sporen,
   alles beslaat standaard allebei de sporen, en alleen een vierkant beeld
   beslaat er één. Zo hoeft de redactie niets in te delen en komt een
   vijfde beeld netjes op de volgende regel. */
/* Alleen een sectie zonder eigen breedtekeuze krijgt de 800 van de
   casekolom. Koos de redactie wél een breedte, dan geldt die: een
   hoofdbeeld over de volle breedte of een tekst op 670 moet niet alsnog
   naar 800 worden teruggetrokken. */
body.case .ml-vrij__inhoud:not([class*="ml-vrij__inhoud--"]) {
  max-width: calc(800px + 2 * var(--ml-marge));
}

body.case .ml-vrij .plate--column {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px 24px;
  align-content: start;
}
body.case .ml-vrij .plate--column > .plate--element {
  grid-column: span 2;
  margin-top: 0;          /* de gap doet dit nu */
}
body.case .ml-vrij .plate--column > .plate--element:has(.ml-beeld--1-1) {
  grid-column: span 1;
}

@media (max-width: 639.98px) {
  body.case .ml-vrij .plate--column { grid-template-columns: 1fr; }
  body.case .ml-vrij .plate--column > .plate--element,
  body.case .ml-vrij .plate--column > .plate--element:has(.ml-beeld--1-1) { grid-column: span 1; }
}

/* ------------------------------------------------- getekend kader */
/* Maten van de live pagina Over ons: het kader is 878 breed binnen de
   container, met 76 binnenmarge rondom. De getekende lijn steekt zes
   pixels naar buiten, dus het kader krijgt die ruimte als marge mee,
   anders snijdt de buurkolom hem af. */
/* De getekende lijn steekt zes pixels buiten het kader; met een negatieve
   marge valt de lijn daar en begint de tekst toch op 70 vanaf de
   containerrand, net als op de live site. */
.ml-kader {
  position: relative;
  margin: -6px;
  padding: 76px;
}
/* De getekende rand is een absolute SVG en komt daarmee ná de inhoud aan
   de beurt bij het tekenen. Zonder deze regel ligt het gele vlak over de
   tekst heen en zie je een leeg kader. Zelfde valkuil als bij het
   vraagblok. */
.ml-kader__inhoud { position: relative; }

.ml-kader__kop {
  margin: 0;
  font-size: var(--ml-kop-m);
  line-height: 1.1;
  color: var(--ml-op-vlak, var(--ml-zwart));
}
/* De tekst in het kader staat op 18, net als de rest van Over ons. */
.ml-kader__tekst { margin-top: 20px; font-size: 18px; line-height: var(--ml-lh-tekst); }
.ml-kader__actie { margin: 32px 0 0; }

@media (max-width: 767px) {
  .ml-kader { padding: 32px 24px; }
}

/* -------------------------------------------- scribble naast een kop */
/* Opgemeten op Over ons bij 1512: de krul is 154 bij 136 en staat links
   buiten de tekstkolom, met zijn rechterrand 16 pixels voor de tekst en
   46 pixels boven de kop. De zigzag is 92 bij 113 en staat juist binnen
   de rechterrand van dezelfde kolom. Op de live site raken ze de tekst
   niet, dus er is ook geen stapeling nodig; een z-index hier zou de
   krul juist achter de paginaachtergrond laten verdwijnen. */
.ml-kop--krul-links,
.ml-kop--zigzag-rechts { position: relative; }

.ml-kop--krul-links::before,
.ml-kop--zigzag-rechts::after {
  content: "";
  position: absolute;
  pointer-events: none;
  background: center / contain no-repeat;
}
.ml-kop--krul-links::before {
  right: calc(100% + 16px);
  top: -46px;
  width: 154px;
  height: 136px;
  background-image: url("../img/scribble-krul.svg");
}
.ml-kop--zigzag-rechts::after {
  right: 0;
  top: -50px;
  width: 92px;
  height: 113px;
  background-image: url("../img/scribble-zigzag.svg");
}

/* Kan het script de scribble tekenen, dan zet het de tekening erin en
   gaat de achtergrondafbeelding uit. De inline tekening krijgt exact
   dezelfde plek en maat als het pseudo-element, zodat er niets
   verspringt op het moment van wisselen. Zonder script, of als het
   ophalen mislukt, blijft de achtergrond gewoon staan. */
.ml-kop--getekend.ml-kop--krul-links::before,
.ml-kop--getekend.ml-kop--zigzag-rechts::after { content: none; }

.ml-teken {
  position: absolute;
  display: block;
  pointer-events: none;
  color: inherit;
}

/* De getekende ovaal en de footerstreep vullen hun eigen vak; die staan
   niet los naast een kop maar vallen er precies overheen. */
.ml-markering .ml-teken,
.ml-footer__streep .ml-teken { inset: 0; width: 100%; height: 100%; }

/* De ovaal hoort achter de letters. Tekst gaat voor, altijd. Het
   pseudo-element dat hij vervangt stond op z-index -1; de ingevoegde
   tekening moet datzelfde doen. Dat blijft binnen de kop hangen en
   verdwijnt niet achter de sectie, doordat .ml-markering een eigen
   stapelcontext heeft met isolation: isolate. */
.ml-markering .ml-teken { z-index: -1; }
.ml-markering.ml-kop--getekend::after,
.ml-footer__streep.ml-kop--getekend { -webkit-mask: none; mask: none; background: none; }
.ml-markering .ml-teken svg { overflow: visible; }
.ml-teken svg { display: block; width: 100%; height: 100%; overflow: visible; }

.ml-kop--krul-links .ml-teken {
  right: calc(100% + 16px);
  top: -46px;
  width: 154px;
  height: 136px;
}
.ml-kop--zigzag-rechts .ml-teken {
  right: 0;
  top: -50px;
  width: 92px;
  height: 113px;
}

/* Op smalle schermen is er links van de kolom geen ruimte meer voor een
   krul; dan vervalt hij liever dan dat hij half buiten beeld hangt. */
@media (max-width: 1023.98px) {
  .ml-kop--krul-links::before,
  .ml-kop--krul-links .ml-teken { display: none; }
  .ml-kop--zigzag-rechts::after,
  .ml-kop--zigzag-rechts .ml-teken { width: 60px; height: 74px; top: -30px; }
}

/* ------------------------------------------- kolomverdeling van een rij */
/* Plate laat de breedte van een kolom niet via de API zetten: een PUT met
   `grid` komt ongewijzigd terug en bij het aanmaken verdeelt Plate zelf
   (twee kolommen worden 11 en 1). Een script kan een pagina dus niet
   neerzetten zoals hij bedoeld is. Deze klassen nemen de verdeling over
   in onze eigen opmaak. Ze staan alleen op secties waar de redactie er
   bewust voor kiest; zonder keuze blijft het raster van Plate leidend.

   Binnen zo'n sectie vervalt de binnenruimte van de kolommen en komt er
   een echte `gap` voor in de plaats. Dat is niet alleen netter maar ook
   nodig: met de halve gutter links en rechts werd de middelste van drie
   gelijke kolommen 15 pixels breder dan zijn buren.

   Een kolom zonder inhoud telt niet mee. Plate maakt bij het toevoegen
   van een kolom vaak een lege buur, en die hoort geen ruimte te pakken.
   Let op het `> *`: een element waarvan de tekst leeg is tekent niets,
   maar de omhullende div van Plate staat er nog wel. Zonder die extra
   stap zou zo'n leeg element toch een halve rij opeisen.
   In de editor blijft de kolom wel staan, anders kun je er niets in
   zetten. */
.ml-vrij[class*="ml-vrij--kol-"] .plate--column {
  padding-inline: 0;
}
.ml-vrij[class*="ml-vrij--kol-"] .plate--column:not(:has(.plate--element > *)) {
  flex: 0 0 0;
  padding: 0;
}
[data-editor="true"] .ml-vrij[class*="ml-vrij--kol-"] .plate--column:not(:has(.plate--element > *)) {
  flex: 0 0 40px;
  opacity: 0.4;
}
/* De tussenruimte staat als marge op elke gevulde kolom na de eerste, en
   niet als `gap` op de rij. Met allebei komt hij er dubbel in en breekt
   de rij af naar twee regels; dat gebeurde bij de slotrij van Over ons.
   Een marge heeft bovendien het voordeel dat een lege kolom vanzelf geen
   ruimte en geen gat oplevert. */
.ml-vrij[class*="ml-vrij--kol-"] .plate--column:has(.plate--element > *) ~ .plate--column:has(.plate--element > *) {
  margin-left: var(--ml-kolomgat, 30px);
}

.ml-vrij--kol-gelijk .plate--column:has(.plate--element > *) {
  flex: 1 1 0;
  max-width: none;
}

/* De vaste verdelingen rekenen met de tussenruimte eruit, zodat de
   kolommen precies de opgemeten breedte krijgen. */
.ml-vrij--kol-8-4 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(1),
.ml-vrij--kol-4-8 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(2) {
  flex: 0 0 calc((100% - var(--ml-kolomgat, 30px)) * 0.6667);
  max-width: calc((100% - var(--ml-kolomgat, 30px)) * 0.6667);
}
.ml-vrij--kol-8-4 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(2),
.ml-vrij--kol-4-8 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(1) {
  flex: 0 0 calc((100% - var(--ml-kolomgat, 30px)) * 0.3333);
  max-width: calc((100% - var(--ml-kolomgat, 30px)) * 0.3333);
}
.ml-vrij--kol-7-5 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(1),
.ml-vrij--kol-5-7 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(2) {
  flex: 0 0 calc((100% - var(--ml-kolomgat, 30px)) * 0.5833);
  max-width: calc((100% - var(--ml-kolomgat, 30px)) * 0.5833);
}
.ml-vrij--kol-7-5 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(2),
.ml-vrij--kol-5-7 .plate--row > .plate--column:has(.plate--element > *):nth-of-type(1) {
  flex: 0 0 calc((100% - var(--ml-kolomgat, 30px)) * 0.4167);
  max-width: calc((100% - var(--ml-kolomgat, 30px)) * 0.4167);
}

/* Tekst met beeld, zoals op Over ons. Opgemeten bij 1512: tekstkolom 675,
   beeld 338, met 125 ertussen, binnen de tweede marge van 1138. Trek die
   125 eraf en de verhouding is precies twee staat tot een. */
.ml-vrij--kol-tekst-beeld { --ml-kolomgat: 125px; }
.ml-vrij--kol-tekst-beeld .plate--row > .plate--column:has(.plate--element > *):nth-of-type(1) {
  flex: 0 0 calc((100% - 125px) * 0.6667);
  max-width: calc((100% - 125px) * 0.6667);
}
.ml-vrij--kol-tekst-beeld .plate--row > .plate--column:has(.plate--element > *):nth-of-type(2) {
  flex: 0 0 calc((100% - 125px) * 0.3333);
  max-width: calc((100% - 125px) * 0.3333);
}

/* De slotrij van Over ons: geel kader 878, tekstkolom 369, ook met 125
   ertussen, maar dan over de volle container van 1372. */
.ml-vrij--kol-kader-tekst { --ml-kolomgat: 125px; }
.ml-vrij--kol-kader-tekst .plate--row > .plate--column:has(.plate--element > *):nth-of-type(1) {
  flex: 0 0 calc((100% - 125px) * 0.7041);
  max-width: calc((100% - 125px) * 0.7041);
}
.ml-vrij--kol-kader-tekst .plate--row > .plate--column:has(.plate--element > *):nth-of-type(2) {
  flex: 0 0 calc((100% - 125px) * 0.2959);
  max-width: calc((100% - 125px) * 0.2959);
}

/* Onder de tabletgrens staat alles weer onder elkaar; een verdeling van
   twee derde tegen een derde is op een telefoon geen verdeling meer.

   Let op de selector. Deze regel stond er al, maar won het niet: een
   mediaregel telt niet mee in de specificiteit, en de vaste verdelingen
   hierboven hebben er met hun `:nth-of-type(1)` eentje meer. Daardoor
   bleven tekst en beeld op een telefoon naast elkaar staan, met een
   tekstkolom van 150 px. Vandaar `.plate--row >` en `:nth-of-type(n)`:
   die wegen even zwaar, en omdat dit later in het bestand staat wint
   het. Een !important is dan niet nodig.

   De grens staat op 809.98, net als de andere telefoonregels in dit
   bestand; hij stond op 767 en dan bleef een smalle tablet in twee
   kolommen hangen. */
@media (max-width: 809.98px) {
  .ml-vrij[class*="ml-vrij--kol-"] .plate--row > .plate--column:has(.plate--element > *):nth-of-type(n) {
    flex: 0 0 100%;
    max-width: 100%;
    margin-left: 0;
  }
  .ml-vrij[class*="ml-vrij--kol-"] .plate--row > .plate--column:has(.plate--element > *) ~ .plate--column:has(.plate--element > *) {
    margin-top: 32px;
  }
}

.ml-vrij--midden .plate--row { align-items: center; }
.ml-vrij--onder  .plate--row { align-items: flex-end; }

/* ------------------------------------------- getekende streep op een beeld

   In fase 2 ligt er op de teamfoto een streep die linksonder over de
   rand valt. Gemeten in het ontwerp: ongeveer half zo breed als het
   beeld, en hij steekt een kwart van zijn eigen breedte naar buiten.

   Hij hoort in de CSS en niet in het beeldbestand, zodat hij blijft
   kloppen als de redactie een andere foto of verhouding kiest. */

.ml-beeld--scribble-links,
.ml-beeld--scribble-rechts { position: relative; overflow: visible; }

.ml-beeld--scribble-links::after,
.ml-beeld--scribble-rechts::after {
  content: "";
  position: absolute; z-index: 1;
  width: 52%; aspect-ratio: 335 / 237;
  background: url("../img/scribble-streep.png") center / contain no-repeat;
  pointer-events: none;
}
.ml-beeld--scribble-links::after  { left: -13%; bottom: -8%; }
.ml-beeld--scribble-rechts::after { right: -13%; top: -8%; rotate: 180deg; }

/* Het beeld zelf mag niet over de streep heen liggen. */
.ml-beeld--scribble-links img,
.ml-beeld--scribble-rechts img { position: relative; z-index: 0; }

@media (max-width: 809.98px) {
  .ml-beeld--scribble-links::after,
  .ml-beeld--scribble-rechts::after { width: 44%; }
}

/* ------------------------------------------------------- de tekstballon

   Getekend in plaats van geplaatst: het kader is dezelfde bobbelrand als
   bij de andere blokken, de staart een eigen vormpje van vaste maat
   linksonder. Daardoor kan de ballon elke hoogte aannemen zonder dat de
   lijn of de staart vervormt. */

/* Geen achtergrondkleur op het blok zelf: de klasse ml-vlak--geel zet die
   wel, en dan staat er een gele rechthoek achter de tekening in plaats van
   een gele ballon. De vulling komt uit het vulpad hieronder, net als bij
   het vraagblok. */
.ml-ballon { position: relative; display: block; background: none; }

/* Het vulvlak en de rand liggen allebei over het hele blok en rekken op
   dezelfde manier mee, dus ze blijven op elkaar passen. De verhouding van
   de tekening is 455 bij 371; daar hoort de ballon dus ongeveer op uit te
   komen, anders vervormt de staart zichtbaar. */
.ml-ballon__vlak,
.ml-ballon__rand {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.ml-ballon__vlak {
  background: var(--ml-vlak-kleur);
  -webkit-mask: url("../img/ballon-vlak.svg") 0 0 / 100% 100% no-repeat;
          mask: url("../img/ballon-vlak.svg") 0 0 / 100% 100% no-repeat;
}
.ml-ballon__rand {
  background: var(--ml-schetslijn, var(--ml-zwart));
  -webkit-mask: url("../img/ballon-rand.svg") 0 0 / 100% 100% no-repeat;
          mask: url("../img/ballon-rand.svg") 0 0 / 100% 100% no-repeat;
}

/* De onderste 12,7 procent van de tekening is staart. De tekst blijft
   daarboven, anders loopt hij de punt in. */
.ml-ballon__tekst {
  position: relative;
  padding: 40px 44px calc(40px + 12.7%);
  font-family: var(--ml-font-kop); font-weight: 700;
  font-size: var(--ml-kop-s); line-height: var(--ml-lh-kop-s);
  letter-spacing: normal;
  text-align: center;
  color: var(--ml-op-vlak, var(--ml-zwart));
}
.ml-ballon--groot .ml-ballon__tekst { font-size: var(--ml-kop-m); line-height: var(--ml-lh-kop); }
.ml-ballon__tekst p { margin: 0; }
.ml-ballon__tekst p + p { margin-top: 0.5em; }

@media (max-width: 809.98px) {
  .ml-ballon__tekst { padding: 28px 30px calc(28px + 12.7%); }
}

/* In de paginakop staat de ballon rechts naast de titel en de inleiding.
   Alleen als de redactie er een in de kop zet; anders verandert er niets. */
@media (min-width: 1200px) {
  .ml-header__inner:has(.ml-ballon) {
    display: grid;
    grid-template-columns: minmax(0, 906fr) 434fr;
    column-gap: 32px;
    align-items: center;
  }
  .ml-header__inner:has(.ml-ballon) .ml-header__koppen,
  .ml-header__inner:has(.ml-ballon) .ml-header__onder { grid-column: 1; }
  .ml-header__inner:has(.ml-ballon) > .plate--container { grid-column: 2; grid-row: 1 / span 2; }
}

/* Onder 1200 past hij daar niet naast en zakt hij onder de inleiding. De
   kop en de ballon zijn dan broers in een gewone blokstroom, dus zonder
   marge plakt de ballon tegen de laatste regel tekst. Op Over ons viel
   dat niet op, want daar staat de ballon in een eigen sectie en zorgt de
   sectieruimte voor lucht. */
@media (max-width: 1199.98px) {
  .ml-header__inner:has(.ml-ballon) > .plate--container { margin-top: 48px; }
}

/* Een nog niet ingevulde uitdagingsbaan toont geen leeg gekleurd vlak,
   maar blijft in de editor staan om te kunnen vullen. */
.ml-uitdaging--leeg { display: none; }
[data-editor="true"] .ml-uitdaging--leeg { display: block; opacity: 0.4; }

/* De dikte van de getekende rand is per blok te zetten. De lijn staat op
   non-scaling-stroke, dus de waarde is gewoon een maat in beeldpunten en
   verandert niet mee met de grootte van het vlak. Zes is de maat van de
   live site; op het grote blauwe aandachtsblok viel die weg, daar is hij
   tien. Een CSS-regel wint het van het stroke-width-attribuut in de SVG,
   dus de include hoeft er niets voor te weten. */
.ml-schetsrand path { stroke-width: var(--ml-schetsdikte, 6); }
/* Stond op 10 omdat de lijn half werd afgeknipt en daardoor dun oogde.
   Nu hij niet meer afgesneden wordt, is 6 genoeg; dat is ook de maat van
   de live site. */
.ml-vraag__blok { --ml-schetsdikte: 6; }
