/* =====================================================================
   kunstgebitkapot.nl - het enige stylesheet van de site.

   Structuur:
   1.  Tokens
   2.  Lettertypes
   3.  Reset en basis
   4.  Layout
   5.  Typografie
   6.  Knoppen en kleine onderdelen
   7.  Kop, navigatie en het offcanvas-menu
   8.  Kruimelpad
   9.  Hero
   10. Secties en kaarten
   11. Lijsten: plaatsen, feiten, vragen
   12. Formulier
   13. Voet, belbalk en knop naar boven
   14. Responsive
   15. Motion

   Ontwerptaal: dezelfde familie als vantoorntandtechniek.nl. Koel grafiet,
   crisp wit, veel lucht, haarlijnen in plaats van vlakken, Manrope voor de
   koppen en Figtree voor de lopende tekst.

   Het verschil met het moederbedrijf: daar is het accent brass en staat het
   alleen op haarlijnen. Hier is het accent het blauw uit het logo, en dat mag
   wél vullen, maar op precies één plek: de belknop. Dit is een spoeddienst.
   De bezoeker moet in een halve seconde zien waar hij moet drukken.

   Mobile first: alles hieronder is de telefoon, de min-width-regels staan in
   sectie 14.
   ===================================================================== */

/* ============================ 1. TOKENS ============================ */

:root {
  /* --- Het palet: diepzee ---
     Het oude palet was neutraal grijs met een blauwe knop. Correct, maar het
     bleef kleurloos. Dit palet heeft één idee: alles wat donker of grijs is,
     krijgt de kleur van het logo mee. De grijzen zijn geen grijzen meer maar
     zeer lichte marinetinten, en de donkere vlakken zijn diep marineblauw in
     plaats van bijna-zwart. Daardoor hoort de cyaan van het logo er ineens bij
     in plaats van dat hij erop geplakt is.

     Daarnaast is er precies één warme kleur, koraal. Die heeft één betekenis en
     verschijnt nergens anders: urgentie en "niet doen". Zo weet de bezoeker
     binnen een halve seconde wat hij moet lezen. Blauw is de weg vooruit,
     koraal is de waarschuwing. Groen is er niet meer als signaalkleur: een
     gekleurd bolletje bij "nu geopend" leest als een statuslampje van een
     dashboard, niet als de openingstijd van een tandtechnisch laboratorium. */

  /* Inkt: marineblauw in plaats van grafiet. */
  --ink: #0a1f33;          /* koppen, 16,3:1 op wit */
  --ink-soft: #3c5164;     /* lopende tekst, 8,6:1 op wit */
  /* --ink-mute stond op #64798c. Dat haalde 4,5:1 op wit en dus net AA, maar deze
     kleur staat bijna nooit op wit: hij staat in de kruimels (--paper), in de
     intro van een getinte sectie en in de hero (--brand-tint). Daar zakte hij
     naar 4,2 en 4,1 en dus onder AA. Nu 5,4 op wit, 5,0 op --paper en 4,8 op de
     hero. Gemeten met gereedschap/controle-contrast.php. */
  --ink-mute: #5a6d7e;     /* meta en bijschriften, 5,4:1 op wit */
  --line: #e3ebf2;         /* haarlijnen, blauw getint */
  --line-strong: #c9d7e3;  /* scheidingslijnen, puur decoratief */
  /* De rand van een invoerveld of een ghost-knop is de enige begrenzing van dat
     element, en daar eist WCAG 1.4.11 3:1 voor. --line-strong haalt 1,5 en was
     dus eigenlijk geen rand.

     Deze stond op #7d8fa1 en haalde 3,3 op wit en 3,1 op --paper. Dat was gemeten
     op twee van de drie achtergronden: op --brand-tint, de aanloop bovenaan elke
     pagina, staat de ghost-knop van de hero er ook op, en daar haalde hij 2,99 en
     dus net geen AA. Een stap donkerder lost alle drie op: 3,6 op wit, 3,3 op
     --paper en 3,2 op --brand-tint. */
  --field-line: #78899b;
  --paper: #f2f7fb;        /* de rustiger gekleurde secties */
  --white: #fff;

  /* Donkere panelen: het menu, het eerste-hulp-blok, het CTA-blok en de voet.
     Diep marineblauw, geen zwart: zwart naast een cyaan logo leest als twee
     losse ontwerpen. */
  --night-950: #06192b;
  --night-900: #0b2743;
  --on-dark: #e8f1f8;
  --on-dark-dim: #9fb6c9;  /* 8,0:1 op --night-950 */
  --on-dark-line: rgba(255, 255, 255, .12);

  /* De cyaan uit het logo. --brand is de signatuur (haarlijnen, iconen,
     accenten), --brand-deep is de enige die vult én de kleur van elke link.

     --brand-deep stond op #0277bd. Wit daarop haalt 4,8:1 en dus AA, maar als
     linkkleur staat hij net zo vaak op --paper, en daar haalde hij 4,45 en dus
     net niet. Eén stap dieper lost allebei op: 5,4 op wit, 5,0 op --paper, 4,8
     op de aanloop van de hero, en wit erop 5,4. */
  --brand: #039be5;
  --brand-deep: #026fb0;
  --brand-dark: #013d66;
  --brand-light: #7fd3f7;  /* op donker: 9,6:1 op --night-950 */
  --brand-tint: #e7f5fe;

  /* Koraal: alleen voor urgentie en "niet doen". Twee tinten, want de heldere
     haalt op wit geen AA voor tekst: die is voor pictogrammen en haarlijnen,
     de diepe is voor tekst. */
  --accent: #f4743b;
  --accent-ink: #b0491d;   /* 5,3:1 op wit */
  --accent-tint: #fff2ec;

  /* Groen komt nog maar op één plek voor: de rand van een geslaagde melding.
     Het statusbolletje is weg, zie sectie 6. #0e8a5f haalde 4,4 op wit en dus
     geen AA; dit haalt 5,9. */
  --open: #0b7350;
  --warn: var(--accent-ink);
  --error: #9b211b;
  --focus: #026fb0;   /* dezelfde als --brand-deep, letterlijk zodat gereedschap/controle-contrast.php hem kan lezen */

  /* Radius: bedieningselementen 12, kaarten 20, groot beeld 28. Een stap ruimer
     dan eerst. Op een telefoon staat een kaart bijna schermbreed, en bij die
     breedte leest 18px als een rechthoek met afgeschuurde hoeken in plaats van
     als een eigen vorm. De verhouding tussen de drie blijft gelijk. */
  --r-ctl: 12px;
  --r-card: 20px;
  --r-lg: 28px;
  --r-pill: 999px;

  /* Schaduw, getint zoals de inkt, nooit puur zwart.

     Elke schaduw bestaat uit drie lagen: een haarscherpe contactlijn vlak onder
     de rand, een korte kernschaduw en een brede zachte val. Een enkele zachte
     schaduw leest als een vlek onder het element; deze stapeling leest als een
     vlak dat echt een paar millimeter boven de pagina ligt. Dat is het verschil
     tussen "er zit een kader omheen" en "het ligt erop", en het is op een
     telefoon het goedkoopste stukje diepte dat er is: geen extra verzoek en
     geen extra laag om te compositen bij het scrollen. */
  --shadow-sm: 0 1px 1px rgba(10, 31, 51, .04), 0 2px 6px -2px rgba(10, 31, 51, .07);
  --shadow: 0 1px 1px rgba(10, 31, 51, .04), 0 6px 14px -8px rgba(10, 31, 51, .16),
            0 18px 40px -22px rgba(10, 31, 51, .22);
  --shadow-lg: 0 1px 2px rgba(10, 31, 51, .05), 0 12px 28px -14px rgba(10, 31, 51, .22),
               0 40px 80px -40px rgba(10, 31, 51, .35);

  /* De belknop is het enige gevulde vlak op de site en draagt zijn eigen schaduw
     in de merkkleur in plaats van in inkt. Een grijze schaduw onder een blauwe
     knop leest als vuil; dezelfde schaduw in het blauw van de knop leest als
     licht. Dit is geen gloed: hij zit onder de knop, niet eromheen. */
  --shadow-call: 0 1px 1px rgba(1, 61, 102, .22), 0 8px 18px -10px rgba(2, 111, 176, .55),
                 0 22px 42px -28px rgba(2, 111, 176, .5);

  /* Ritme */
  --wrap: 1180px;
  --pad: clamp(1.25rem, 5vw, 2rem);
  /* De sectieruimte stond op 3,25rem op een telefoon. Dat is de ruimte die je
     kiest als je bang bent dat de pagina te lang wordt, en het is precies wat
     een pagina goedkoop laat lezen: alles raakt elkaar bijna. Lucht is het
     goedkoopste luxemateriaal dat er is. */
  --section-y: clamp(3.75rem, 8vw, 6.5rem);
  --nav-h: 64px;

  --ease: cubic-bezier(.16, 1, .3, 1);
  /* Voor iets dat binnenkomt, in plaats van iets dat antwoordt op een tik. */
  --ease-out: cubic-bezier(.22, .61, .25, 1);

  /* De korrel op de donkere panelen. Een dekkend donker vlak van vierhonderd
     pixels hoog is een dode plek op een scherm; deze ruis van nog geen
     driehonderd bytes geeft hem textuur zonder afbeelding, zonder beweging en
     zonder dat je hem bewust ziet. Hij ligt als eerste laag boven het verloop.
     Staat hier als laatste token: hij bevat geen hexkleur, dus
     gereedschap/controle-contrast.php loopt er gewoon overheen. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.055'/%3E%3C/svg%3E");

  --font-display: 'Manrope', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-text: 'Figtree', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
}
/* ============================ 2. LETTERTYPES ============================ */
/* Zelf gehost, één variabel bestand per familie, alleen de latijnse tekens.
   Samen 45 KB. Zie docs/04-beslissingen/0008-ontwerptaal.md. */

@font-face {
  font-family: 'Figtree';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/figtree-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 500 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ============================ 3. RESET EN BASIS ============================ */

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

[hidden] { display: none !important; }

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

body {
  margin: 0;
  background: var(--white);
  color: var(--ink-soft);
  font-family: var(--font-text);
  font-size: 1.0625rem;       /* 17px, prettig leesbaar zonder te schreeuwen */
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  /* Ruimte voor de vaste kop. De ruimte onderin voor de zwevende belbalk zit
     niet hier maar op .footer: als <body> hem draagt, houdt de donkere voet op
     en staat er daaronder nog vijf rem wit waar de balk in zweeft. Een lichte
     strook onder een donker blok, precies waar de pagina eindigt. */
  padding-top: var(--nav-h);
}

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

/* .subhead ziet eruit als een h3 maar is een gewone alinea: kaartjes, stappen en de
   kopjes in de voet horen niet in de koppenstructuur. 30 koppen op de homepage bij
   zo'n 740 woorden gaf in Seobility een waarschuwing, zie docs/02-architectuur/seo.md. */
h1, h2, h3, .subhead {
  margin: 0 0 .55em;
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 700;
  letter-spacing: -.024em;
  line-height: 1.1;
  text-wrap: balance;
}

/* De h1 mag op een telefoon groter en strakker dan hij stond. Op 390 pixels kwam
   hij op 2,05rem uit: netjes, maar het leest als de kop van een alinea in plaats
   van als de kop van de pagina. Nu begint hij op 2,3rem met een strakkere
   spatiering, want hoe groter een letter staat, hoe meer lucht er optisch tussen
   valt. Op 320 pixels past "kunstgebit" nog steeds op een regel; dat is de maat
   die dit woord hier bepaalt. */
h1 {
  font-size: clamp(2.15rem, 1.05rem + 4.9vw, 3.6rem);
  line-height: 1.04;
  letter-spacing: -.035em;
  /* Geen balance op een telefoon. "Is uw kunstgebit kapot of gebroken?" past op
     320 pixels nooit op twee regels, en balance maakte er dan
     "Is uw kunstgebit / kapot / of gebroken?" van: een middelste regel van een
     woord leest als een fout. Gewoon vullen geeft "kapot of / gebroken?".
     Vanaf 48em, waar een kop wel op twee regels past, mag balance het weer doen. */
  text-wrap: pretty;
}
@media (min-width: 48em) {
  h1 { text-wrap: balance; }
}
h2 { font-size: clamp(1.55rem, .95rem + 2.2vw, 2.35rem); letter-spacing: -.026em; }
/* De ondergrens stond op 1,1rem. Op een telefoon is dat 17,6 pixels naast een
   lopende tekst van 17: het verschil tussen een kop en een alinea zat dan alleen
   nog in het vette en in het lettertype, en dat is te weinig om een pagina mee
   te kunnen scannen. Nu 18,9 pixels, en de bovengrens blijft waar hij stond. */
h3, .subhead { font-size: clamp(1.18rem, 1.06rem + .5vw, 1.3rem); letter-spacing: -.015em; line-height: 1.25; }

p, ul, ol, dl { margin: 0 0 1.1em; }
p { text-wrap: pretty; }

a { color: var(--brand-deep); text-underline-offset: .18em; }
a:hover { color: var(--brand-dark); }

strong { color: var(--ink); font-weight: 700; }

/* De browser zet <address> schuin. Dat stond alleen in de voet rechtgezet, dus
   op de contactpagina stond het adres van het bedrijf in cursief. */
address { font-style: normal; }

:where(a, button, input, select, textarea, summary):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ---- Wat je voelt als je iets aanraakt ----
   Android en iOS leggen bij elke tik een grijsblauw vlak over het hele element.
   Dat vlak is van de browser, niet van deze site: het heeft een eigen kleur, een
   eigen vorm en het blijft op Android staan tot je ergens anders tikt. Op een
   knop die zelf al indrukt is het bovendien dubbelop.

   Weg ermee, maar alleen bij wat hieronder zelf antwoord geeft. Een tik die
   nergens op reageert voelt als een kapotte site, en dat is erger dan een
   lelijke flits. Daarom staat elke regel hier naast zijn eigen :active. */
.button, .header__toggle, .totop, .m-link, .card--link, .nav__list a,
.places a, .faq summary, .footer a {
  -webkit-tap-highlight-color: transparent;
}

::selection { background: var(--brand-deep); color: #fff; }

/* ============================ 4. LAYOUT ============================ */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.section { padding-block: var(--section-y); }
.section--tint { background: var(--paper); }
.section--tight { padding-block: calc(var(--section-y) * .55); }

/* ---- De ruimte tussen twee secties ----
   Elke sectie telde zijn eigen ruimte boven en onder. Twee witte secties op
   elkaar gaven dus twee keer --section-y, op een telefoon ruim honderd pixels
   niets tussen twee blokken die gewoon bij elkaar horen. Dat leest niet als
   lucht maar als een gat waar iets uit gevallen is, en het was het duidelijkst
   op /diensten: de waarschuwing over lijmen zweefde daar in een leeg scherm.

   Nu telt tussen twee secties alleen de onderkant van de bovenste mee. Een
   sectie met een eigen achtergrond houdt zijn volle ruimte: daar begint een
   nieuw vlak, en een vlak heeft aan de bovenkant zijn eigen lucht nodig. */
.section + .section { padding-block-start: 0; }
.section--tint + .section,
.section + .section--tint { padding-block-start: var(--section-y); }

.stack > * + * { margin-top: 1.1rem; }

.grid { display: grid; gap: 1.1rem; }
.cards { list-style: none; margin: 0; padding: 0; }
/* Een zin met links onder een rij kaarten (de 404). Zonder eigen ruimte plakt
   hij tegen de onderrand van de kaarten, want .cards heeft geen ondermarge. */
.cards__after { margin: 1.5rem 0 0; color: var(--ink-soft); }
.nomargin { margin-bottom: 0; }
.center { text-align: center; }

.skip {
  position: fixed;
  left: -9999px;
  top: .5rem;
  z-index: 100;
  padding: .8rem 1.3rem;
  border-radius: var(--r-ctl);
  background: var(--ink);
  color: var(--white);
  font-weight: 600;
  text-decoration: none;
}
.skip:focus { left: .5rem; color: var(--white); }

/* ============================ 5. TYPOGRAFIE ============================ */

.section__head { max-width: 46rem; margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }
.section__head p { color: var(--ink-mute); margin-bottom: 0; }
/* Het labeltje boven de kop is ook een <p> en verloor door de regel hierboven
   zijn ondermarge: dan plakt het tegen de h2 aan. */
.section__head .eyebrow { margin-bottom: .9rem; }

/* De lead stond op dezelfde maat als de lopende tekst en verschilde er dus
   alleen in breedte van. Een aanhef hoort een eigen trede te zijn tussen de kop
   en de tekst, anders valt de pagina na de kop meteen terug op een. */
.lead {
  font-size: clamp(1.15rem, 1.02rem + .6vw, 1.35rem);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: 34em;
  margin-bottom: 1.5rem;
}

/* Het labeltje boven een kop, met een blauw streepje ervoor. Geen pil: een pil
   is een vlak, en vlakken zijn hier voor knoppen.

   Het stond in hoofdletters met .16em spatiëring. Dat is het kickerlabel van
   elke landingspagina, en voor een doelgroep die grotendeels ouder is leest een
   regel hoofdletters bovendien slechter dan gewone tekst. Nu gewoon geschreven,
   iets groter, en nog steeds duidelijk ondergeschikt aan de kop eronder. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-size: .9rem;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--ink-mute);
}
.eyebrow::before {
  content: '';
  width: 1.6rem;
  height: 2px;
  border-radius: 2px;
  background: var(--brand);
  flex: none;
}

.prose { max-width: 42rem; }
.prose h2 { margin-top: 1.8em; }
.prose h3 { margin-top: 1.5em; }
.prose ul { padding-left: 1.1rem; }
.prose li { margin-bottom: .35em; }
.prose li::marker { color: var(--brand); }

/* ============================ 6. KNOPPEN EN KLEINE ONDERDELEN ============================ */

.icon { width: 1.35em; height: 1.35em; flex: none; vertical-align: -.25em; }

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  /* Drieenhalve centimeter breed en ruim vijftig pixels hoog: dit is de knop
     waar een oudere bezoeker met een duim op moet raken terwijl hij overstuur
     is. De 44 pixels uit de richtlijn is een ondergrens, geen streefwaarde. */
  min-height: 3.25rem;
  padding: .95rem 1.5rem;
  border: 1.5px solid transparent;
  border-radius: var(--r-ctl);
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .25s var(--ease), border-color .25s var(--ease),
              color .25s var(--ease), box-shadow .25s var(--ease), transform .15s var(--ease);
}
.button .icon { width: 1.15em; height: 1.15em; }
/* Indrukken mag je voelen: de knop zakt in en de schaduw zakt mee. Zonder dat
   tweede blijft hij op dezelfde hoogte zweven en voelt de tik nergens naar. */
.button:active { transform: translateY(1px) scale(.994); }
.button--call:active { box-shadow: 0 1px 1px rgba(1, 61, 102, .22), 0 4px 10px -8px rgba(2, 111, 176, .5); }

/* De enige gevulde kleur op de site. */
/* De enige gevulde kleur op de site, dus ook de enige die diepte mag hebben.
   De vulling blijft een egale --brand-deep: wit daarop is gemeten op 5,4:1, en
   een verloop zou de bovenkant lichter maken en dat getal stilletjes verlagen.
   De haarlijn bovenin ligt binnen de knop en raakt de letters niet, en de
   schaduw eronder draagt de merkkleur in plaats van grijs. */
.button--call {
  background: var(--brand-deep);
  color: var(--white);
  box-shadow: var(--shadow-call), inset 0 1px 0 rgba(255, 255, 255, .2);
}
.button--call:hover {
  background: var(--brand-dark);
  color: var(--white);
  box-shadow: var(--shadow-call), inset 0 1px 0 rgba(255, 255, 255, .26);
}

.button--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--field-line);
}
.button--ghost:hover { border-color: var(--ink); background: var(--paper); color: var(--ink); }

.button--block { width: 100%; }

/* Op een donker vlak draait de knop om: wit vlak, donkere tekst. Blauw op
   bijna-zwart is blauw op donker, en dan moet het contrast uit de knop zelf komen. */
.cta .button--call, .m-foot .button--call { background: var(--white); color: var(--ink); }
.cta .button--call:hover, .m-foot .button--call:hover { background: var(--brand-tint); color: var(--brand-dark); }

/* De tweede knop op een donker vlak: alleen een haarlijn, geen vulling. */
.button--ghost-light {
  background: transparent;
  color: var(--on-dark);
  border-color: rgba(255, 255, 255, .3);
}
.button--ghost-light:hover {
  background: rgba(255, 255, 255, .08);
  border-color: var(--on-dark);
  color: var(--white);
}

/* ---- "Nu geopend" ----
   Hier stond een groen bolletje met een gloedring eromheen. Dat is het
   statuslampje van een serverdashboard: het belooft realtime en het trekt meer
   aandacht dan de openingstijd verdient. Open of dicht blijkt uit de woorden en
   uit de inkt, niet uit een kleurcode die een kwart van de mannen boven de
   vijftig toch niet ziet.

   Daarna was het een regel grijze tekst, en dat was te weinig. Dit blok staat op
   vijftien pagina's tussen de aanhef en de belknop, dus precies op de plek waar
   de bezoeker beslist of hij nu belt of morgen terugkomt. Daar mag het gezien
   worden.

   Nu twee treden naast een haarlijn: dezelfde vorm als .notice. Dat is
   de enige vorm op deze site die zegt "dit is een blok met betekenis", en hij
   kost geen vlak, geen schaduw en geen nieuwe kleur. Het verschil tussen open en
   dicht draagt de haarlijn: de merkkleur als wij open zijn, grijs als wij dicht
   zijn. Geen groen, geen gloed, geen bolletje dat ademt.

   Waarom grid en twee losse spans, en geen flexbox met één regel tekst: zo'n
   regel is één naamloos flexitem, en dat springt bij wrap in zijn geheel onder
   het pictogram. Bij de lange gesloten-tekst stond het klokje daardoor op een
   telefoon in zijn eentje boven de regel. Zie docs/05-valkuilen/index.md. */
.status {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: .1rem .65rem;
  margin: 0 0 1.5rem;
  padding: .1rem 0 .15rem 1.05rem;
  border-left: 2px solid var(--line-strong);
  /* Tijden veranderen per dagdeel. Met tabelcijfers springt de regel niet van
     breedte als 08:00 in 11:00 verandert. */
  font-variant-numeric: tabular-nums;
}
.status .icon {
  grid-row: span 2;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: .25em;
  color: var(--ink-mute);
}
/* De eerste trede is het antwoord: open of dicht. Manrope, want dit is een kop
   van twee woorden en geen lopende tekst. */
.status__lead {
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 700;
  letter-spacing: -.015em;
  line-height: 1.3;
  color: var(--ink-mute);
}
/* De tweede trede is wat de bezoeker eraan heeft: tot hoe laat, of vanaf
   wanneer weer. Kleiner en zachter, maar hij verdwijnt nooit, want dit is het
   stukje waar hij naar op zoek is. */
.status__note {
  font-size: .93rem;
  line-height: 1.4;
  color: var(--ink-mute);
}
.status--open { border-left-color: var(--brand); }
.status--open .icon { color: var(--brand-deep); }
.status--open .status__lead { color: var(--ink); }

/* ---- Een regel met een pictogram ervoor ----
   In de reset staat `img, svg { display: block }`, want dat haalt de witruimte
   onder een plaatje weg. Gevolg: een pictogram midden in lopende tekst valt op
   een eigen regel. Overal elders op de site is de ouder een flexbox en viel dat
   niet op, maar op de contactpagina stonden telefoon, e-mail en route daardoor
   bóven hun eigen link. Dit is de flexbox voor zo'n regel. */
/* Geen ondermarge: de min-height geeft al lucht, en drie van deze regels onder
   elkaar met een alineamarge ertussen lazen als drie losse alinea's in plaats
   van als één blok contactgegevens. */
.iconline {
  display: flex;
  align-items: center;
  gap: .6rem;
  min-height: 2.5rem;
  margin-bottom: 0;
}
.iconline .icon { width: 1.2rem; height: 1.2rem; color: var(--brand-deep); flex: none; }

/* Opsomming met vinkjes. */
.checks { list-style: none; margin: 0; padding: 0; display: grid; gap: .65rem; }
.checks li { display: flex; gap: .7rem; align-items: flex-start; }
.checks .icon { color: var(--brand-deep); width: 1.15rem; height: 1.15rem; margin-top: .28em; }

/* Waarschuwing: niet zelf lijmen.
   Bewust geen kaartje met een gekleurd randje: dat is het standaard
   meldingsblokje dat op elke website staat. Dit is een haarlijn met een label
   erboven, zoals de rest van de site ook met haarlijnen werkt. */
.notice {
  max-width: 44rem;
  padding-left: 1.6rem;
  border-left: 2px solid var(--warn);
}
.notice__label {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin: 0 0 .5rem;
  font-family: var(--font-display);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--warn);
}
.notice__label .icon { width: 1.1rem; height: 1.1rem; }
.notice > p { margin-bottom: 0; }
.notice strong { color: var(--ink); }

/* ============================ 7. KOP EN NAVIGATIE ============================ */

.header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  /* Dekkend wit, geen backdrop-filter: dat kost een extra compositielaag bij elke
     scroll, en een element met backdrop-filter wordt een containing block voor
     position:fixed erbinnen. Zie docs/05-valkuilen/index.md. */
  background: var(--white);
  border-bottom: 1px solid transparent;
  transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.header.is-scrolled {
  border-bottom-color: var(--line);
  box-shadow: 0 6px 24px -18px rgba(10, 31, 51, .45);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
}

/* ---- Het logo ----
   Het bestand was 300x75 terwijl het merk zelf maar 271x49 besloeg: een derde
   van de hoogte was doorzichtige lucht. De css zet een hoogte op het element,
   dus die lucht telde mee en het merk kwam op een telefoon op zo'n 22 pixels
   uit. Het bestand is nu bijgesneden (gereedschap/logo-bijsnijden.php), dus de
   hoogte hieronder is de hoogte die je ook echt ziet. */
.header__logo { display: inline-flex; align-items: center; line-height: 0; }
/* Bij het scrollen krimpt het logo een paar pixels mee met de aandacht: bovenaan
   de pagina is het merk het onderwerp, daarna is het de weg terug. De balk zelf
   houdt zijn hoogte, want daar hangt de padding van <body> aan. */
.header__logo img { height: 34px; width: auto; transition: height .3s var(--ease); }
.header.is-scrolled .header__logo img { height: 30px; }

.header__actions { display: flex; align-items: center; gap: .5rem; }

.header__call .icon { width: 1.15rem; height: 1.15rem; }

.header__toggle {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--r-ctl);
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.header__toggle:hover { border-color: var(--ink-mute); }
.header__toggle .icon { width: 1.4rem; height: 1.4rem; }
.header__toggle > span { display: grid; place-items: center; }
.header__toggle .icon-close { display: none; }
.header__toggle[aria-expanded='true'] .icon-open { display: none; }
.header__toggle[aria-expanded='true'] .icon-close { display: grid; }

/* ---- De belknop in de kopbalk ----
   Op een telefoon staat hij er niet. Logo, belknop en hamburger samen passen
   niet in 320 pixels zonder dat het logo terugvalt naar onleesbaar klein, en de
   bezoeker houdt op een telefoon sowieso twee belknoppen over: de grote knop
   bovenaan de pagina, en de balk onderin die inschuift zodra die knop weg is.
   Die balk staat in de duimzone en is de betere van de twee.
   Vanaf 48em past hij wel en staat er "Bellen"; vanaf 62em het nummer voluit. */
.header__call { display: none; }
.header__call-long { display: none; }

/* De hamburger heeft geen doos nodig: het pictogram is genoeg, en twee vlakken
   naast elkaar in de balk maken de kop zwaar. */
.header__toggle { border: 0; background: transparent; }
/* Alleen bij een echte muisaanwijzer. Op Android blijft een :hover na een tik
   staan tot je ergens anders tikt, en dan zit er een grijze doos achter het
   kruisje zolang het menu openstaat. */
@media (hover: hover) {
  .header__toggle:hover { background: var(--paper); }
}
.header__toggle:active { background: var(--paper); }

/* De links naast elkaar, pas vanaf de brede weergave (sectie 14). */
.nav { display: none; }
.nav__list { display: flex; align-items: center; gap: .25rem; list-style: none; margin: 0; padding: 0; }
.nav__list a {
  position: relative;
  display: block;
  padding: .55rem .8rem;
  border-radius: var(--r-ctl);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: .95rem;
  color: var(--ink-soft);
  text-decoration: none;
  transition: color .2s var(--ease);
}
/* Het streepje stond op scaleX(0) en schoof bij hover van links naar rechts in.
   Dat is de animatie van elke templatemenubalk. Nu staat het streepje er bij de
   pagina waar je bent, en verder niet: het zegt waar je bent in plaats van dat
   het laat zien dat het kan bewegen. */
.nav__list a[aria-current='page']::after {
  content: '';
  position: absolute;
  left: .8rem;
  right: .8rem;
  bottom: .3rem;
  height: 2px;
  border-radius: 2px;
  background: var(--brand);
}
.nav__list a:hover { color: var(--ink); background: var(--paper); }
.nav__list a[aria-current='page'] { color: var(--ink); }

/* ---- Het offcanvas-menu ----
   Staat bewust buiten <header>, zodat het zich aan het scherm vasthoudt en niet
   aan de balk. Donker paneel, dezelfde taal als het moederbedrijf: haarlijnen,
   Manrope, een streepje in de merkkleur dat inschuift. */
.offcanvas {
  position: fixed;
  inset: 0;
  z-index: 49;
  visibility: hidden;
  pointer-events: none;
  transition: visibility 0s linear .5s;
}
.offcanvas.is-open { visibility: visible; pointer-events: auto; transition: visibility 0s; }

.offcanvas__scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 25, 43, .85);
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.offcanvas.is-open .offcanvas__scrim { opacity: 1; }

.m-panel {
  position: absolute;
  inset: 0 0 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  padding: calc(var(--nav-h) + 1.25rem) var(--pad) 0;
  overflow: hidden;
  color: var(--on-dark);
  background: var(--grain), linear-gradient(180deg, var(--night-900) 0%, var(--night-950) 60%);
  border-left: 1px solid rgba(255, 255, 255, .08);
  transform: translateX(100%);
  transition: transform .5s var(--ease);
}
.m-panel:focus { outline: none; }
.offcanvas.is-open .m-panel { transform: none; }

/* De links stonden hier optisch gecentreerd in de ruimte tussen de balk en het
   contactblok. Op een telefoon van 412x915 gaf dat 199 pixels leegte boven
   "Home", en leegte bóven de inhoud leest als een pagina die nog aan het laden is.

   Nu beginnen ze meteen onder de balk en rekken ze mee: elke link mag groeien
   tot 5,5rem, daarna houdt het op. Op een klein toestel blijven ze compact
   omdat er niets te verdelen valt, op een groot toestel worden het ruime
   regels in plaats van een propje met lucht eromheen. Wat er dan nog overblijft
   valt onderaan, net boven het contactblok, en daar stoort het niet. */
.m-nav {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

/* Deze links rekken niet mee met de schermhoogte. Dat hebben we wel geprobeerd,
   om de leegte onderin het paneel op te vullen, maar op een lang toestel werden
   het rijen van ruim honderd pixels en dan leest een menu van zes regels als
   zes lege vlakken. Een menu-item is een menu-item. De ruimte die overblijft
   valt onder de lijst, en dat is rust, geen fout.

   De lucht binnen een rij schaalt wél mee, via vh. Met een vaste 1,1rem paste
   het menu niet meer op een toestel van 320x568: zes rijen van 58 in 305 pixels
   gaat niet, en een menu dat moet scrollen is geen menu. Nu is een rij daar 48
   pixels en op een grote telefoon 57, en de ondergrens van 2,75rem houdt hem
   altijd boven de 44 pixels die je met een duim moet kunnen raken. */
.m-link {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 1 auto;
  min-height: 2.75rem;
  padding-block: clamp(.8rem, 1.9vh, 1.15rem);
  padding-inline: 1.5rem 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.2rem;
  letter-spacing: -.02em;
  line-height: 1.15;
  color: var(--on-dark);
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .07);
  transition: color .25s var(--ease);
}
/* Net als in de balk: het streepje hoort bij de huidige pagina en schuift niet
   in bij hover. */
.m-link[aria-current='page']::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  margin-top: -1px;
  width: .85rem;
  height: 2px;
  border-radius: 2px;
  background: var(--brand);
}
.m-link:hover, .m-link:focus-visible, .m-link:active { color: var(--brand-light); }
.m-link[aria-current='page'] { color: var(--brand-light); }

/* "Alle pagina's" is geen hoofdmenu-item maar een uitweg voor wie iets niet kan
   vinden. Hij houdt dezelfde rijhoogte als de rest, want een kleine regel onder
   vijf grote regels leest als een restje. Het verschil zit in de kleur en het
   gewicht: je ziet in één oogopslag dat hij ondergeschikt is, zonder dat het
   ritme van de lijst breekt. */
.m-link--sub {
  font-weight: 500;
  color: var(--on-dark-dim);
}
.m-link--sub:hover, .m-link--sub:focus-visible { color: var(--on-dark); }

/* Geen eigen bovenlijn: de linklijst sluit zelf al af met een haarlijn. Op een
   toestel van 320x568 staat het contactblok maar dertien pixels onder die lijn,
   en dan zag je twee lijnen vlak onder elkaar. */
/* Hier stonden drie dingen met elk hun eigen breedte links uitgelijnd onder
   elkaar: een grijze statusregel, een knop zo breed als zijn eigen tekst, en een
   mailadres. Drie losse dingen die toevallig onder elkaar stonden, met aan de
   rechterkant een rafelrand van drie verschillende lengtes. Dat is wat er
   rommelig aan was, niet de inhoud.

   Nu staan er nog twee dingen, in de volgorde die klopt: wat er op dit moment
   geldt, en de knop die je moet hebben. Het mailadres is eruit; het stond er als
   derde breedte onder en het staat voluit in de voet van elke pagina. Wie in
   paniek een kapot gebit in zijn hand heeft, mailt niet. */
.m-foot {
  flex: none;
  margin-top: auto;
  padding-top: 1.4rem;
  padding-bottom: calc(clamp(1.2rem, 3vh, 1.8rem) + env(safe-area-inset-bottom, 0px));
  display: grid;
  gap: .9rem;
}
.m-foot .button--call { width: 100%; }

/* Dezelfde twee treden als op een lichte pagina, maar dan in de inkt van het
   paneel. De haarlijn is hier het merkblauw dat op donker leesbaar blijft. */
.m-foot .status { margin: 0; border-left-color: var(--on-dark-line); }
.m-foot .status .icon { color: var(--on-dark-dim); }
.m-foot .status__lead { color: var(--on-dark); }
.m-foot .status__note { color: var(--on-dark-dim); }
.m-foot .status--open { border-left-color: var(--brand-light); }
.m-foot .status--open .icon { color: var(--brand-light); }
.m-foot .status--open .status__lead { color: var(--white); }

/* Terwijl het menu openstaat scrollt de pagina eronder niet mee. */
body.menu-open { overflow: hidden; }
body.menu-open .callbar { opacity: 0; pointer-events: none; }

/* ================= 8. KRUIMELPAD EN DE AANLOOP VAN EEN SUBPAGINA ================= */

/* Het kruimelpad is de eerste regel van een subpagina en dus de plek waar de
   pagina begint. Het stond op een vlak --paper-bandje van #f2f7fb, en daaronder
   begon meteen wit met de volle sectieruimte erboven. Op een telefoon las dat
   als een gat van ruim honderd pixels tussen twee bijna gelijke grijzen: de
   kruimels hingen in het niets en de kop begon veel te laag.

   Nu is het kruimelpad de bovenrand van dezelfde aanloop als de hero op de
   homepage. De kruimels, de eyebrow, de kop, de openingstijd en de belknop
   staan samen in een zacht merkverloop dat naar wit uitloopt, en pas daaronder
   begint het wit. Elke pagina van de site opent daarmee op dezelfde manier.

   De verdeling: .crumbs is de dekkende tint en de sectie eronder zet het verloop
   voort. Twee elementen kunnen geen verloop delen, dus de eerste stop van dat
   verloop is precies de kleur van het bandje erboven. */
.crumbs { background: var(--brand-tint); font-size: .88rem; }

/* De eerste sectie van een pagina met kruimels is de paginakop. Dat is de enige
   plek in dit stylesheet waar op de volgorde van de html gerekend wordt; elk
   paginabestand begint met <section class="section">, zie
   docs/02-architectuur/mapstructuur.md. */
.crumbs + main > .section:first-child {
  padding-block-start: clamp(1.4rem, 4vw, 2.25rem);
  background: linear-gradient(180deg, var(--brand-tint) 0%, #f4fafe 46%, var(--white) 100%);
}

.crumbs__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .2rem .5rem;
  /* Geen margin- of padding-shorthand: deze klasse staat samen met .wrap op
     hetzelfde element en zou de uitlijning daarvan uitzetten. Zie de valkuilen. */
  margin-block: 0;
  padding-block: .95rem .8rem;
  color: var(--ink-mute);
}
.crumbs__list li { display: flex; align-items: center; }
.crumbs__list a { color: var(--ink-mute); text-decoration: none; }
/* Blauw is de weg vooruit, ook hier: een kruimel is een link terug en gedraagt
   zich bij aanwijzen als elke andere link op de site. */
.crumbs__list a:hover { color: var(--brand-deep); text-decoration: underline; }

/* Een haarlijnchevron in plaats van een schuine streep. Dezelfde taal als de
   rest van de site, en hij wijst de kant op waar je leest. */
.crumbs__list li + li::before {
  content: '';
  flex: none;
  width: .34rem;
  height: .34rem;
  margin-right: .5rem;
  border-right: 1.5px solid var(--line-strong);
  border-bottom: 1.5px solid var(--line-strong);
  transform: rotate(-45deg) translate(-.02rem, -.02rem);
}
.crumbs__list [aria-current='page'] { color: var(--ink); font-weight: 600; }

/* ============================ 9. HERO ============================ */

/* De hero is op een telefoon de hele eerste indruk, en die is bijna altijd de
   enige die wij krijgen: wie hier komt is iets kwijt en kijkt hooguit een paar
   tellen.

   De volgorde stond als kop, tekst, openingstijd, knoppen, vinkjes, foto. Op een
   telefoon betekende dat vijf blokken tekst achter elkaar en kwam het beeld pas
   na anderhalf scherm. Dat leest als een brief, niet als een bedrijf.

   Nu: kop, tekst, openingstijd, knoppen, meteen het beeld, en onderaan een
   streep met wat wij beloven. De belknop blijft daarmee boven de vouw, dat is de
   enige harde eis, en de bezoeker ziet direct daarna waar hij terechtkomt. Het
   beeld is bovendien de LCP van de pagina en staat al in de preload, dus hoger
   in beeld kost niets. */
.hero {
  position: relative;
  padding-block: clamp(1.75rem, 5vw, 3.5rem) clamp(2.25rem, 5vw, 3.75rem);
  background: linear-gradient(180deg, var(--brand-tint) 0%, #f4fafe 46%, var(--white) 100%);
}
.hero__grid {
  display: grid;
  gap: clamp(1.6rem, 5vw, 3.5rem);
  align-items: center;
  grid-template-areas: 'tekst' 'beeld' 'belofte';
}
.hero__text { grid-area: tekst; }
.hero__media { grid-area: beeld; }
.hero__promise { grid-area: belofte; }

.hero h1 { margin-bottom: .4em; }

.hero__actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.hero__actions .button { flex: 1 1 13rem; }

/* ---- Het beeld in een kader met een bijschrift eroverheen ----
   Een foto die zomaar op de achtergrond ligt is een plaatje. Een foto met een
   kaartje eroverheen leest als een opname uit het eigen laboratorium, en het
   kaartje zegt iets wat de bezoeker wil weten en nergens anders in de hero
   staat: waar wij staan. Het kaartje ligt binnen de foto en niet over de rand
   heen: op 320 pixels heeft hij anders geen plek om te staan. */
.frame { position: relative; margin: 0; }
.frame img {
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  width: 100%;
}
.frame__tag {
  position: absolute;
  left: .85rem;
  bottom: .85rem;
  max-width: calc(100% - 1.7rem);
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .55rem .85rem;
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  /* Dekkend wit, geen matglas: over een foto is een half doorzichtig vlak nooit
     twee keer even leesbaar, en dan is de gemeten inkt op wit een aanname. */
  background: var(--white);
  box-shadow: var(--shadow);
  font-family: var(--font-display);
  font-size: .88rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--ink);
}
.frame__tag .icon { width: 1.05rem; height: 1.05rem; color: var(--brand-deep); flex: none; }

/* De belofte onder de hero: dezelfde drie vinkjes, maar als afsluitende streep
   onder de hele hero in plaats van als lijstje midden in de tekstkolom. Daar
   stonden ze tussen de knoppen en het beeld in en duwden ze het beeld weg. */
.hero__promise {
  padding-top: 1.25rem;
  border-top: 1px solid var(--line-strong);
}

/* ============================ 10. SECTIES EN KAARTEN ============================ */

.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 1.6rem;
  box-shadow: var(--shadow-sm);
}
.card h2 { font-size: clamp(1.2rem, 1rem + .9vw, 1.5rem); }

/* ---- De feitkaart: een pictogram, een kop en één zin ----
   Onder elkaar op een telefoon kostte dat bijna anderhalf scherm scrollen voor
   vier regels tekst, omdat elke kaart zijn pictogram, zijn kop en zijn tekst
   onder elkaar zet. Op een smal scherm staat het pictogram daarom naast de
   tekst: het is dan een lijstje feiten, wat het ook is. Zodra ze naast elkaar
   passen mag het pictogram weer boven.

   Let op de klasse: dit hing eerst aan `.grid--4 .card`, maar dat raster draagt
   ook de vier dienstkaarten, en die hebben geen pictogram. Daar kwam de kop
   dus in de eerste kolom en de tekst in de tweede. Een regel die ervan uitgaat
   dat er een `.card__ico` in staat, moet dat ook in de selector zeggen. */
/* De tussenruimte was net zo groot als de binnenruimte van de kaart, en dan
   leest een rij kaarten als vier losse doosjes in plaats van als een lijst. */
.grid--4.cards { gap: .8rem; }
.card--fact {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 1rem;
  padding: 1.35rem;
}
.card--fact .card__ico { grid-row: span 2; margin-bottom: 0; padding-top: .15rem; }

@media (min-width: 40em) {
  .card--fact { display: block; padding: 1.5rem; }
  .card--fact .card__ico { margin-bottom: .9rem; }
}
.card h3, .card .subhead { margin-bottom: .35em; }
.card p:last-child { margin-bottom: 0; }
/* Het pictogram bovenin een kaart. Het pictogram is een lijn-svg uit icon(),
   geen plaatje: scherp op elk scherm, geen extra verzoek, en het neemt de
   merkkleur over.

   Het stond in een afgerond vlakje met een lichtblauwe vulling. Dat vlakje is
   weg: de ontwerptaal van dit project is haarlijnen in plaats van gekleurde
   vlakken, en vier van die vlakjes naast elkaar is precies het rijtje
   pictogramtegels dat op elke willekeurige landingspagina staat. Het pictogram
   alleen, wat groter, zegt hetzelfde en telt mee als lijnwerk. */
.card__ico {
  display: block;
  margin-bottom: .9rem;
  color: var(--brand-deep);
}
.card__ico .icon { width: 1.7rem; height: 1.7rem; }

/* De eerste sectie van een binnenpagina is de paginakop. Die krijgt dezelfde
   zachte aanloop als de hero, zodat elke pagina op dezelfde manier begint.
   Op de homepage staat .hero vooraan, dus daar grijpt deze regel niet. */
main > .section:first-child {
  /* Onderaan minder lucht: de paginakop en de eerste sectie erna telden allebei
     hun volle ruimte op, en dan valt er een gat van een kwart scherm tussen. */
  padding-bottom: calc(var(--section-y) * .5);
  background: linear-gradient(180deg, var(--paper) 0%, rgba(242, 247, 251, 0) 85%);
}
/* En de sectie daar meteen onder telt ook maar de helft mee. Op een pagina met
   een korte kop, zoals de sitemap, stond er anders bijna een half scherm niets
   tussen de inleidende zin en de eerste kop. */
main > .section:first-child + .section { padding-top: calc(var(--section-y) * .5); }

.card--link {
  display: flex;
  flex-direction: column;
  height: 100%;
  text-decoration: none;
  color: inherit;
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease);
}
/* Geen translateY erbij: een kaart die twee pixels opspringt laat de rij ernaast
   stilstaan en leest als een kaart die losgeraakt is. De rand die aanzet is
   genoeg om te zien dat het een link is. */
.card--link:hover, .card--link:active {
  border-color: var(--brand);
  box-shadow: var(--shadow);
  color: inherit;
}
/* De tekst in een linkkaart houdt geen eigen ondermarge: .card__more heeft zijn
   eigen ruimte erboven, en samen werd dat een gat van dertig pixels in een
   kaart van drie regels. */
.card--link p { color: var(--ink-soft); }
.card--link > p:not(.card__more) { margin-bottom: 0; }
.card__more {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  margin-top: auto;
  padding-top: .9rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: .95rem;
  color: var(--brand-deep);
}
.card__more .icon { width: 1.05em; height: 1.05em; }
.card--link:hover .card__more { color: var(--brand-dark); text-decoration: underline; }

/* ---- Eerste hulp: het donkere paneel met "wel doen" en "niet doen" ----
   Dit is de tweede beat van de homepage, na de hero. Donker vlak, dezelfde taal
   als het CTA-blok en het menu, zodat de site één systeem blijft. */
/* De korrel ligt als eerste laag boven het verloop, op alle vier de donkere
   vlakken van de site: dit paneel, het CTA-blok, de voet en het menu. Zonder
   korrel is zo'n vlak een dode plek van vierhonderd pixels; met korrel is het
   materiaal. Het kost geen verzoek, geen beweging en geen compositielaag. */
.firstaid {
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 5vw, 3rem);
  background: var(--grain), linear-gradient(180deg, var(--night-900) 0%, var(--night-950) 70%);
  color: var(--on-dark-dim);
}
.firstaid__intro { max-width: 34rem; margin-bottom: clamp(1.75rem, 4vw, 2.5rem); }
.firstaid h2 { color: var(--white); margin-bottom: .5em; }

.eyebrow--light { color: var(--on-dark-dim); }
.eyebrow--light::before { background: var(--brand-light); }

.dodont { display: grid; gap: 1.75rem; }
.dodont__col { padding-top: 1.25rem; border-top: 2px solid var(--on-dark-line); }
.dodont__col--do { border-top-color: rgba(127, 211, 247, .5); }
.dodont__col--dont { border-top-color: rgba(244, 116, 59, .55); }
.dodont__head {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin-bottom: .9rem;
  font-size: 1rem;
  letter-spacing: .01em;
  color: var(--white);
}
.dodont__head .icon { width: 1.15rem; height: 1.15rem; }
.dodont__head--do .icon { color: var(--brand-light); }
.dodont__head--dont .icon { color: var(--accent); }
.dodont ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.dodont li { position: relative; padding-left: 1.1rem; line-height: 1.5; }
.dodont li::before {
  content: '';
  position: absolute;
  left: 0;
  top: .72em;
  width: .4rem;
  height: 1px;
  background: var(--on-dark-line);
}

@media (min-width: 40em) {
  .dodont { grid-template-columns: 1fr 1fr; gap: 2.5rem; }
}

@media (min-width: 62em) {
  .firstaid { display: grid; grid-template-columns: 1fr 1.15fr; gap: 3.5rem; align-items: start; }
  .firstaid__intro { margin-bottom: 0; }
}

/* ---- Genummerde stappen ----
   Hier stond het cijfer klein onder een kort blauw streepje, in een eigen
   kolom, en de kop begon ernaast op een andere hoogte. Dat streepje hing
   nergens aan vast en het cijfer zweefde onder de kop: het las als een fout in
   plaats van als een ontwerp.

   Nu is het een genummerde lijst zoals een genummerde lijst hoort te zijn. Het
   cijfer staat op dezelfde regel als de kop, groot genoeg om te tellen, en de
   haarlijn loopt over de volle breedte van de stap in plaats van alleen boven
   het cijfer. Dat is dezelfde haarlijn als bij de vragen en de feiten, dus de
   stappen horen nu bij de rest van de site. */
.steps { list-style: none; counter-reset: stap; margin: 0; padding: 0; display: grid; gap: 0; }
.steps li {
  counter-increment: stap;
  display: grid;
  grid-template-columns: 1.9rem 1fr;
  gap: 0 1rem;
  align-items: baseline;
  padding: 1.35rem 0;
  border-top: 1px solid var(--line);
}
.steps li::before {
  /* Gewoon 1, 2, 3. "01" suggereert dat er nog een stap 10 komt. */
  content: counter(stap);
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--brand-deep);
  font-variant-numeric: tabular-nums;
}
.steps li:last-child { border-bottom: 1px solid var(--line); }
.steps h3, .steps .subhead { margin: 0 0 .3em; color: var(--ink); }
/* De tekst hoort onder de kop, niet onder het cijfer. */
.steps p { grid-column: 2; margin-bottom: 0; color: var(--ink-soft); }

/* Tekst met beeld ernaast. */
.split { display: grid; gap: clamp(1.75rem, 4vw, 3.5rem); align-items: center; }
.split img { border-radius: var(--r-lg); box-shadow: var(--shadow); width: 100%; }

/* Het donkere blok met de oproep om te bellen. */
.cta {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  /* Ondergrens 1.5rem en niet 2rem: met 2rem was de belknop op 320 pixels 216 breed,
     vijf pixels te smal, en brak het nummer af na "655". */
  padding: clamp(1.5rem, 5vw, 3.5rem);
  background: var(--grain), linear-gradient(180deg, var(--night-900) 0%, var(--night-950) 70%);
  color: var(--on-dark-dim);
}
.cta h2 { color: var(--white); max-width: 18ch; }
.cta p { max-width: 46ch; }
.cta__actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.5rem; }
/* Op een telefoon vullen de twee knoppen de breedte, net als in de hero. Twee
   knoppen van eigen breedte onder elkaar aan de linkerkant lazen als twee losse
   stickers in een groot vlak. Vanaf 48em krijgen ze hun eigen breedte terug,
   want dan is het blok te breed om een knop over te rekken. */
.cta__actions .button { flex: 1 1 13rem; }

/* ============================ 11. LIJSTEN ============================ */

/* Feitenblok op een plaatspagina. */
.facts { margin: 0 0 1.75rem; border-top: 1px solid var(--line); }
.facts > div {
  display: grid;
  gap: .1rem;
  padding: .85rem 0;
  border-bottom: 1px solid var(--line);
}
.facts dt { color: var(--ink-mute); font-size: .92rem; margin: 0; }
.facts dd { margin: 0; color: var(--ink); font-weight: 600; }

/* ---- De route per plaats, op een regiopagina ----
   Dezelfde haarlijnen als de plaatsenlijst. Een oude plaats-url stuurt met een 301
   naar het anker van die plaats hier; :target zet er dan een blauwe lijn voor, zodat
   wie uit Google komt meteen ziet welke regel over zijn plaats gaat. Blauw, want dit
   is de weg vooruit. Het beweegt niet. De scroll-margin houdt de regel onder de
   vaste kopbalk. */
.routes { margin: 0 0 1.5rem; border-top: 1px solid var(--line); }
.route {
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--line);
  scroll-margin-top: calc(var(--nav-h) + 1rem);
}
.route:target { border-left: 2px solid var(--brand); padding-left: 1rem; }
.route h3 {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin: 0 0 .3rem;
}
.route__time {
  color: var(--brand-deep);
  font-family: var(--font-text);
  font-size: .9rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.route__meta { color: var(--ink-mute); font-size: .92rem; margin: 0 0 .35rem; }
.route p:last-child { margin-bottom: 0; }
.route__source { color: var(--ink-mute); font-size: .88rem; max-width: 46rem; }

/* Openingstijden. */
.hours { display: grid; grid-template-columns: 1fr auto; gap: .4rem 1rem; margin: 0 0 1rem; }
.hours dt { color: inherit; }
.hours dd { margin: 0; color: var(--ink); font-weight: 600; text-align: right; white-space: nowrap; }

/* ---- Plaatsen met hun reistijd ----
   Dit waren 69 losse kaartjes met een rand en afgeronde hoeken, elk met een
   marge eromheen. Onder elkaar op een telefoon werd dat een lap van acht
   schermen met doosjes, en een rij doosjes leest als een uitdraai uit een
   database. Het is een lijst, dus het is nu een lijst: haarlijnen tussen de
   regels, verder niets. Dat is dezelfde taal als de vragen en de stappen, en
   het scheelt ruim vierhonderd pixels hoogte.

   De rij blijft 3rem hoog: dat is de ondergrens voor iets waar je met een duim
   op moet kunnen tikken. */
.places {
  list-style: none;
  margin: 0 0 1.5rem;
  padding: 0;
  display: grid;
  gap: 0 2rem;
  border-top: 1px solid var(--line);
}
/* Op de sitemap staan hier negenenzestig plaatsen onder elkaar. Dat was een
   grijze lijst waar je doorheen moest ploegen: de naam en de reistijd stonden
   allebei in dezelfde stille inkt, en de reistijd is juist het gegeven waar de
   bezoeker op zoekt ("hoe ver moet ik rijden").

   Nu draagt de naam het gewicht van een index (Manrope, net als elke kop) en
   staat de reistijd in het blauw dat op deze site de weg vooruit betekent, met
   tabelcijfers zodat de kolom recht blijft. Het chevronnetje is hetzelfde
   haarlijntje als in het kruimelpad: het zegt dat er iets achter zit.
   Op een telefoon is een rij 3,25rem hoog, ruim boven wat een duim nodig heeft. */
/* Een dorp zonder eigen route (places--plain) krijgt dezelfde rij, maar zonder link en
   dus zonder chevron: er zit niets achter. */
.places a, .places--plain li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  min-height: 3.25rem;
  padding: .7rem .25rem;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: -.012em;
  text-decoration: none;
  transition: color .2s var(--ease);
}
.places a:hover, .places a:active { color: var(--brand-deep); }
.places .minutes {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  color: var(--brand-deep);
  font-weight: 600;
  font-size: .9rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Het chevronnetje achter de reistijd. Als ::after en niet als svg per regel:
   negenenzestig keer hetzelfde pictogram in de html is bijna twee kilobyte voor
   iets wat de css in één regel kan tekenen. */
.places a .minutes::after {
  content: '';
  width: .42rem;
  height: .42rem;
  border-top: 1.5px solid var(--brand);
  border-right: 1.5px solid var(--brand);
  transform: rotate(45deg);
  margin-left: .1rem;
}

/* Een lijst met plaatsen staat op de sitemap onder een kopje per reistijdring.
   Het aantal erachter is een telling en geen kop, dus het draagt de inkt en de
   maat van een bijschrift en niet die van de kop waar het naast staat. */
.count {
  font-family: var(--font-text);
  font-size: .88rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-mute);
}
/* Het volgende kopje mag niet tegen de lijst erboven aan plakken. */
.places + h3 { margin-top: 1.9rem; }

/* Veelgestelde vragen. */
.faq { display: grid; gap: 0; border-top: 1px solid var(--line); max-width: 52rem; }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  padding: 1.15rem 0;
  list-style: none;
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.02rem, 1rem + .35vw, 1.2rem);
  letter-spacing: -.015em;
  color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '';
  flex: none;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  border: 1.5px solid var(--line-strong);
  background:
    linear-gradient(var(--brand-deep), var(--brand-deep)) center / .65rem 2px no-repeat,
    linear-gradient(var(--brand-deep), var(--brand-deep)) center / 2px .65rem no-repeat;
  transition: transform .3s var(--ease), border-color .2s var(--ease);
}
.faq summary:hover::after { border-color: var(--brand); }
/* Open: alleen de horizontale streep, dus een minteken. De draaiing was 135
   graden, en een horizontale streep die 135 graden draait is een schuin
   streepje. Dat las als een potloodje, niet als "klap dicht". 180 graden laat
   hem draaien en eindigt weer horizontaal. */
.faq details[open] summary::after {
  transform: rotate(180deg);
  background:
    linear-gradient(var(--brand-deep), var(--brand-deep)) center / .65rem 2px no-repeat;
}
.faq details > *:last-child { margin-bottom: 1.25rem; }
.faq p { max-width: 46em; }

/* ============================ 12. FORMULIER ============================ */

/* Het contactformulier staat in een kaart naast een korte inleiding. Het had een
   vaste breedte van 38rem en stond dan op desktop als een smalle kolom links in
   een lege vlakte. Nu vult het de kaart, en vanaf 40em staan de korte velden
   twee aan twee: voornaam naast achternaam, e-mail naast telefoon. */
.contact-form { display: grid; gap: 1.75rem; }
.contact-form__intro > p:not(.eyebrow) { color: var(--ink-soft); }
.contact-form__card { padding: 1.25rem; }

.form { display: grid; gap: 1.1rem; }
.form__row { display: grid; gap: .35rem; }
.form label { font-weight: 600; color: var(--ink); font-size: .98rem; }
.form .hint { color: var(--ink-mute); font-weight: 400; }

.form input[type='text'],
.form input[type='email'],
.form input[type='tel'],
.form textarea {
  width: 100%;
  min-height: 3rem;
  padding: .75rem .9rem;
  border: 1.5px solid var(--field-line);
  border-radius: var(--r-ctl);
  background: var(--white);
  color: var(--ink);
  font: inherit;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.form textarea { min-height: 9rem; resize: vertical; }
.form input:focus, .form textarea:focus {
  border-color: var(--brand-deep);
  box-shadow: 0 0 0 3px rgba(2, 119, 189, .14);
}
.form [aria-invalid='true'] { border-color: var(--error); background: var(--accent-tint); }

.form__check { display: grid; grid-template-columns: auto 1fr; gap: .75rem; align-items: start; }
.form__check input { width: 1.4rem; height: 1.4rem; margin-top: .25rem; accent-color: var(--brand-deep); }
.form__check label { font-weight: 400; color: var(--ink-soft); }

.error { color: var(--error); font-weight: 600; font-size: .95rem; margin: 0; }

.alert {
  padding: 1.1rem 1.25rem;
  border-radius: var(--r-ctl);
  margin-bottom: 1.5rem;
  border: 1px solid;
  border-left-width: 3px;
}
.alert--error { background: #fffafa; border-color: #e8c4c1; border-left-color: var(--error); color: #7d1c17; }
.alert--ok { background: #f4fbf7; border-color: #bfe3ce; border-left-color: var(--open); color: #0b5236; }
.alert p:last-child { margin-bottom: 0; }
.alert strong { color: inherit; }

.honeypot { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ============================ 13. VOET EN BELBALK ============================ */

.footer {
  background: var(--grain), var(--night-950);
  color: var(--on-dark-dim);
  /* Onderin de ruimte waar de zwevende belbalk in hangt, zodat de voetkleur tot
     de onderrand doorloopt. De balk is 4,5rem hoog inclusief de lucht eronder. */
  padding: var(--section-y) 0 calc(2rem + 4.75rem + env(safe-area-inset-bottom, 0px));
  font-size: 1rem;
}
/* Deze koppen stonden op .74rem met .16em spatiëring: op een telefoon elf en een
   halve pixel in hoofdletters. Dat is de maat van een bijschrift onder een
   grafiek, niet van een kopje boven een lijst met telefoonnummers, en juist
   hoofdletters lezen slechter voor de ogen waar deze site voor gemaakt is.
   Een halve trede groter en minder ver uit elkaar. */
.footer h2, .footer__title {
  font-size: .82rem;
  color: var(--on-dark);
  text-transform: uppercase;
  letter-spacing: .11em;
  margin-bottom: 1rem;
}
.footer a { color: var(--on-dark-dim); text-decoration: none; }
.footer a:hover, .footer a:active { color: var(--white); }
.footer__grid { display: grid; gap: 2.5rem; }
.footer__logo { width: 180px; height: auto; margin-bottom: 1.1rem; }
.footer address { line-height: 1.9; }
.footer address a { color: var(--on-dark); }
.footer__small { font-size: .92rem; color: #7e95a9; }
/* "Op deze site" en "Goed om te weten" zijn twee eigen blokken. Ze stonden samen in
   de laatste kolom, en die werd daardoor twee keer zo lang als de rest: op desktop
   een kolom die onder alles uit hing. Zie de valkuil over de voet. */
.footer__links { list-style: none; margin: 0; padding: 0; display: grid; }
.footer__links a { display: block; padding: .45rem 0; }
.footer__tagline { max-width: 30rem; }

/* De juridische links staan onderin bij de bedrijfsregel en niet meer tussen de
   gewone paginalinks: daar leidden ze af van de weg naar een reparatie. */
.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem 1.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer .hours dd { color: var(--on-dark); }
/* Op 320 pixels passen dag en tijd niet naast elkaar: "Maandag t/m vrijdag" brak over
   twee regels. Daar staat de tijd onder de dag, net als in de smalle kolom op desktop. */
.footer .hours { grid-template-columns: 1fr; gap: 0; }
.footer .hours dd { text-align: left; margin-bottom: .6rem; }
.footer .button--call { background: var(--white); color: var(--ink); margin-top: .35rem; }
.footer .button--call:hover { background: var(--brand-tint); color: var(--brand-dark); }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-items: center;
  justify-content: space-between;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--on-dark-line);
  font-size: .9rem;
}
.footer__bottom p { margin: 0; }
/* Het logo van het moederbedrijf in de lichte versie, rechtstreeks overgenomen
   van vantoorntandtechniek.nl: dat is dezelfde klant en dit is het bestand dat
   zij zelf op hun eigen donkere voet zetten.

   Hier stond het donkere logo op een wit plaatje met een afgeronde rand eromheen,
   want anders verdween het in het donker. Zo'n plaatje is een pleister: het maakt
   van een logo een sticker en het legt een lichte rechthoek midden in een donker
   vlak. De lichte versie heeft dat allemaal niet nodig, want hij is er zelf voor
   gemaakt: 80% van het bestand is doorzichtig en de inkt is gebroken wit. */
.footer__parent img { width: 160px; height: auto; }

/* De vaste belbalk verschijnt pas als de belknop uit de hero uit beeld is. */
/* De belbalk was een strook over de volle breedte, vastgeplakt aan de onderrand.
   Dat is de vorm van een cookiemelding. Nu is het een zwevende balk met ruimte
   eromheen en een echte schaduw: hij hoort bij de bezoeker en niet bij de
   pagina, en je ziet eronder dat de pagina doorloopt. De hoogte en het
   raakvlak blijven gelijk, dus voor een duim verandert er niets. */
.callbar {
  position: fixed;
  left: .7rem;
  right: .7rem;
  bottom: calc(.7rem + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .45rem;
  /* Dekkend wit, geen backdrop-filter: matglas over een halfzichtbare tekst is
     onrustig, en het kost een extra compositielaag bij elke scroll. */
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: calc(var(--r-ctl) + .45rem);
  box-shadow: var(--shadow-lg);
  transform: translateY(calc(100% + 1.4rem));
  opacity: 0;
  transition: transform .4s var(--ease), opacity .3s var(--ease);
}
.callbar.is-visible { transform: none; opacity: 1; }
/* Zonder javascript staat de balk er gewoon. */
html:not(.js) .callbar { transform: none; opacity: 1; }
.callbar .button--call { flex: 1; min-height: 2.9rem; }

/* De knop naar boven staat in de belbalk, rechts naast het telefoonnummer. Een
   losse knop die over de tekst zweeft ziet er altijd uit als een sticker, en hij
   moest van kleur wisselen om leesbaar te blijven boven de donkere blokken. In de
   balk staat hij op een vlak dat er toch al is, dus geen van beide speelt nog. */
.totop {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.9rem;
  height: 2.9rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--ink-soft);
  background: var(--white);
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.totop .icon { width: 1.3rem; height: 1.3rem; }
.totop:hover, .totop:active { border-color: var(--brand); color: var(--brand-deep); }

/* ============================ 14. RESPONSIVE ============================ */

/* Vanaf 360 pixels staan de twee linklijsten van de voet naast elkaar. Onder elkaar
   maakten ze de voet op een telefoon ruim 1600 pixels lang. De linkerlijst is zo
   breed als zijn langste regel, de rechter krijgt de rest; een lange titel als
   "Kunstgebit gebroken, wat nu?" loopt daar over twee regels, en dat leest beter
   dan nog eens tweehonderd pixels scrollen. */
@media (min-width: 22.5em) {
  .footer__grid { grid-template-columns: auto 1fr; column-gap: 1.75rem; }
  .footer__grid > :not(.footer__links-block) { grid-column: 1 / -1; }
  .footer .hours { grid-template-columns: 1fr auto; gap: .4rem 1rem; }
  .footer .hours dd { text-align: right; margin-bottom: 0; }
}

@media (min-width: 30em) {
  .m-panel { width: 22rem; }
  .header__logo img { height: 38px; }
  .header.is-scrolled .header__logo img { height: 34px; }
  .places { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 40em) {
  .grid--2 { grid-template-columns: repeat(2, 1fr); }
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .facts > div { grid-template-columns: 15rem 1fr; gap: 1rem; align-items: baseline; }
  /* Twee kolommen: het merkblok over de hele breedte, daaronder contact naast de
     openingstijden en de twee linklijsten naast elkaar. Vier blokken van ongeveer
     gelijke lengte, dus geen kolom die onder de andere uit hangt. */
  .footer__grid { grid-template-columns: repeat(2, 1fr); column-gap: 2.5rem; }
  .footer__grid > :not(.footer__links-block) { grid-column: auto; }
  /* Met .footer__grid ervoor, anders wint de regel hierboven: :not() telt mee. */
  .footer__grid > .footer__brand { grid-column: 1 / -1; }
  /* De onderste balk: de bedrijfsregel met de juridische links eronder links, het
     logo van Van Toorn rechts ernaast in het midden. */
  .footer__bottom { display: grid; grid-template-columns: 1fr auto; gap: .9rem 2rem; }
  .footer__parent { grid-column: 2; grid-row: 1 / span 2; }
  /* De belofte onder de hero wordt hier een streep van drie in plaats van drie
     regels onder elkaar. */
  .hero__promise .checks { grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
  .contact-form__card { padding: 2rem; }
  /* Alles in het formulier beslaat de hele breedte, behalve de korte velden. */
  .form { grid-template-columns: 1fr 1fr; gap: 1.1rem 1.25rem; }
  .form > * { grid-column: 1 / -1; }
  .form > .form__row--half { grid-column: auto; }
}

@media (min-width: 48em) {
  :root { --nav-h: 72px; }
  /* Twee kolommen routes: op een breed scherm is een regel anders een halve meter lang. */
  .routes { display: grid; grid-template-columns: 1fr 1fr; gap: 0 2.5rem; }
  /* Geen zwevende belbalk meer, alleen de knop naar boven rechtsonder. Die
     heeft nog wel ruimte nodig om niet over de onderste regel te liggen. */
  .footer { padding-bottom: 4rem; }
  /* Het nummer staat hier in de kopbalk, dus de belknop in de balk kan weg. Wat
     overblijft is een doorzichtige houder onderin voor de knop naar boven. */
  .callbar {
    left: 0;
    right: 0;
    bottom: 0;
    justify-content: flex-end;
    padding: 0 var(--pad) var(--pad);
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    pointer-events: none;
  }
  .callbar .button--call { display: none; }
  .totop { pointer-events: auto; box-shadow: 0 10px 26px -18px rgba(10, 31, 51, .9); }
  .header__logo img { height: 44px; }
  .header.is-scrolled .header__logo img { height: 38px; }
  .header__call { display: inline-flex; padding: .6rem 1rem; min-height: 44px; }
  /* Tekst naast beeld, en de belofte als streep over de volle breedte eronder. */
  .hero__grid {
    grid-template-columns: 1.02fr .98fr;
    grid-template-areas: 'tekst beeld' 'belofte belofte';
  }
  .split { grid-template-columns: 1fr 1fr; }
  .split--reverse .split__media { order: -1; }
  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--4.cards { gap: 1.1rem; }
  .cta__actions .button { flex: 0 0 auto; }
  /* Drie stappen in twee kolommen laat de derde alleen achter. Dus of onder
     elkaar, of alle drie naast elkaar, niets ertussenin. */
  .steps { grid-template-columns: repeat(3, 1fr); gap: 2rem 1.75rem; }
  .places { grid-template-columns: repeat(3, 1fr); }
}

/* Vanaf hier past het menu naast het logo en verdwijnt de hamburger. */
@media (min-width: 62em) {
  .nav { display: block; }
  .header__toggle { display: none; }
  .offcanvas { display: none; }
  .header__call { padding: .75rem 1.25rem; }
  .header__call-short { display: none; }
  .header__call-long { display: inline; white-space: nowrap; }
  /* Het merkblok wordt een strook bovenin: logo, zin en belknop op een rij, met een
     haarlijn eronder. Daaronder vier kolommen die zo breed zijn als hun inhoud, met
     de ruimte ertussen verdeeld. Vier gelijke kolommen waren op 992 pixels zo'n 190
     pixels breed, en dan brak "Kunstgebit gebroken, wat nu?" over twee regels; de
     langste regels samen zijn hier ongeveer 680 pixels, er is 890. */
  .footer__grid { grid-template-columns: repeat(4, auto); justify-content: space-between; gap: 2.5rem 3rem; }
  .footer__brand {
    display: flex;
    align-items: center;
    gap: 1.5rem 3rem;
    padding-bottom: 2.5rem;
    border-bottom: 1px solid var(--on-dark-line);
  }
  .footer__brand .footer__logo { margin-bottom: 0; flex: none; }
  .footer__brand .footer__tagline { margin: 0; }
  .footer__brand .button--call { margin: 0 0 0 auto; flex: none; }
  /* In vier kolommen is de kolom openingstijden smal: dag en tijd naast elkaar
     passen dan niet en "Maandag t/m vrijdag" brak over twee regels. De tijd onder
     de dag leest in een smalle kolom rustiger. */
  .footer .hours { grid-template-columns: 1fr; gap: 0; }
  .footer .hours dd { text-align: left; margin-bottom: .6rem; }
  .places { grid-template-columns: repeat(4, 1fr); }
  /* Vier kaarten naast elkaar pas hier. Op 768 pixels bleef er 170 pixels per
     kaart over en dan breekt de kop van een kaart over drie regels. */
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
  /* De inleiding blijft staan terwijl je langs de velden scrolt. */
  .contact-form { grid-template-columns: minmax(0, 1fr) minmax(0, 1.8fr); gap: 3.5rem; align-items: start; }
  .contact-form__intro { position: sticky; top: 6.5rem; }
  .contact-form__card { padding: 2.5rem; }
}

/* De onderste balk op een rij pas vanaf hier: de bedrijfsregel, de drie juridische
   links en het logo van Van Toorn zijn samen zo'n 980 pixels, en daaronder viel het
   logo los op een eigen regel. */
@media (min-width: 75em) {
  .footer__bottom { display: flex; }
}

/* ============================ 15. MOTION ============================ */

/* ---- Inhoud die binnenkomt terwijl je scrolt ----
   Wat het de bezoeker vertelt: dat er nog iets volgt, en waar het volgende blok
   begint. Een lange pagina waar alles er altijd al staat leest als een document;
   een pagina waar elk blok bij binnenkomst zijn laatste twaalf pixels nog moet
   afleggen leest als een pagina die gemaakt is. Meer dan dat mag het niet doen:
   het is veertien pixels en een kwartseconde, geen voorstelling.

   Hoe: met een scrolltijdlijn in de css, niet met javascript. Geen
   IntersectionObserver, geen tweede scrollluisteraar, geen klasse die erbij
   gezet moet worden, en het draait in de browser buiten de hoofddraad om. Kan de
   browser het niet, dan staat alles er gewoon: @supports laat de hele regel dan
   weg en niemand ziet een halfdoorzichtig blok.

   Wat er bewust NIET meedoet: alles wat bij het laden al in beeld staat. De
   hero, de paginakop van een subpagina en het kruimelpad. Een element dat bij
   het openen halverwege zijn animatie staat, staat halverwege zijn doorzichtigheid,
   en het beeld in de hero is bovendien het element waar Google de LCP aan meet.
   Daar valt niets te winnen en een meting te verliezen. */
@supports (animation-timeline: view()) {
  /* screen erbij: op papier bestaat scrollen niet, en een blok dat nooit in beeld
     is gekomen zou dan blanco uit de printer komen. Zie de valkuilen. */
  @media screen and (prefers-reduced-motion: no-preference) {
    .section__head,
    .card,
    .steps li,
    .split > *,
    .places,
    .faq,
    .notice,
    .firstaid,
    .cta {
      animation: opkomen linear both;
      animation-timeline: view();
      /* Klaar als het blok voor bijna de helft binnen is: daarna leest het als
         iets dat achterloopt op je duim. */
      animation-range: entry 0% entry 45%;
    }

    /* Wat bij het laden al in beeld staat, doet niet mee. */
    .hero *,
    main > .section:first-child .section__head { animation: none; }
  }
}

@keyframes opkomen {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
  }
  .m-panel, .callbar { transition: none; }
}
