/* ayoubbouders.nl — "levendig & opvallend", laag bovenop style.css.
 * LEVENDIG-20260926
 *
 * Waarom een apart bestand en niet in style.css: die stylesheet is 57 KB, loopt netjes via
 * tokens en wordt ook door anderen aangeraakt. Door hier alléén te herdefiniëren blijft het
 * origineel intact en is deze hele richting terug te draaien door één <link> uit layout.php
 * te halen. Dat is geen nette-jongensregel maar praktisch: een smaakkeuze moet omkeerbaar zijn.
 *
 * De opzet volgt style.css: alles via tokens, niets hardgecodeerd, zodat de thema-schakelaar
 * (licht/donker) en de zes accentkleuren blijven werken. Een kleur die ik hier vastzet, breekt
 * vijf van de zes accenten — daarom staat er nergens een letterlijke hex behalve in de
 * neutrale gloedlagen.
 *
 * Drie principes:
 *   1. KLEUR ALS VLAK, niet als randje. Accent krijgt oppervlak (hero-gloed, gradient-knoppen,
 *      gekleurde kaartkoppen) in plaats van alleen een lijntje van 1px.
 *   2. DIEPTE. Zachte, gekleurde schaduw i.p.v. grijze; kaarten liften bij aanwijzen.
 *   3. BEWEGING DIE IETS ZEGT. Alleen op wat je kunt aanwijzen of wat binnenkomt — nooit
 *      eindeloos knipperen. Alles uit bij prefers-reduced-motion (onderaan dit bestand).
 */

/* ═══════════════════════════════════════════════════ 1. rijkere kleur-tokens */

:root {
  /* Gekleurde schaduw i.p.v. grijze: een schaduw in de accentkleur laat een kaart
     'zweven' in plaats van 'vuil' lijken. Drie lagen = zachte afloop. */
  --shadow: 0 2px 4px -2px color-mix(in srgb, var(--acc) 18%, transparent),
            0 12px 24px -12px color-mix(in srgb, var(--acc) 22%, transparent),
            0 28px 60px -30px color-mix(in srgb, var(--acc) 30%, transparent);
  --shadow-lift: 0 4px 8px -3px color-mix(in srgb, var(--acc) 22%, transparent),
                 0 18px 36px -14px color-mix(in srgb, var(--acc) 28%, transparent),
                 0 44px 80px -34px color-mix(in srgb, var(--acc) 34%, transparent);

  /* Het verloop dat overal terugkomt. Eén definitie, zodat knoppen, koppen en vlakken
     dezelfde kleurbeweging maken en het geheel als één systeem leest. */
  --verloop: linear-gradient(115deg, var(--acc) 0%, var(--acc-2) 100%);
  --verloop-diep: linear-gradient(115deg, var(--acc-dk) 0%, var(--acc) 55%, var(--acc-2) 100%);

  /* CONTRAST-AAN-HET-EIND-20260926 — gemeten, niet ingeschat.
     De markeerstift in de hero gebruikte --verloop-diep, dat eindigt op --acc-2: de lichtste
     kleur van het stel. Witte letters op dát uiteinde haalden 2,11:1 (mint) tot 2,86:1
     (blauw, de standaard) — onder de 3:1 die WCAG voor grote tekst vraagt. Vier van de zes
     accenten zakten erdoor. Het viel niet op omdat de LINKERkant er prima uitziet; de fout
     zit alleen aan het eind van het verloop, precies waar de laatste letters staan.
     Dit verloop blijft daarom over de hele lengte donker: het loopt van --acc-dk naar een
     met zwart verdonkerde --acc. Nog steeds kleur en beweging, maar wit blijft leesbaar.
     🪤 Bij het aanpassen: meet opnieuw met een pixelmonster op ~94% breedte. Het oog is hier
     een slechte rechter — 2,9:1 ziet er prima uit en is het niet. */
  --verloop-markeer: linear-gradient(115deg,
                     color-mix(in srgb, var(--acc-dk) 94%, #000) 0%,
                     color-mix(in srgb, var(--acc) 70%, #000) 100%);

  --radius: 18px;
  --radius-s: 12px;
}

/* ═════════════════════════════════════════ 2. achtergrond met kleur en diepte */

/* Een vlakke achtergrondkleur is het verschil tussen "een site" en "een sjabloon".
   Twee zachte kleurwolken geven diepte zonder de leesbaarheid aan te tasten; ze staan
   vast t.o.v. het document (niet fixed) zodat scrollen niet stottert op mobiel. */
body { position: relative; }
body::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 190vh;
  z-index: -1; pointer-events: none;
  background:
    radial-gradient(70ch 60ch at 82% -6%,  color-mix(in srgb, var(--acc-2) 26%, transparent) 0%, transparent 62%),
    radial-gradient(60ch 55ch at -8% 18%,  color-mix(in srgb, var(--acc)   20%, transparent) 0%, transparent 60%),
    radial-gradient(80ch 50ch at 50% 92%,  color-mix(in srgb, var(--acc-2) 14%, transparent) 0%, transparent 65%);
}
:root[data-theme="dark"] body::before { opacity: .55; }

/* ═══════════════════════════════════════════════════════════════ 3. de hero */

/* De bestaande .hero heeft al ::before/::after voor gloed. Die maken we groter en
   kleuriger in plaats van ze te vervangen — anders vecht deze laag met het origineel. */
.hero::before { opacity: 1.35; filter: saturate(1.35); }
.hero::after  { opacity: 1.25; filter: saturate(1.3); }

/* De accentwoorden in de kop als markeerstift: een kleurvlak met witte letters, niet
   alleen gekleurde letters. Dat is de "opvallend"-keuze — het oog springt erheen, en
   wit-op-accent is op een lichte achtergrond ook het contrastrijkst.
   VEEG-VOLGT-DE-REGEL-20260926: de eerste poging was een absoluut geplaatste ::after onder
   het woord. Dat ging mis zodra de kop over twee regels brak — .grad is inline, dus de
   ::after nam de omhullende rechthoek van béíde regels en belandde als los blauw streepje
   naast "oplevert". Een achtergrond hoort bij de tekst zelf en breekt dus netjes mee.
   box-decoration-break:clone geeft elke regel zijn eigen afgeronde vlak — precies wat je
   met een markeerstift zou doen. Zonder die regel krijgt alleen de eerste regel een ronde
   linkerhoek en de laatste een ronde rechter, met een rare doorlopende balk ertussen. */
.hero h1 .grad {
  background: var(--verloop-markeer);
  -webkit-background-clip: border-box; background-clip: border-box;
  -webkit-text-fill-color: #fff; color: #fff;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  padding: .04em .22em .1em;
  margin-inline: -.06em;
  border-radius: .28em;
  text-decoration: none;
  box-shadow: 0 10px 26px -12px color-mix(in srgb, var(--acc) 70%, transparent);
}

/* Het lead-blok mag iets groter en rustiger: grote koppen vragen om lucht eronder. */
.hero p.lead { font-size: clamp(1.06rem, 1.7vw, 1.28rem); line-height: 1.6; }

/* ══════════════════════════════════════════════════════════ 4. knoppen */

.btn {
  border-radius: 999px;
  font-weight: 650;
  letter-spacing: -.01em;
  position: relative; overflow: hidden;
  transition: transform .16s cubic-bezier(.34,1.56,.64,1), box-shadow .2s ease, filter .16s ease;
}

.btn-primary {
  /* KNOPCONTRAST-20260926 — gemeten met een pixelmonster onder het label, niet geschat.
     Hier stond --verloop (--acc → --acc-2). Wit haalde aan het BEGIN van het label 4,58:1,
     in het midden 3,46:1 en aan het EIND 2,58:1 — tweederde van elk CTA-label zat dus onder
     de 4,5:1 die normale tekst nodig heeft. Het valt niet op omdat de linkerkant er goed
     uitziet; de laatste letters verdwijnen.
     --verloop-markeer loopt van --acc-dk naar een verdonkerde --acc en blijft over de hele
     lengte donker genoeg. Nog steeds kleur en beweging, maar leesbaar tot het laatste teken. */
  background: var(--verloop-markeer);
  color: #fff !important;           /* huisregel: altijd wit op de primaire knop */
  border-color: transparent;
  box-shadow: 0 2px 6px -1px color-mix(in srgb, var(--acc) 45%, transparent),
              0 10px 24px -10px color-mix(in srgb, var(--acc) 60%, transparent);
}
.btn-primary:hover {
  transform: translateY(-2px);
  filter: brightness(1.06) saturate(1.1);
  box-shadow: 0 4px 10px -2px color-mix(in srgb, var(--acc) 50%, transparent),
              0 16px 34px -12px color-mix(in srgb, var(--acc) 70%, transparent);
}
/* glans die één keer overloopt bij aanwijzen — geen doorlopende animatie */
.btn-primary::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 30%,
              color-mix(in srgb, #fff 42%, transparent) 48%, transparent 66%);
  transform: translateX(-120%);
  transition: transform .62s cubic-bezier(.4,0,.2,1);
}
.btn-primary:hover::after { transform: translateX(120%); }

.btn-ghost {
  border-color: color-mix(in srgb, var(--acc) 32%, var(--line));
  background: color-mix(in srgb, var(--bg-2) 70%, transparent);
  backdrop-filter: blur(6px);
}
.btn-ghost:hover {
  transform: translateY(-2px);
  border-color: var(--acc);
  background: color-mix(in srgb, var(--acc) 8%, var(--bg-2));
  box-shadow: 0 10px 24px -14px color-mix(in srgb, var(--acc) 70%, transparent);
}

/* ══════════════════════════════════════════════════════════════ 5. kaarten */

.card {
  border-radius: var(--radius);
  position: relative;
  transition: transform .22s cubic-bezier(.34,1.3,.64,1), box-shadow .22s ease, border-color .22s ease;
}
/* Gekleurde bovenrand die bij aanwijzen oplicht: geeft elke kaart een 'kop'
   zonder extra markup en zonder dat het in rust schreeuwt. */
.card::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: var(--verloop);
  border-radius: var(--radius) var(--radius) 0 0;
  opacity: 0; transition: opacity .22s ease;
}
.card:hover {
  transform: translateY(-5px);
  border-color: color-mix(in srgb, var(--acc) 34%, var(--line));
  box-shadow: var(--shadow-lift);
}
.card:hover::before { opacity: 1; }

/* Het icoon in een kaart krijgt een gekleurd vlakje: veel meer aanwezigheid dan
   een los emoji op wit, en het bindt de kaarten visueel aan elkaar. */
.card .icon {
  width: 46px; height: 46px; display: grid; place-items: center;
  border-radius: var(--radius-s);
  background: color-mix(in srgb, var(--acc) 12%, transparent);
  font-size: 1.35rem; margin-bottom: 1rem;
  transition: background .22s ease, transform .22s ease;
}
.card:hover .icon {
  background: var(--verloop);
  transform: scale(1.06) rotate(-3deg);
}

/* ══════════════════════════════════════════════ 6. "waar speelt het"-tegels */

.pick-card {
  border-radius: var(--radius-s);
  position: relative; overflow: hidden;
  transition: transform .18s cubic-bezier(.34,1.4,.64,1), box-shadow .2s ease,
              border-color .2s ease, background .2s ease;
}
.pick-card::before {
  content: ""; position: absolute; inset: 0;
  background: var(--verloop); opacity: 0;
  transition: opacity .2s ease;
}
.pick-card > * { position: relative; }
.pick-card:hover {
  transform: translateY(-3px) scale(1.015);
  border-color: transparent;
  box-shadow: var(--shadow);
}
.pick-card:hover::before { opacity: 1; }
.pick-card:hover .pick-card-k,
.pick-card:hover .pick-card-s { color: #fff; }

/* ═══════════════════════════════════════════════════════════════ 7. cijfers */

/* De cijfers zijn het harde bewijs op deze site. Die mogen dus het meest opvallen. */
.stat .v {
  /* In het LICHTE thema is --verloop-diep goed (5,9–6,5:1), maar in het DONKERE thema loopt
     hij naar --acc-dk toe en dat is juist donkerder dan de kaart eronder: gemeten 2,62–2,93:1,
     onder de 3:1 die grote tekst nodig heeft. Daarom hieronder een eigen verloop per thema. */
  background: var(--verloop-diep);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: -.03em;
}
:root[data-theme="dark"] .stat .v {
  background: linear-gradient(115deg, var(--acc-lt) 0%, var(--acc-2) 100%);
}
.stat {
  padding: 1.4rem 1.2rem;
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--bg-2) 78%, transparent);
  border: 1px solid var(--line-soft);
  transition: transform .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.stat:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--acc) 30%, var(--line));
  box-shadow: var(--shadow);
}

/* ═══════════════════════════════════════════════════════ 8. sectiekoppen */

/* Een klein gekleurd streepje boven elke kop: geeft ritme aan een lange pagina,
   zodat je bij het scrollen voelt waar een nieuw onderwerp begint. */
.section-head > h2::before {
  content: ""; display: block;
  width: 46px; height: 4px; border-radius: 999px;
  background: var(--verloop);
  margin-bottom: .9rem;
}
.section-head h2 { letter-spacing: -.03em; }

/* De "alt"-secties krijgen kleur in plaats van alleen een andere grijstint,
   zodat afwisseling ook echt als afwisseling leest. */
.section.alt {
  background: linear-gradient(180deg,
              color-mix(in srgb, var(--acc) 5%, var(--bg-2)) 0%,
              var(--bg-2) 45%,
              color-mix(in srgb, var(--acc-2) 4%, var(--bg-2)) 100%);
}

/* ══════════════════════════════════════════════════════════ 9. eyebrow/chip */

.eyebrow {
  background: color-mix(in srgb, var(--acc) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--acc) 24%, transparent);
  color: var(--acc-ink);
  font-weight: 700;
}
.eyebrow .dot {
  background: var(--verloop);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--acc) 18%, transparent);
}

.chip {
  border-radius: 999px;
  transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease;
}
.chip:hover {
  transform: translateY(-2px);
  border-color: color-mix(in srgb, var(--acc) 40%, var(--line));
  box-shadow: 0 8px 20px -12px color-mix(in srgb, var(--acc) 60%, transparent);
}

/* ═══════════════════════════════════════════════════════ 10. vinkjes */

/* Het vinkje wordt een gevuld rondje: leest sneller als "geregeld" dan een kaal streepje. */
.checks li::before {
  background: var(--verloop);
  color: #fff;
}

/* ══════════════════════════════════════════════════════ 11. binnenkomen */

/* De bestaande .reveal schuift 16px omhoog. Iets meer afstand en een vleugje schaal
   maakt het merkbaar zonder traag te worden. */
@media (prefers-reduced-motion: no-preference) {
  .reveal { transform: translateY(22px) scale(.995); transition: opacity .6s ease, transform .6s cubic-bezier(.22,.9,.3,1); }
  .reveal.in { transform: none; }
}

/* ═════════════════════════════════════════════════════ 12. rust bewaren */

/* Wie in zijn systeem heeft staan dat beweging hem hindert, krijgt hier alles stil.
   Dat is geen extraatje: voor mensen met evenwichts- of migraineklachten is een
   bewegende pagina echt onbruikbaar. */
@media (prefers-reduced-motion: reduce) {
  .btn, .card, .pick-card, .stat, .chip, .card .icon { transition: none !important; }
  .btn-primary::after { display: none; }
  .btn:hover, .card:hover, .pick-card:hover, .stat:hover, .chip:hover { transform: none !important; }
  .card:hover .icon { transform: none !important; }
}

/* Printen: alle gloed en kleurvlakken eruit, anders kost één pagina een halve cartridge
   en wordt gradient-tekst onleesbaar (transparante letters op wit papier). */
@media print {
  body::before { display: none !important; }
  .hero h1 .grad, .stat .v {
    background: none !important; -webkit-text-fill-color: #111 !important; color: #111 !important;
  }
  .hero h1 .grad::after { display: none !important; }
  .card::before, .pick-card::before, .section-head > h2::before { display: none !important; }
  .section.alt { background: none !important; }
}

/* ═══════════════════════════════════════ 13. categoriebalk kennisbank */

/* Hoort bij KB-CATEGORIEEN-20260926 in index.php: de ingangen naar de 450 uitlegpagina's.
   Hergebruikt .chip (staat al in style.css en is hierboven levendig gemaakt), dus hier
   alleen de plaatsing en het telnummertje. */
.kb-cats {
  display: flex; flex-wrap: wrap; gap: .55rem;
  margin: -1rem 0 2rem;
}
.kb-cats .chip { font-weight: 600; }
.kb-cats-n {
  display: inline-grid; place-items: center;
  min-width: 1.5em; height: 1.5em; padding: 0 .35em;
  margin-left: .1rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--acc) 15%, transparent);
  color: var(--acc-ink);
  font-size: .78rem; font-weight: 700; font-variant-numeric: tabular-nums;
}
.kb-cats .chip:hover .kb-cats-n {
  background: var(--verloop); color: #fff;
}

/* ══════════════════════════════════ 14. kaartrijen swipebaar op telefoon */

/* SWIPE-OP-TELEFOON-20260926 — gemeten probleem, geen smaakkwestie.
 *
 * De homepage was op een iPhone 13 ruim 17.000 px lang. Eén sectie nam daarvan 3.554 px
 * (21%): de kennisbank, omdat een raster van `auto-fill, minmax(280px, 1fr)` op een scherm
 * van 390 px terugvalt naar één kolom. Acht kaarten onder elkaar = acht keer ~440 px.
 * Datzelfde geldt voor nieuws en portfolio.
 *
 * Onder elkaar zetten is de gebruikelijke oplossing en precies de verkeerde: het maakt de
 * pagina langer naarmate je MEER laat zien, dus het straft inhoud af. Een horizontaal
 * schuivende rij kost één kaarthoogte, ongeacht het aantal kaarten — en veegt op een
 * telefoon van nature.
 *
 * Bewust zonder JavaScript: scroll-snap doet het werk. Daardoor blijft het werken met
 * toetsenbord (pijltjes), met een schermlezer (het is gewoon een rij artikelen in
 * documentvolgorde) en als er iets misgaat in app.js.
 *
 * 88vw i.p.v. 100vw: de volgende kaart piept net over de rand. Zonder dat randje ziet een
 * bezoeker niet dát er meer is en veegt hij nooit — dan heb je de inhoud alsnog verstopt.
 */
@media (max-width: 1000px) {
  .home-kb-grid,
  .news-grid,
  .portfolio-grid,
  .portfolio-grid-lg {
    display: flex;
    grid-template-columns: none;          /* het grid-raster uitzetten */
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 1.25rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;                /* de balk zelf weg; de kaartrand toont al dat er meer is */
    /* van rand tot rand vegen, terwijl de kaarten met de tekst uitgelijnd blijven */
    margin-inline: calc(50% - 50vw);
    padding-inline: calc(50vw - 50% + .1px);
    padding-bottom: .5rem;
  }
  .home-kb-grid::-webkit-scrollbar,
  .news-grid::-webkit-scrollbar,
  .portfolio-grid::-webkit-scrollbar,
  .portfolio-grid-lg::-webkit-scrollbar { display: none; }

  .home-kb-grid > *,
  .news-grid > *,
  .portfolio-grid > *,
  .portfolio-grid-lg > * {
    flex: 0 0 88vw;
    max-width: 88vw;
    scroll-snap-align: start;
  }

  /* De fade-in hoort bij verticaal binnenscrollen: je scrollt, er komt iets op. In een
     zijwaartse rij staan de kaarten er al — daar voegt hij niets toe en kan hij alleen maar
     inhoud kosten (gemeten: 17 kaarten bleven leeg na volledig doorvegen). Zie
     ONTHULLEN-MAG-NOOIT-VERBERGEN-20260927 in app.js voor het vangnet aan de andere kant. */
  .home-kb-grid > .reveal,
  .news-grid > .reveal,
  .portfolio-grid > .reveal,
  .portfolio-grid-lg > .reveal { opacity: 1; transform: none; }
}

/* TABLET-WAS-HET-LANGST-20260926 — gemeten, en het tegenovergestelde van wat je verwacht.
 * Met de grens op 700px was een tablet de SLECHTSTE maat van allemaal: op 768px viel het
 * raster terug op twee kolommen en werd de pagina 12.361 px — lánger dan diezelfde pagina op
 * een telefoon van 390 px (10.021 px met de veegrij). De veegrij loopt daarom door tot 1000px.
 * Daarboven passen er vier kaarten naast elkaar en is een gewoon raster juist beter.
 * Op tablet twee kaarten tegelijk (46vw), zodat de rij niet leeg oogt op een breed scherm. */
@media (min-width: 701px) and (max-width: 1000px) {
  .home-kb-grid > *,
  .news-grid > *,
  .portfolio-grid > *,
  .portfolio-grid-lg > * {
    flex: 0 0 46vw;
    max-width: 46vw;
  }
}

/* Wie liever niet veegt of een muis gebruikt, moet nog steeds bij alles kunnen: onder de
   rij staat daarom altijd de knop naar de volledige lijst (die stond er al in de HTML). */

/* OVERZICHT-IS-GEEN-VEEGRIJ-20260927 — de veegrij hierboven sloeg door naar pagina's waar hij
 * juist schaadt. Gemeten op een iPhone 13: op /portfolio.php stond 1 van de 17 kaarten in beeld
 * (rij 6.162 px breed), op /kennisbank.php 1 van de 24 (rij 8.681 px). Verticaal scrollen leverde
 * daar dus niets op — de hele inhoud van de pagina zat achter een zijwaartse veegbeweging.
 *
 * 🪤 Het verschil is niet de kaart maar de ROL van de lijst. Op de homepage is de rij een
 * SELECTIE met een "bekijk alles"-knop eronder: mist de bezoeker kaart 5, dan mist hij niets.
 * Op een overzichtspagina IS de lijst de pagina, en daar verwacht iemand die er bewust
 * naartoe klikte juist te scrollen. Dezelfde CSS-klasse, tegengestelde behoefte.
 *
 * Terug naar één kolom zou de eerste fout herhalen (24 × ~440 px = 10.500 px). Daarom een
 * LIJSTweergave: beeld links, tekst rechts. ~128 px per rij i.p.v. ~440, alles verticaal
 * bereikbaar, en de bezoeker overziet er vijf tegelijk in plaats van één.
 */
@media (max-width: 1000px) {
  .is-overzicht {
    display: grid;
    grid-template-columns: 1fr;
    gap: .75rem;
    overflow-x: visible;
    scroll-snap-type: none;
    margin-inline: 0;
    padding-inline: 0;
  }
  .is-overzicht > * {
    flex: initial;
    max-width: none;
    display: grid;
    grid-template-columns: 104px 1fr;
    align-items: start;
    gap: 0;
    padding: 0;
    overflow: hidden;
  }

  /* 🪤 Alleen `grid-template-columns` zetten was NIET genoeg en de fout was stil: een kaart heeft
   * vijf kinderen (beeld, label, titel, samenvatting, link), en die vullen het raster gewoon van
   * links naar rechts door. De titel landde daardoor in kolom 1 — een cel van 103 px — en werd
   * 122 px hoog over vijf regels. Kaarthoogte 300 px i.p.v. de bedoelde 128, dus de pagina werd
   * juist LANGER dan met de veegrij. Elk kind moet expliciet zijn plek krijgen. */
  .is-overzicht > * > * { grid-column: 2; min-width: 0; }

  /* het beeld: vast en klein links, over de volle hoogte van de rij.
   * 🪤 `aspect-ratio: 1/1` + `min-height: 104px` leek hier logisch en kostte 70 px per rij:
   * een vierkant van 104 px geeft het beeld een VASTE hoogte, en een item dat rijen spant duwt
   * die hoogte in de eerste rij. Rij 1 werd dus 104 px voor een label van 34 px. `align-self:
   * stretch` zonder eigen hoogte laat het beeld juist volgen wat de tekst nodig heeft. */
  .is-overzicht .kb-card-shot,
  .is-overzicht .portfolio-shot {
    grid-column: 1;
    /* 🪤 `grid-row: 1 / -1` deed hier NIETS: lijn -1 is de laatste lijn van het EXPLICIETE
     * raster, en dat bestaat hier niet (er is alleen `grid-template-columns`). Het beeld spande
     * dus één rij en werd 54 px hoog naast 176 px tekst. `span` rekent wél door in een
     * impliciet raster; 6 is ruim genoeg voor de vijf delen van de langste kaart. */
    grid-row: 1 / span 6;
    align-self: stretch;
    margin: 0;
    border: 0;
    border-radius: 0;
    aspect-ratio: auto;
    height: auto;
    min-height: 0;
  }

  /* Een liggend beeld (16:9) in een staand vak van 104x156 knipt met `cover` ruim de helft weg —
   * en standaard gebeurt dat aan BEIDE zijkanten, dus juist de linkerkant waar op een
   * websitescreenshot het logo staat en op een kennisbank-cover de kop begint. Gemeten: er stond
   * "rtner voor al uw" en "gina's voor restaurar" in beeld. Links-boven uitlijnen houdt het
   * herkenbare deel heel. */
  .is-overzicht .kb-card-shot img,
  .is-overzicht .portfolio-shot img { object-position: left top; }

  /* De kennisbankcover komt in de lijst uit een <picture> (staande variant zonder titel, zie
     BEELD-IN-EEN-KLEIN-VAK-20260927). Die is al op maat, dus juist NIET links uitsnijden. */
  .is-overzicht .kb-card-shot img { object-position: center; }

  /* <picture> is standaard een inline-element en zou hier tussen de link en de afbeelding gaan
     zitten: de link stretcht wel, de picture niet, en dan valt de afbeelding terug op haar
     eigen hoogte. `display: contents` laat de opmaak precies zo werken alsof de wrapper er
     niet is — de <img> blijft rechtstreeks reageren op de regels van .kb-card-shot. */
  .kb-card-shot picture { display: contents; }

  .is-overzicht .news-card-meta,
  .is-overzicht .news-card-title,
  .is-overzicht .news-card-excerpt,
  .is-overzicht .news-card-more { padding-left: .85rem; padding-right: .85rem; }
  .is-overzicht .news-card-meta  { padding-top: .7rem; font-size: .74rem; }
  .is-overzicht .news-card-title { font-size: .98rem; margin-top: .25rem; padding-bottom: .7rem; }

  /* "Lees uitleg →" kost 46 px per rij en zegt in een lijst niets extra: de titel is al de link.
     Die krijgt daarom de accentkleur, zodat het zichtbaar aanklikbaar blijft — een losse
     herhaalde knop onder elke regel maakt de lijst alleen langer en rommeliger. */
  .is-overzicht .news-card-more { display: none; }
  .is-overzicht .news-card-title a { color: var(--acc-ink); }

  /* De samenvatting mag niet de hele winst opeten. Twee regels is genoeg om te bepalen of het
     artikel over jouw vraag gaat; wie meer wil, tikt erop. */
  .is-overzicht .news-card-excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: .85rem;
    margin-top: .2rem;
  }

  .is-overzicht .portfolio-meta { padding: .7rem .85rem; }
  .is-overzicht .portfolio-title { font-size: .98rem; margin: .3rem 0 .3rem; }

  /* Het zweef-effect van de bureaubladkaart hoort niet bij een lijstregel: op een telefoon
     blijft :hover na een tik hangen en dan staat één rij scheef tussen de andere. */
  .is-overzicht > *:hover { transform: none; }
}

/* ═══════════════════════════════════════════ 15. echte iconen i.p.v. emoji */

/* ICONEN-NIET-EMOJI-20260926 — zie inc/icoon.php voor het waarom.
   De SVG's zijn stroke-based en erven currentColor, dus ze volgen automatisch het thema en
   het gekozen accent. Dat kan een emoji niet: die heeft zijn eigen kleuren. */
.ico {
  display: inline-block;
  vertical-align: -.15em;   /* optisch op de tekstregel, niet op de basislijn */
  flex: none;
  color: inherit;
}

/* In een dienstenkaart zit het icoon in een gekleurd vlakje (zie 5. kaarten hierboven).
   Daar moet het gecentreerd staan en bij het aanwijzen wit worden, want dan wordt het
   vlakje zelf accentkleurig. */
.card .icon { color: var(--acc-ink); }
.card:hover .icon { color: #fff; }
.card:hover .icon .ico { color: #fff; }

/* De keuzetegels op de afspraakpagina en de landingspagina's. */
.pick-card-icon {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px; margin-bottom: .6rem;
  border-radius: 10px;
  background: color-mix(in srgb, var(--acc) 12%, transparent);
  color: var(--acc-ink);
  transition: background .2s ease, color .2s ease;
}
.pick-card:hover .pick-card-icon { background: rgba(255,255,255,.22); color: #fff; }

/* Merklogo's (Microsoft, WordPress, Apple, Google) zijn gevulde vormen in plaats van lijnen.
   Die worden bij hetzelfde formaat optisch zwaarder dan de lijn-iconen ernaast; iets kleiner
   maakt de rij weer rustig. */
.pick-card-icon .ico[viewBox="0 0 24 24"] { width: 100%; height: 100%; }

/* ═══════════════════════════════════════════ 16. eigen verzoek op /afspraak/ */

/* EIGEN-VERZOEK-20260926 — het invoerveld onder de onderwerptegels. */
.eigen-verzoek {
  margin-top: 1.6rem;
  padding: 1.2rem 1.3rem 1rem;
  border: 1px dashed color-mix(in srgb, var(--acc) 38%, var(--line));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--acc) 5%, var(--bg-2));
}
.eigen-verzoek label {
  display: block; font-weight: 700; margin-bottom: .6rem; color: var(--txt);
}
.eigen-verzoek-rij { display: flex; gap: .6rem; flex-wrap: wrap; }
.eigen-verzoek-rij input {
  flex: 1 1 22rem; min-width: 0;
  padding: .72rem .95rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--bg-2); color: var(--txt);
  font: inherit; font-size: .98rem;
}
.eigen-verzoek-rij input:focus-visible {
  outline: 2px solid var(--acc); outline-offset: 1px; border-color: var(--acc);
}
.eigen-verzoek-rij .btn { flex: 0 0 auto; }
.eigen-verzoek-hint { margin: .7rem 0 0; font-size: .86rem; color: var(--txt-3); }

/* Op een smal scherm de knop over de volle breedte: naast een invoerveld van 100%
   zou hij anders op een eigen regel van 4rem eindigen. */
@media (max-width: 560px) {
  .eigen-verzoek-rij .btn { width: 100%; justify-content: center; }
}

/* ═════════════════════════════════════ 17. verzendrij met WhatsApp-knop */

/* WHATSAPP-DOORSTUREN-20260926 — de twee knoppen onder het contactformulier. */
.verzendrij { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; }
.btn-wa { display: inline-flex; align-items: center; gap: .5rem; }
/* WhatsApp-groen, maar alleen als randje en bij aanwijzen — een volvlak groene knop naast de
   primaire accentknop trekt de aandacht weg van de hoofdactie (het formulier versturen). */
.btn-wa { border-color: color-mix(in srgb, #25d366 45%, var(--line)); }
.btn-wa:hover {
  border-color: #25d366;
  background: color-mix(in srgb, #25d366 10%, var(--bg-2));
  color: var(--txt) !important;
}
@media (max-width: 560px) {
  .verzendrij .btn { width: 100%; justify-content: center; }
}

/* ═══════════════════════════════════════════ 18. bel met de AI-assistent */

/* BEL-MET-DE-AI-20260926 — zie ab_bel_ai() in inc/visuals.php. */
.bel-ai {
  display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
  margin-bottom: 1.8rem;
  padding: 1.1rem 1.3rem;
  border-radius: var(--radius);
  border: 1px solid color-mix(in srgb, var(--acc) 26%, var(--line));
  background: linear-gradient(115deg,
              color-mix(in srgb, var(--acc) 9%, var(--bg-2)),
              color-mix(in srgb, var(--acc-2) 7%, var(--bg-2)));
}
.bel-ai > div { flex: 1 1 18rem; min-width: 0; }
.bel-ai strong { display: block; margin-bottom: .2rem; }
.bel-ai p { margin: 0; font-size: .92rem; color: var(--txt-2); }
.bel-ai .btn { flex: 0 0 auto; display: inline-flex; align-items: center; gap: .45rem; }

.bel-ai-icoon {
  flex: none;
  display: grid; place-items: center;
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--verloop); color: #fff;
  box-shadow: 0 8px 20px -10px color-mix(in srgb, var(--acc) 70%, transparent);
}

.btn-bel { display: inline-flex; align-items: center; gap: .45rem; }

@media (max-width: 560px) {
  .bel-ai { flex-direction: column; align-items: flex-start; }
  .bel-ai .btn { width: 100%; justify-content: center; }
}

/* ═══════════════════════════════════════════════════ 19. hulpmiddelen/tools */

/* TOOLS-VAN-ITLIVE-20260926 — de tools komen van itlive.nl/gratis-tools/, maar de opmaak is
   hier van deze site. De overgenomen inspect-ui.js schrijft .ik-* klassen; die krijgen
   hieronder de vorm die bij de rest past, zodat het geen vreemd eiland wordt. */

.veld-label { display:block; font-weight:700; margin-bottom:.5rem; }
.tool-rij { display:flex; gap:.6rem; flex-wrap:wrap; }
.tool-rij input {
  flex:1 1 20rem; min-width:0;
  padding:.72rem .95rem; border:1px solid var(--line); border-radius:999px;
  background:var(--bg-2); color:var(--txt); font:inherit; font-size:.98rem;
}
.tool-rij input:focus-visible { outline:2px solid var(--acc); outline-offset:1px; border-color:var(--acc); }
.tool-rij .btn { flex:0 0 auto; }
.tool-note { margin:.9rem 0 0; font-size:.86rem; color:var(--txt-3); }
.tool-uitslag:empty { display:none; }
.tool-uitslag {
  margin-top:1.1rem; padding:1rem 1.1rem;
  border-radius:var(--radius-s);
  background:color-mix(in srgb, var(--acc) 5%, var(--bg));
  border:1px solid var(--line-soft);
}

/* uitslag-onderdelen uit inspect-ui.js */
.ik-pills { display:flex; flex-wrap:wrap; gap:.4rem; margin:0 0 .9rem; }
.ik-pill  { display:inline-block; padding:.28rem .7rem; border-radius:999px; font-size:.8rem; font-weight:700; }
.ik-pill.ok  { background:color-mix(in srgb, #16a34a 16%, transparent); color:#14532d; }
.ik-pill.bad { background:color-mix(in srgb, #dc2626 14%, transparent); color:#7f1d1d; }
:root[data-theme="dark"] .ik-pill.ok  { color:#86efac; }
:root[data-theme="dark"] .ik-pill.bad { color:#fca5a5; }
.ik-row { display:grid; grid-template-columns:minmax(104px,150px) 1fr; gap:.5rem;
          padding:.5rem 0; border-bottom:1px solid var(--line-soft); }
.ik-row:last-child { border-bottom:0; }
.ik-row span { color:var(--txt-3); font-size:.86rem; }
.ik-row b    { font-weight:650; word-break:break-word; }
.ik-tips { margin:.9rem 0 0; padding-left:1.15rem; color:var(--txt-2); }
.ik-tips li { margin:.25rem 0; }
.ik-err, .ik-wait { font-weight:650; }
.ik-err { color:#b91c1c; }
:root[data-theme="dark"] .ik-err { color:#fca5a5; }
.ik-note { color:var(--txt-3); font-size:.86rem; }
.ik-box { background:transparent; padding:0; }

@media (max-width:560px) {
  .tool-rij .btn { width:100%; justify-content:center; }
  .ik-row { grid-template-columns:1fr; gap:.1rem; }
}

/* ═══════════════════════════════════════════════════════ 20. keuzehulp */

/* KIES-HULP-20260926 — /kies-hulp/: onderwerp, vorm en omschrijving in één scherm. */
.kies-blok { border:0; padding:0; margin:0 0 2rem; }
.kies-blok legend {
  display:flex; align-items:center; gap:.6rem;
  font-size:1.15rem; font-weight:700; margin-bottom:1rem; padding:0;
}
.kies-nr {
  display:grid; place-items:center; width:1.8rem; height:1.8rem; border-radius:50%;
  background:var(--verloop-markeer); color:#fff; font-size:.9rem; font-weight:700;
}
.kies-optioneel { font-weight:500; color:var(--txt-3); font-size:.9rem; }

.kies-opties { display:grid; grid-template-columns:repeat(auto-fill,minmax(210px,1fr)); gap:.7rem; }
.kies-opties--breed { grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); }

/* De radio zelf blijft bestaan voor toetsenbord en schermlezer; alleen onzichtbaar. */
.kies-optie input { position:absolute; opacity:0; width:0; height:0; }
.kies-optie-vak {
  display:block; height:100%; padding:.9rem 1rem;
  border:1px solid var(--line); border-radius:var(--radius-s);
  background:var(--bg-2); cursor:pointer;
  transition:border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.kies-optie-vak:hover { transform:translateY(-2px); border-color:color-mix(in srgb,var(--acc) 40%,var(--line)); }
.kies-optie input:checked + .kies-optie-vak {
  border-color:var(--acc);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--acc) 30%,transparent), var(--shadow);
  background:color-mix(in srgb,var(--acc) 6%,var(--bg-2));
}
/* Focus moet zichtbaar zijn ook al is de radio onzichtbaar. */
.kies-optie input:focus-visible + .kies-optie-vak { outline:2px solid var(--acc); outline-offset:2px; }

.kies-optie-ico  { display:inline-grid; place-items:center; width:32px; height:32px; margin-bottom:.5rem;
                   border-radius:9px; background:color-mix(in srgb,var(--acc) 12%,transparent); color:var(--acc-ink); }
.kies-optie-k    { display:block; font-weight:700; }
.kies-optie-s    { display:block; font-size:.88rem; color:var(--txt-2); margin-top:.15rem; }
.kies-optie-meta { display:block; font-size:.8rem; color:var(--txt-3); margin-top:.45rem; }

.kies-vraag {
  width:100%; padding:.8rem 1rem; border:1px solid var(--line); border-radius:999px;
  background:var(--bg-2); color:var(--txt); font:inherit;
}
.kies-vraag:focus-visible { outline:2px solid var(--acc); outline-offset:1px; border-color:var(--acc); }
.kies-hint { margin:.6rem 0 0; font-size:.88rem; color:var(--txt-2); }

/* ═══════════════════════════════════ 21. contrast rechtgezet (audit 26-09) */

/* Een audit met pixelmetingen over 10 pagina's × 2 thema's bracht een reeks teksten aan het
   licht die er prima uitzien maar onder de leesbaarheidsgrens zitten. Alles hieronder is
   gemeten, niet geschat — de getallen staan erbij zodat een volgende wijziging te toetsen is. */

/* --txt-3 haalde 3,85:1 op de paginakleur en 4,11:1 op wit; nodig is 4,5:1 voor normale tekst.
   Dit token draagt veel kleine tekst: de ondertitels van keuzetegels, de footerkoppen, "450
   resultaten", de voettekst met copyright en de privacylink. Eén tint donkerder tilt ze in één
   keer allemaal over de grens (4,69:1 op de paginakleur, 5,00:1 op wit) zonder dat het grijs
   zwart wordt. In het donkere thema was --txt-3 al goed (4,5–8,9:1) en blijft ongemoeid. */
/* (verwijderd 26-09: werd verderop overschreven — dode regel) */
/* CORRECTIE-20260926: #5f7187 was gekalibreerd op wit (5,00) maar niet op de blauw getinte
   panelen; daar bleef het op 4,26. En het donkere thema kreeg de wijziging helemaal niet mee:
   `:root[data-theme="dark"]` in style.css heeft een hogere specificiteit dan `:root` hier, dus
   de regel hierboven deed daar niets. Beide nu apart gezet en gemeten op de moeilijkste
   ondergrond die er is: #4f5d70 haalt 6,70 op wit en 5,71 op het lichtste getinte paneel;
   #8b9db3 haalt 6,16 op de donkere kaart. */
:root[data-theme="dark"] { --txt-3: #8b9db3; }

/* De voettekst kreeg `opacity:.85` mee (style.css), waardoor de gerenderde pixel lichter is dan
   de kleur die hier staat: 5,00 werd zo 3,70. Dekking eraf en de kleur zelf laten spreken. */
.foot-bottom { opacity: 1; }
.foot-bottom span, .foot-legal a { color: var(--txt-3); }

/* De zwevende WhatsApp-knop: wit op WhatsApp-groen #25D366 is 1,98:1 — veruit het laagste op
   de site, en hij staat op élke pagina.
   CORRECTIE-20260926: eerst stond hier #128C7E. Dat haalt 4,14:1 en dat is NET te weinig: het
   label is 15px vet, en de grens van 3:1 geldt pas vanaf 18,66px vet. Een hermeting ving dat.
   #0f7a5f haalt 5,29:1 en blijft in het WhatsApp-kleurbereik (het donkergroen/teal uit hun
   eigen huisstijl). In diezelfde correctie: de eerdere opmerking dat "het icoon het felle groen
   blijft" klopte niet — het icoon is wit, er zit geen groen in. */
/* (verwijderd 26-09: werd verderop overschreven — dode regel) */

/* Filterchips in het DONKERE thema hielden een witte achtergrond terwijl de tekst meekleurde:
   2,11:1. Een vergeten override — in licht was dezelfde chip 7,28:1. */
:root[data-theme="dark"] .filter-chip {
  background: var(--bg-2) !important;
  color: var(--txt) !important;
  border-color: var(--line);
}
:root[data-theme="dark"] .filter-chip.on,
:root[data-theme="dark"] .filter-chip[aria-current="true"] {
  background: var(--acc) !important; color: #fff !important; border-color: transparent;
}

/* Gradient-tekst in een kop werkt alleen als de kop ook echt een markeervlak krijgt. Op
   /privacy/ en /cookies/ staat .grad in een h1 zonder dat vlak, en dan wordt de cyaan helft
   van het woord 2,01:1 op de lichte achtergrond — de laatste letters verdwijnen.
   Elke .grad in een h1 krijgt daarom hetzelfde markeervlak als op de homepage. */
h1 .grad {
  background: var(--verloop-markeer);
  -webkit-background-clip: border-box; background-clip: border-box;
  -webkit-text-fill-color: #fff; color: #fff;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
  padding: .04em .22em .1em; margin-inline: -.06em; border-radius: .28em;
  box-shadow: 0 10px 26px -12px color-mix(in srgb, var(--acc) 70%, transparent);
}

/* Placeholders: in het donkere thema kreeg een deel van de velden de standaardkleur van de
   browser (2,43:1). Expliciet zetten, in beide thema's ruim boven 4,5:1. */
input::placeholder, textarea::placeholder { color: var(--txt-3); opacity: 1; }
:root[data-theme="dark"] input::placeholder,
:root[data-theme="dark"] textarea::placeholder { color: #9fb0c6; opacity: 1; }
/* Sommige invoervelden vielen in donker terug op de UA-styling; dat sloot niet aan bij de site. */
:root[data-theme="dark"] input, :root[data-theme="dark"] textarea, :root[data-theme="dark"] select {
  background: var(--bg-2); color: var(--txt); border-color: var(--line);
}

/* De tekst in de AI-band staat op een blauw vlak: 3,26:1 voor de lopende tekst en 2,67:1 voor
   het kleine regeltje eronder. Wit in plaats van lichtblauw lost beide op. */
/* CORRECTIE-20260926: de vorige poging zette alleen de tekstkleur, maar liet de BAND staan.
   Die loopt van --acc naar --acc-2 en wordt rechts zo licht dat wit er 3,60:1 haalt. En de
   regel voor .ai-klein was volledig INERT: elders staat `.ai-klein{color:rgba(255,255,255,.72)
   !important}`, en zonder !important verliest een nieuwe regel daarvan — hij stond er dus wel,
   maar veranderde niets (gemeten: nog steeds 2,69:1). Allebei nu echt aangepakt. */
.ai-band, #projecthulp {
  background: linear-gradient(115deg,
              color-mix(in srgb, var(--acc-dk) 92%, #000) 0%,
              color-mix(in srgb, var(--acc) 78%, #000) 100%) !important;
}
#projecthulp p { color: #fff !important; }
/* 🪤 CORRECTIE-20260926 (tweede hermeting): hier stond
   `#projecthulp .ai-klein, .ai-card .ai-klein, .ai-klein`. Veel te breed. De widget heeft
   NAMELIJK TWEE van deze regeltjes: een op de blauwe band (.ai-copy) en een in de witte kaart
   (.ai-card). Door ze allebei wit te maken werd de disclaimer in de kaart wit-op-wit — gemeten
   1,04:1, dus volledig onzichtbaar in het lichte thema. Ik had donker gerepareerd en licht
   gesloopt, en dat viel niet op omdat ik alleen op de band had gekeken.
   Nu per ondergrond: wit op de band, donkergrijs op de kaart. */
.ai-copy .ai-klein { color: color-mix(in srgb, #fff 90%, transparent) !important; }

/* Het aantal in een actieve filterchip stond op 85% wit (4,19:1). Vol wit haalt 5,17:1. */
.filter-chip.on span, .filter-chip[aria-current="true"] span { color: #fff !important; }

/* ══════════════════════════════════ 22. contrast, tweede ronde (hermeting) */

/* Een hermeting met pixelmonsters liet zien dat ronde 21 het meeste oploste, maar vier
   plekken nog net te laag bleven — en op één plek had ik het zelfs SLECHTER gemaakt. */

/* 🪤 MIJN EIGEN FOUT: ik zette .ai-klein op halftransparant wit
   (color-mix(#fff 88%, transparent)). Halftransparant wit MENGT met de blauwe band eronder,
   dus het werd effectief #c4ddfb: contrast 2,56 waar het 2,67 was. Een reparatie die het
   erger maakt. Vol wit, geen transparantie. */
#projecthulp .ai-copy .ai-klein { color: #fff !important; }

/* De disclaimer IN de kaart staat op een lichte (of donkere) kaartachtergrond, niet op de band.
   Zelfde ID-specificiteit als de regel hierboven, anders wint die alsnog van de themaregel. */
#projecthulp .ai-card .ai-klein { color: #475569 !important; }
:root[data-theme="dark"] #projecthulp .ai-card .ai-klein { color: #c3d2e6 !important; }

/* De band zelf was te licht om wit op te dragen: het verloop liep naar #2c88f0 en daar haalt
   wit maar 3,57. Een donkerder verloop (eindigend rond #1e5fd0) brengt de hele band boven de
   4,5 zonder dat hij zijn kleur verliest. */
#projecthulp, .ai-band, section#projecthulp {
  background-image: linear-gradient(115deg,
                    color-mix(in srgb, var(--acc-dk) 92%, #000) 0%,
                    color-mix(in srgb, var(--acc) 74%, #000) 100%) !important;
}
#projecthulp p, #projecthulp h2, #projecthulp li { color: #fff; }
/* De grijze toelichting onder het AI-antwoord stond vast op #475569 en werd in het donkere
   thema onleesbaar (2,25). Laat hem de themakleur volgen. */
#projecthulp [style*="475569"], #projecthulp .ai-uitleg { color: var(--txt-2) !important; }

/* De zwevende WhatsApp-knop: #128C7E bracht wit op 4,14 — beter dan 1,98, maar het label is
   15px/800 en heeft dus 4,5 nodig. Het donkerste groen uit de WhatsApp-huisstijl (#075E54,
   de kleur van hun koptekstbalk) haalt 7,67 en blijft herkenbaar. */
.wa-fab, .wa-fab:hover { background: #075E54 !important; }

/* --txt-3 haalde 5,00 op wit, maar veel kleine tekst staat op een LICHT GETINTE kaart
   (#dbf0fc) en daar bleef het op 4,26-4,42 steken. Eén stap donkerder haalt 5,07 op die
   kaarten en 5,95 op wit — nog steeds duidelijk grijs, niet zwart.
   Alleen het lichte thema: in donker wint de eigen override van style.css en die was al goed
   (4,5-8,9), dus daar verandert er niets. */
:root { --txt-3: #566578; }

/* In het donkere thema stond deze regel op een getinte kaart nog op 4,30. */
:root[data-theme="dark"] .kies-optie-meta { color: #9fb0c6; }


/* ── kopstructuur rechtgezet, uiterlijk gelijk gehouden ──────────────────── */

/* KOPSTRUCTUUR-20260926: een paar koppen stonden op een te laag niveau (h3 of h4 waar h2
   hoorde), waardoor de koppenlijst niveaus oversloeg. Voor een schermlezer is die lijst de
   snelste manier om een pagina te verkennen; een gat erin leest als ontbrekende inhoud.
   De niveaus kloppen nu, maar het formaat moet hetzelfde blijven als voorheen — anders
   verandert het ontwerp terwijl er alleen een tag is aangepast. */
.foot-kop { font-size: .82rem; text-transform: uppercase; letter-spacing: .08em;
            color: var(--txt-3); font-weight: 700; margin: 0 0 .8rem; }
.zij-kop  { font-size: 1.15rem; margin: 0 0 .5em; }

/* ── laatste contrastpunten uit de audit ─────────────────────────────────── */

/* Het verplicht-sterretje bij formuliervelden gebruikte --acc / --acc-ink. In het donkere
   thema is dat #2563eb op #0b1220 = 3,62 bij 13,8px — onder de 4,5 die normale tekst nodig
   heeft. Juist dit teken vertelt of een veld verplicht is; wie het niet ziet, vult het over.
   --acc-lt is de variant die voor tekst op een donkere achtergrond bedoeld is. */
:root[data-theme="dark"] label span[style*="--acc"] { color: var(--acc-lt) !important; }

/* De letters in de merktegels van de koppelingenbalk waren 7px en haalden 3,92. Zeven pixels
   is sowieso onleesbaar; ze staan bovendien naast de merknaam in gewone tekst, dus ze dragen
   geen informatie. Iets groter en met meer gewicht, zodat ze in elk geval niet als ruis lezen. */
.chip .badge, .chip svg + span { font-weight: 700; }

/* ═══════════════════════════════════════════ 23. de WhatsApp-knop */

/* WHATSAPP-KNOP-20260926 — derde poging, en nu met de reden erbij.
 *
 * 1e stand: wit op WhatsApp-groen #25D366 = contrast 1,98. Onleesbaar.
 * 2e poging: de hele knop donkerteal. Leesbaar (7,67), maar er zat geen WhatsApp-groen meer
 *   op een knop die juist aan dat groen wordt herkend.
 * 3e poging: fel groen met donkergroene letters. Leesbaar, maar een donker logo op fel groen
 *   ziet er niet uit — het WhatsApp-logo hoort wit te zijn, zo kent iedereen het.
 *
 * Wat wél allebei kan: WhatsApp heeft zelf twee huiskleuren. Naast het felle #25D366 is er
 * het diepe #075E54 van hun koptekstbalk. Een verloop tussen die twee blijft onmiskenbaar
 * WhatsApp, en wit haalt er 4,5+ op. Het logo blijft dus wit, zoals het hoort.
 */
.wa-fab {
  background: linear-gradient(135deg, #128C7E 0%, #075E54 100%) !important;
  color: #fff !important;
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 2px 6px -1px rgba(7,94,84,.5),
              0 12px 28px -10px rgba(7,94,84,.65),
              inset 0 1px 0 rgba(255,255,255,.18);   /* dun lichtrandje = glans bovenop */
  transition: transform .18s cubic-bezier(.34,1.4,.64,1), box-shadow .22s ease, filter .18s ease;
}
.wa-fab svg, .wa-fab path { fill: #fff !important; stroke: none !important; }
.wa-fab span { color: #fff !important; }

.wa-fab:hover {
  transform: translateY(-3px) scale(1.03);
  filter: saturate(1.15) brightness(1.06);
  box-shadow: 0 4px 10px -2px rgba(7,94,84,.55),
              0 20px 40px -12px rgba(7,94,84,.75),
              inset 0 1px 0 rgba(255,255,255,.25);
}

/* De zachte puls: één ring die uitdijt en vervaagt, traag genoeg om niet af te leiden.
   Dit is wat de knop "levend" maakt zonder dat er iets knippert. */
.wa-fab::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: 0 0 0 0 rgba(37,211,102,.55);
  animation: wa-puls 3.2s cubic-bezier(.4,0,.6,1) infinite;
  pointer-events: none;
}
@keyframes wa-puls {
  0%   { box-shadow: 0 0 0 0 rgba(37,211,102,.5); }
  60%  { box-shadow: 0 0 0 14px rgba(37,211,102,0); }
  100% { box-shadow: 0 0 0 0 rgba(37,211,102,0); }
}
/* Wie beweging heeft uitgezet, krijgt een stilstaande knop — geen uitzondering. */
@media (prefers-reduced-motion: reduce) {
  .wa-fab::after { animation: none; }
  .wa-fab:hover { transform: none; }
}

/* ═════════════════════════════ 24. mobiele blokkades (audit 26-09, deel 2) */

/* 1. ARTIKELPAGINA'S WAREN OP EEN TELEFOON ONLEESBAAR — 450 pagina's.
 *    Gemeten op een iPhone 13: innerWidth 756 px terwijl het scherm 390 px is. De browser
 *    zoomt dan de hele pagina uit om die 756 px te laten passen, en dan wordt 16,96 px tekst
 *    effectief 8,7 px. Je kunt het artikel simpelweg niet lezen.
 *    Oorzaak: .news-article heeft max-width:46rem (736 px) en staat in een grid-cel. Een
 *    grid-item heeft standaard min-width:auto en krimpt dus NIET onder zijn inhoudsbreedte —
 *    de 736 px wint van de 390 px die er beschikbaar is. min-width:0 geeft hem toestemming
 *    om wél te krimpen; max-width:100% houdt hem binnen de kolom.
 *    🪤 Dit is precies het soort fout dat op een desktop onzichtbaar is: daar is 736 px niets
 *    bijzonders en ziet de pagina er perfect uit. */
.news-article, .news-body { min-width: 0; max-width: 100%; }
.news-body img, .news-body pre, .news-body table { max-width: 100%; height: auto; }

/* 2. DE COOKIEBALK DEKTE DE WHATSAPP-KNOP VOLLEDIG AF.
 *    Gemeten: de balk staat op y=432 met een hoogte van 159 px (dus tot y=591), terwijl de
 *    WhatsApp-knop op y=528 zit. Bij élk eerste bezoek, op alle pagina's, op telefoon én
 *    tablet: de knop is niet aan te raken. Ook de vaste actiebalk en de eerste CTA's van de
 *    pagina vielen eronder.
 *    De balk hoort onderaan te plakken, niet midden in het scherm. En zolang hij open staat
 *    schuiven de zwevende knoppen erboven. */
/* De drie zwevende elementen stapelen van onder naar boven: actiebalk, dan de WhatsApp-knop,
   dan "terug naar boven". Elk krijgt de hoogte van wat eronder zit plus een marge, zodat ze
   elkaar nooit overlappen — niet met en niet zonder open cookiebalk.
   🪤 Bij de eerste poging kregen de WhatsApp-knop en "terug naar boven" dezelfde waarde en
   lagen ze precies op elkaar: het ene probleem opgelost, het andere gemaakt. Daarom hier
   expliciete, oplopende hoogtes in plaats van twee keer dezelfde berekening. */
@media (max-width: 900px) {
  .ab-cookie { bottom: 0 !important; top: auto !important; }

  /* zonder cookiebalk: balk 88px → WhatsApp op 96 → naar boven op 166 */
  .wa-fab { bottom: 96px !important; }
  .totop  { bottom: 166px !important; }

  /* met open cookiebalk schuift alles 168px omhoog */
  body:has(.ab-cookie.is-open) .mobile-cta { bottom: 168px !important; }
  body:has(.ab-cookie.is-open) .wa-fab     { bottom: 264px !important; }
  body:has(.ab-cookie.is-open) .totop      { bottom: 334px !important; }
}

/* 3. "TERUG NAAR BOVEN" OPENDE HET BERICHTFORMULIER.
 *    .totop en .mobile-cta hebben allebei z-index 40 en overlappen elkaar; bij een gelijke
 *    z-index wint het element dat later in de HTML staat, en dat is de CTA-balk. Een tik op
 *    het pijltje opende dus "Bericht". Gemeten met elementFromPoint: het midden van .totop
 *    gaf 'mobile-cta-mail' terug.
 *    De knop hoort boven de balk te liggen én ver genoeg erboven om niet te overlappen. */
.totop { z-index: 60 !important; }
@media (max-width: 900px) { .totop { bottom: calc(88px + 14px); } }

/* 4. DE NIEUWE HULPMIDDELEN HADDEN GEEN OPMAAK — alle 19.
 *    style.css heeft regels voor .field input, .form input, .tool-rij input en meer, maar geen
 *    enkele voor .tool-form. De velden vielen dus terug op de browserstandaard: 21 px hoog,
 *    Arial, font-size 13,3 px, border:2px inset. Twee gevolgen die echt hinderen:
 *      - een invoerveld van 21 px is op een telefoon nauwelijks te raken (44 px is de norm);
 *      - onder 16 px zoomt iOS Safari automatisch in zodra je een veld aantikt, en blijft de
 *        pagina daarna ingezoomd staan.
 *    16 px is hier dus geen smaak maar de grens waaronder iOS ingrijpt. */
.tool-form input:not([type="checkbox"]):not([type="radio"]),
.tool-form select,
.tool-form textarea {
  width: 100%;
  min-height: 44px;
  padding: .7rem .9rem;
  font: inherit;
  font-size: 16px;
  color: var(--txt);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  margin-bottom: .9rem;
}
.tool-form textarea { min-height: 120px; line-height: 1.5; }
.tool-form select { appearance: auto; }
.tool-form input:focus-visible, .tool-form select:focus-visible, .tool-form textarea:focus-visible {
  outline: 2px solid var(--acc); outline-offset: 1px; border-color: var(--acc);
}
.tool-form label { display: block; font-weight: 650; margin: .2rem 0 .4rem; }
/* De keuzevakjes van de wachtwoordgenerator stonden als doorlopende zin achter elkaar. */
.tool-form label:has(input[type="checkbox"]) {
  display: flex; align-items: center; gap: .55rem; font-weight: 500; margin: 0 0 .5rem;
}
.tool-form input[type="checkbox"] { width: 20px; height: 20px; min-height: 0; margin: 0; flex: none; }
.tool-form .dt-out, .tool-form #dt-out {
  display: block; margin-top: .4rem; padding: .9rem 1rem;
  background: color-mix(in srgb, var(--acc) 5%, var(--bg));
  border: 1px solid var(--line-soft); border-radius: var(--radius-s);
  white-space: pre-wrap; word-break: break-word;
}

/* ═══════════════════════════════════ 25. leesbaarheid en aanraakbaarheid */

/* Uit de mobiele audit: een reeks links en teksten zit onder de grens waarop ze nog prettig
   te gebruiken zijn. De richtlijn is 44x44 px voor iets wat je met een vinger raakt, en
   minstens 12 px voor tekst die informatie draagt. */

/* Footerlinks waren 34,8 px hoog — net te laag, op élke pagina en er zijn er veel. Extra
   verticale ruimte maakt ze raakbaar zonder dat de footer er anders uitziet. */
@media (max-width: 900px) {
  .foot-grid a, footer .plain a { display: inline-block; padding: .35rem 0; min-height: 44px;
                                  line-height: 1.9; }
  /* "Meer hierover →" en "Lees uitleg →" waren 19-23 px hoog. */
  .card a[href], .news-card-more { display: inline-block; padding: .3rem 0; min-height: 40px; }
  /* De links in de cookiebalk waren 18 px. */
  /* RAAKVLAK-ZONDER-EXTRA-HOOGTE-20260927 — correctie op mijn eigen reparatie hierboven.
   * `min-height: 40px` op een link MIDDEN IN een tekstregel maakt die regel 40 px hoog, en de
   * cookiebalk groeide daardoor van 159 naar 179 px. Bij een vers bezoek op een telefoon was
   * samen met de actiebalk 46% van het scherm bedekt — op precies het moment dat iemand moet
   * beslissen of hij blijft. Een raakdoel repareren mag de bladspiegel niet opeten.
   * Padding omhoog/omlaag met een even grote negatieve marge geeft wél 44 px raakvlak, maar
   * kost geen enkele pixel in de layout. */
  .ab-cookie a {
    display: inline-block;
    padding-block: 12px;
    margin-block: -12px;
    padding-inline: .15rem;
    min-height: 0;
  }
}

/* Tekst onder 12 px draagt op een telefoon niets meer bij; deze stonden op 11,5-11,8 px. */
.tag, .lp-badge, footer small, .foot-bottom { font-size: .8rem; }

/* De thema- en kleurknopjes in de kop waren 36x36. */
@media (max-width: 900px) { .iconbtn { min-width: 44px; min-height: 44px; } }

/* De voorbeeldvragen in de AI-band zijn echte knoppen die mensen aantikken; die waren 36,4 px.
   De merkbadges in de koppelingenbalk blijven bewust klein: dat zijn een of twee letters naast
   de merknaam die er in gewone tekst naast staat, dus ze dragen geen informatie die je moet
   kunnen lezen. Ze zijn wel van 7 naar 10,9 px gegaan zodat ze niet meer als vlek lezen. */
@media (max-width: 900px) {
  .ai-chip, button.ai-chip { min-height: 44px; padding-block: .6rem; }
  .carousel-nav .iconbtn, button.iconbtn { min-width: 44px; min-height: 44px; }
}
/* De ondertitel onder het logo stond op 11,5 px. */
.brand-txt small { font-size: .8rem; }

/* ══════════════════════════ 26. wat de ronde hierboven MISTE (opnieuw gemeten) */

/* TAPDOELEN-OP-METING-NIET-OP-NAAM-20260927
 *
 * De ronde hierboven repareerde `.foot-grid a` en `footer .plain a` — en de links die het
 * probleem wáren, "Privacy (AVG)" en "Cookies", staan in `.foot-legal`. Die zaten dus na de
 * reparatie nog steeds op 16 px hoog, op élke pagina, terwijl ik ze afgevinkt had.
 * 🪤 Repareren op de naam die je verwacht in plaats van op de selector die je gemeten hebt,
 * geeft een fix die schoon oogt, netjes laadt en niets doet. Hernoem of hermeet altijd.
 */
@media (max-width: 900px) {
  .foot-legal a { display: inline-block; padding: .55rem .15rem; min-height: 44px; line-height: 1.9; }

  /* "Bekijk live →" was 18 px hoog en is dé link waarmee iemand het werk gaat bekijken —
     twintig keer op de site, en precies de knop die je met een duim wilt raken. */
  .portfolio-meta a[href] { display: inline-block; padding: .45rem 0; min-height: 44px; }

  /* De vragen in "Veelgestelde vragen" waren 27 px. Een <summary> is de hele klikregel, dus
     hier is het niet de tekst maar de regelhoogte die telt. */
  details > summary { min-height: 44px; display: flex; align-items: center; }

  /* Filterchips stonden op 38 px — twee pixels onder de grens, maar het zijn er 40 op één
     pagina en ze staan dicht op elkaar. Dan is twee pixels het verschil tussen "raak" en
     "net de verkeerde categorie". */
  /* 🪤 Alleen `min-height` zetten haalde de hoogte naar 44 maar liet de paginanummers op 34-39 px
     BREED staan — en juist die (1, 2, 11) staan vlak naast elkaar onderaan de kennisbank, waar
     een misser je naar de verkeerde pagina stuurt. Een raakdoel heeft twee maten. */
  .filter-chip { min-height: 44px; min-width: 44px; display: inline-flex; align-items: center;
                 justify-content: center; }

  /* Ook in de veegrij op de homepage is de artikeltitel een link; die stond daar op 21 px. */
  .news-card-title a { display: inline-block; min-height: 44px; }

  /* In de lijstweergave is de titel de enige link van de regel (de knop eronder is weg),
     dus die moet zelf ruim genoeg zijn; hij stond op 39 px. */
  .is-overzicht .news-card-title a { display: inline-block; min-height: 44px; }
}

/* De carrouselstipjes waren 8x8 px — het kleinste raakdoel van de hele site, en er staan er
 * dertien onder elkaar op de homepage. Groter máken mag niet: dan worden het vlekken in plaats
 * van stipjes. Daarom blijft het zichtbare stipje precies zoals het was en groeit alleen het
 * raakvlak, met padding plus `background-clip: content-box` — de achtergrond stopt dan bij de
 * inhoud en de padding blijft doorzichtig. `gap` wordt navenant kleiner, anders staat de rij
 * ineens veel te ver uit elkaar. */
/* De teller die vanaf zeven kaarten in de plaats van de stipjes komt (zie
   STIPJES-PASSEN-NIET-ALTIJD-20260927 in app.js). */
.carousel-teller {
  margin: .5rem 0 0;
  font-size: .85rem;
  font-variant-numeric: tabular-nums;   /* anders springt de regel bij elke cijferwissel */
  color: var(--txt-3);
  letter-spacing: .02em;
}

.carousel-dots { gap: 0; }
.carousel-dots button {
  box-sizing: content-box;
  padding: 18px;                 /* 8 px stip + 2x18 = 44 px raakvlak, in beide richtingen */
  background-clip: content-box;
  border-radius: 999px;
}

/* ══════════════════════════ 27. het sprongmenu op de dienstenpagina */

/* SPRONGMENU-KOSTTE-VIER-SCHERMEN-20260927
 *
 * Gemeten op een iPhone 13: je scrolt **2.911 px — ruim vier schermen** voordat je de eerste
 * dienst ziet. Daarvan is 2.155 px het keuzemenu zelf: elf kaarten van 188 px, elk met icoon,
 * titel én samenvatting, in één kolom onder elkaar.
 *
 * 🪤 Het menu is bedoeld om SNELLER bij een dienst te komen en deed precies het omgekeerde.
 * Wie niet weet dat het een sprongmenu is, leest elf samenvattingen en denkt dat dát de pagina
 * is — en de bezoeker die "webshop" zocht, is allang weg voor hij bij blok twee is.
 *
 * Op mobiel dus twee kolommen zonder samenvatting: de naam is genoeg om te kiezen, en die
 * samenvatting staat honderd pixels verderop bij de dienst zelf nog een keer. Op pc verandert
 * er niets — daar staan er drie naast elkaar en is het menu 784 px, wat prima past.
 */
@media (max-width: 700px) {
  .dienst-sprong {
    grid-template-columns: 1fr 1fr;
    gap: .55rem;
  }
  .dienst-sprong .card {
    padding: .85rem .6rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    min-height: 0;
  }
  /* De samenvatting verdwijnt alleen VISUEEL uit het menu; een schermlezer leest hem nog en
     hij staat sowieso bij de dienst zelf. */
  .dienst-sprong .card p { display: none; }
  .dienst-sprong .card h3 {
    font-size: .95rem;
    line-height: 1.25;
    margin: 0;
    text-wrap: balance;      /* "Computerhulp aan huis" breekt dan netjes over twee regels */
  }
  .dienst-sprong .card .icon { margin: 0; }
}

/* Tussen 701 en 1000 px (tablet) drie smalle kolommen in plaats van twee brede kaarten. */
@media (min-width: 701px) and (max-width: 1000px) {
  .dienst-sprong { grid-template-columns: repeat(3, 1fr); }
  .dienst-sprong .card p { display: none; }
}

/* ══════════════════════════ 28. drie keer dezelfde WhatsApp-knop in één scherm */

/* EEN-WHATSAPP-PER-SCHERM-20260927
 *
 * Gemeten op een iPhone 13, op /windows-hulp/ en de andere dienstpagina's: **drie** WhatsApp-
 * ingangen tegelijk in beeld — de knop in de kop, de zwevende bel rechtsonder, en de groene
 * knop in de vaste balk. Drie keer dezelfde actie maakt de keuze niet makkelijker maar
 * onduidelijker, en het kost ruimte op precies het scherm waar iemand beslist.
 *
 * De zwevende bel is bovendien niet gratis: hij dekt inhoud af. Gemeten door bij elke
 * scrollpositie te kijken wat eronder ligt — 27 posities op /diensten/, 22 op /tools.php,
 * 15 op /kennisbank.php, met lijstitems en lopende tekst eronder.
 *
 * Onder 760 px staat de vaste balk er al, met WhatsApp als grote groene knop over de halve
 * breedte. Daar is de zwevende bel dus de derde ingang naar hetzelfde gesprek en verdwijnt hij.
 * Op een breed scherm is er géén vaste balk — daar blijft hij precies zoals hij was.
 *
 * 🪤 Dit is bewust ALLEEN een mobiele regel: WhatsApp blijft overal even bereikbaar, alleen
 *    niet drie keer tegelijk. Terugdraaien is één regel.
 */
@media (max-width: 760px) {
  .wa-fab { display: none !important; }

  /* 🪤 Eerste poging schoof de "naar boven"-knop naar de vrijgekomen plek van de bel. Daarmee
   * was de OVERLAP niet weg maar alleen van eigenaar gewisseld: gemeten 24 scrollposities op
   * /diensten/, 23 op /tools.php, met lopende tekst en koppen eronder — vrijwel hetzelfde als
   * daarvoor. Een zwevend element boven de tekst is het probleem, niet wélk element het is.
   *
   * Nu staat er op een telefoon niets meer bóven de inhoud: de knop gaat NAAST de vaste balk,
   * in de strook die onderaan toch al is vrijgehouden (body heeft daar padding). De balk maakt
   * rechts ruimte, de knop past er precies in, en samen dekken ze geen letter meer af. */
  .totop {
    bottom: 18px !important;
    right: 12px !important;
    top: auto !important;
  }
  .mobile-cta { right: 66px; }

  /* Staat de cookiebalk open, dan schuiven balk én knop samen omhoog — nooit los van elkaar,
     want dan overlappen ze weer (dat ging op 26-09 al een keer mis). */
  body:has(.ab-cookie.is-open) .mobile-cta { bottom: 168px !important; }
  body:has(.ab-cookie.is-open) .totop      { bottom: 174px !important; }
}

/* ══════════════════════════ 29. de merkkop: minder lucht, strakker gezet */

/* KOP-STOND-TE-RUIM-20260927
 *
 * Tussen "Ayoub Bouders" en de slagzin zat een dikke luchtlaag. Niet door een marge — die staan
 * allebei op 0 — maar door de REGELHOOGTE: `line-height:1.15` plus `min-height:1.25em` op een
 * sierletter die zelf al veel witruimte in de letterkast heeft (Great Vibes heeft lange staarten
 * en hoge stokken, dus de regel is optisch veel hoger dan de letters zelf).
 *
 * Gemeten in de browser met vier waarden naast elkaar: het merkblok gaat van 64 px naar 52 px
 * zonder dat er een letter wordt afgesneden. Bij 0,90 raakt de staart van de "y" de slagzin —
 * dat is de ondergrens, dus 0,95 is bewust gekozen en niet het uiterste.
 *
 * 🪤 `min-height` moet mee omlaag, anders doet de line-height niets: die min-height staat er voor
 *    de typ-animatie (`.brand-name.is-typing`), zodat de kop niet springt terwijl de naam wordt
 *    "getypt". Weghalen mag dus niet — alleen gelijk optrekken met de nieuwe regelhoogte.
 */
/* 🪤 De line-height staat BEWUST niet hier maar in breedte-en-beweging.css, bij de reparatie
   die de afgesneden krullen oploste. Twee bestanden die dezelfde eigenschap sturen is precies
   hoe een eerdere sessie hier een mobiele indeling sloopte — dus één plek, met de uitleg erbij.
   Wat hier wél hoort: de min-height mee omlaag, anders houdt die het vak alsnog hoog. */
.brand-name { min-height: 1em; }

/* De slagzin stond op 1,65 regelhoogte; dat is ruim voor één regel van 12,8 px en het duwde de
   kop verder uit elkaar. 1,4 leest net zo prettig en scheelt nog eens een paar pixels. */
.brand-txt small {
  line-height: 1.4;
}

/* SLAGZIN-BRAK-IN-DE-KOP-20260927 — gemeten per schermbreedte hoeveel regels de slagzin nodig had:
 *
 *   320px → 4 regels   360/390px → 3 regels   414/480px → 2 regels   vanaf 560px → 1 regel
 *
 * Op een telefoon stond er dus "Websites, webshops &" met een losse "&" aan het regeleinde, en op
 * 320 px viel hij zelfs over vier regels uiteen. Dat maakt de kop rommelig op precies het moment
 * dat iemand zijn eerste indruk vormt, en het levert niets op: de hero eronder zegt in grote
 * letters hetzelfde. Onder de gemeten grens van 560 px dus alleen de naam — die staat daar mooi
 * in balans naast het beeldmerk.
 *
 * 🪤 Alleen visueel weg: een schermlezer leest hem nog wel, en boven 560 px staat hij er gewoon.
 *    Terugzetten is één regel.
 */
@media (max-width: 559px) {
  .brand-txt small {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* 🪤 De slagzin vulde het merkblok mee tot 52 px. Weg = 38 px, en daarmee zakte de logo-link
     onder de 40 px die een vinger nodig heeft. Een raakdoel dat krimpt doordat je er iets
     ANDERS uit haalt — daarom hier meteen een ondergrens. */
  .brand { min-height: 44px; }
}

/* De sluitknop van de cookiebalk was 36x36. Hij staat naast "Begrepen" en doet hetzelfde, maar
   wie hem mist tikt op de knop eronder. */
.ab-cookie-x { min-width: 44px; min-height: 44px; }

/* PORTFOLIO-TEGELS-MOBIEL-20260928 — het portfolio is een BEELDlijst, geen leeslijst.
 * OVERZICHT-IS-GEEN-VEEGRIJ maakte er op de telefoon een lijst van: 104 px beeld links, tekst
 * rechts. Voor de kennisbank klopt dat (de titel is de inhoud), maar op /portfolio.php IS de
 * schermafbeelding de inhoud — en op 104 px breed is een website niet te herkennen (eigenaar
 * 28-09: "de foto's niet op mobiel, moet beter"). Daarom hier twee kolommen met het hele beeld
 * boven de naam: 57 projecten ≈ 29 rijen, en je ziet per scherm 6 websites in plaats van 5
 * postzegels. Alleen `.portfolio-grid.is-overzicht`, de kennisbank blijft een lijst. */
@media (max-width: 1000px) {
  .portfolio-grid.is-overzicht {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .7rem;
  }
  .portfolio-grid.is-overzicht > * {
    display: flex;
    flex-direction: column;
    border-radius: 14px;
  }
  .portfolio-grid.is-overzicht .portfolio-shot {
    grid-row: auto;
    aspect-ratio: 16 / 10;
    border-bottom: 1px solid var(--line, rgba(15, 23, 42, .08));
  }
  .portfolio-grid.is-overzicht .portfolio-shot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
  }
  .portfolio-grid.is-overzicht .portfolio-meta {
    padding: .55rem .7rem .35rem;
    display: flex;
    flex-direction: column;
    flex: 1;
  }
  .portfolio-grid.is-overzicht .tag {
    align-self: flex-start;
    font-size: .68rem;
    padding: .15rem .45rem;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .portfolio-grid.is-overzicht .portfolio-title {
    font-size: .9rem;
    line-height: 1.2;
    margin: .35rem 0 .1rem;
    overflow-wrap: anywhere;
  }
  .portfolio-grid.is-overzicht .portfolio-meta a[href] {
    margin-top: auto;
    font-size: .82rem;
    padding: .35rem 0;
    min-height: 40px;
    display: flex;
    align-items: center;
  }
}
@media (min-width: 701px) and (max-width: 1000px) {
  .portfolio-grid.is-overzicht { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
