/* Learning Community: één opmaak voor pc, laptop, tablet en telefoon.

   De vormgeving volgt Apple's ontwerpuitgangspunten: doorschijnende lagen voor
   de vaste chrome met de inhoud die eronderdoor schuift, typografie waarvan de
   letterafstand met de tekengrootte meebeweegt, maten in rem zodat een grotere
   systeemtekst de hele indeling meeneemt, en beweging die op de aanraking
   reageert in plaats van op het loslaten. */

:root {
  /* Kleur, en waarom deze — herzien op 11-09-2026.

     Hier stond tot vandaag een bewust ingehouden palet, met als reden dat
     ingehouden beter werkt dan een spelpalet als je een uur achter elkaar
     oefent. Dat onderzoek klopt nog steeds. Maar Robert vroeg met opzet om
     het tegenovergestelde: speels en kleurrijk, in de geest van Duolingo, met
     grote ronde vormen en knoppen die aanvoelen als indrukken. Die twee
     wensen zijn te verzoenen zonder dat de een de ander opeet: de kleur mag
     vrolijk zijn zolang de discipline overeind blijft die hieronder al stond
     — elke sterke kleur met precies één betekenis, nooit de enige drager naast
     kleur, en elke combinatie gemeten op de WCAG-contrastmaat in plaats van
     geschat.

     Het vertrekpunt is de kea, de bergpapegaai: olijfgroen verenkleed,
     oranjerood onder de vleugels, en het grijsblauw van de bergen waar hij
     leeft. Daaruit vier betekenissen, net als eerst:

       accent (hoofdkleur)  olijfgroen van het verenkleed, voor wat je kunt
                             aanraken en waar je nu bent
       goed                 een helderder grasgroen, voor wat klopt, beheerst
                             is of de grens haalde — een andere tint dan de
                             hoofdkleur, anders vallen "aanraakbaar" en
                             "gehaald" samen
       waarschuw            het oranjerood onder de vleugels, voor "let op, dit
                             vraagt om actie", en nooit als enige drager
       fout                 dieper rood dan waarschuw, voor een fout antwoord;
                             dat is een les, geen alarm, dus geen schrikkleur

     Nieuw is een vijfde rol die er eerst niet was: onbehandeld, het
     berggrijsblauw, voor stof die nog niet aan de beurt is geweest. Dat
     bestond al impliciet in de lege baan van elke voortgangsbalk; nu heeft
     die baan er ook echt de kleur van in plaats van neutraal grijs, en dat is
     geen verzonnen voortgang maar precies het omgekeerde: het benoemt wat er
     nog niet gemeten is als "nog niet", niet als "niets".

     Voortgang zelf blijft het systeem van eerst: de vulling begint in de
     hoofdkleur en springt naar goed zodra de grens gehaald is, naar fout waar
     het zwak staat, naar waarschuw waar iets aandacht vraagt — altijd met een
     getal of een woord ernaast, nooit kleur alleen.

     Alle combinaties hieronder halen nog steeds minstens 4,5 op de
     contrastmaat van de WCAG tegen zowel wit als de achtergrondtint, gemeten
     en niet geschat. */

  --achter: #f3f7f1;
  --kaart: #ffffff;
  --rand: rgba(16, 34, 40, .12);
  --randzacht: rgba(16, 34, 40, .07);
  --tekst: #141b22;
  --zacht: #53646e;
  --accent: #4c7a28;
  --accentzacht: rgba(76, 122, 40, .12);
  /* Wat er op een accentknop staat. In het licht is het accent donker en is
     wit de enige leesbare keuze; in het donker is het accent juist licht, en
     dan moet de tekst mee omslaan. */
  --opaccent: #ffffff;
  /* De statuskleuren staan een stap donkerder dan de kea zelf: de zachte
     vlakken eronder zijn doorzichtig en stapelen op de getinte achtergrond,
     en daar zakt het contrast anders net onder de 4,5. Nu haalt elke kleur
     die grens ook op zijn eigen zachte vlak, gemeten en niet geschat. */
  --goed: #057259;
  --goedzacht: rgba(5, 114, 89, .11);
  --fout: #b02a2a;
  --foutzacht: rgba(176, 42, 42, .1);
  --waarschuw: #975300;
  --waarschuwzacht: rgba(151, 83, 0, .11);
  /* De vijfde rol: stof die nog niet aan de beurt is geweest. Het
     berggrijsblauw van de kea's leefgebied, gebruikt in de lege baan van elke
     voortgangsbalk zodat "nog niet gedaan" een eigen kleur heeft in plaats van
     kaal grijs. */
  /* De vulkleuren. Waarom die er apart zijn.

     De kleuren hierboven zijn allemaal donker gezet omdat ze ook als tekst
     gebruikt worden: een woord in --goed moet leesbaar zijn op wit, en dat
     vraagt 4,5 op de contrastmaat. Maar een gevuld knooppunt, een voortgangsbalk
     of een gekleurde kop is geen tekst: daar zit hooguit een vinkje of een
     grote letter op, en dan volstaat 3. Door voor die twee dingen dezelfde
     donkere kleur te gebruiken werd het hele scherm zo gedempt als de strengste
     eis, terwijl dat alleen voor de tekst nodig was.

     Vandaar deze reeks: dezelfde kleuren, maar helderder, en uitsluitend voor
     vlakken waar geen kleine tekst op staat. Alle vier halen nog steeds 3 of
     hoger tegen wit, gemeten en niet geschat (groen 3,07 / rood 4,12 /
     oranje 3,07 / blauw 3,56), dus een wit vinkje blijft zichtbaar.

     Het is bewust niet het palet van Duolingo zelf. Dat groen (#58CC02) haalt
     maar 2,2 tegen wit; hun eigen knoppen zijn niet leesbaar volgens de norm.
     En het zou een kopie zijn. */
  --goedvol: #009f7c;
  --foutvol: #e0453f;
  --waarschuwvol: #f2a618;
  --accentvol: #539d2b;
  --blauwvol: #1f8fd0;

  --onbehandeld: #5b6e7d;
  --onbehandeldzacht: rgba(91, 110, 125, .12);

  /* Bandkleuren, alleen om trajecten uit elkaar te houden op het dashboard —
     geen van deze draagt een oordeel, dus ze staan los van accent/goed/fout/
     waarschuw hierboven. Zes tinten uit dezelfde kea-familie: het olijfgroen
     en oranjerood van hierboven, plus bergmeerblauw, het blauwpaars dat op de
     vleugelpennen van een kea iriseert, alpien goud en grasgroen. Bij meer
     dan zes trajecten herhaalt de reeks. */
  /* Tokens v2 (14-09-2026, wijzigingsverslag fase 1: DS-01, KL-01 t/m KL-06).

     Trajectkleuren (KL-05, B2): vier eigen kleuren buiten de betekenis-
     kleuren, vast per traject via trajectkleur.js. Wit haalt er 4,5:1 op in
     beide thema's. De oude banden blijven als alias tot niets ze meer vraagt. */
  --traject1: #037ac0;
  --traject2: #4770d4;
  --traject3: #8261cc;
  --traject4: #a853ad;
  --optraject: #ffffff;
  --band1: var(--traject1);
  --band2: var(--traject2);
  --band3: var(--traject3);
  --band4: var(--traject4);
  --band5: var(--traject1);
  --band6: var(--traject2);

  /* Geel vlak draagt een donkere glyph en een oker rand (KL-02): wit op geel
     haalt geen 3:1, de rand tegen de pagina wel. */
  --opwaarschuwvol: #141b22;

  /* Lippen (KL-04): berekend in OKLCH, niet gemengd met zwart, zodat de tint
     levendig blijft. Dit zijn de hex-terugvallen; @supports verderop rekent
     ze uit de kleur zelf. */
  --accentdonker: #375e15;
  --goeddonker: #008163;
  --foutdonker: #b9312d;
  --uitgeschakeld: #e5e5e5;
  --uitgeschakeldtekst: #595959;
  --kaartrand: #e5e5e5;

  /* Vorm, tekst en beweging (CONTRACTS §4.2). */
  --lip: .25rem;
  --lipklein: .125rem;
  --icoonmaat: 1.875rem;
  --icoonlijn: 2.4;
  --tekst-kop-groot: 1.5625rem;
  --tekst-kop: 1.1875rem;
  --tekst-basis: 1.0625rem;
  --tekst-label: .9375rem;
  --tekst-klein: .875rem;
  --gewicht-vet: 700;
  --gewicht-gewoon: 500;
  --veer: cubic-bezier(.35, 1.8, .35, .83);
  --vulcurve: cubic-bezier(.22, 1, .36, 1);
  --duurklik: .2s;
  --duurin: .3s;
  --duuruit: .3s;

  /* De vlakkenlaag, overgenomen van shadcn/ui.

     Waarom dit erbij komt. Het palet hierboven benoemt kleur met betekenis:
     wat je kunt aanraken, wat klopt, wat fout is, wat aandacht vraagt. Wat er
     niet in stond is de laag eronder: de rustige vlakken waar een ontwerp op
     staat. Daardoor stond overal waar een zacht vlak nodig was een eigen
     rgba-waarde, en die liepen uiteen. shadcn benoemt die laag wel, en dat is
     precies het stuk dat hier ontbrak.

     Let op één naamsverschil dat blijft. Bij shadcn heet de aanraakbare
     merkkleur `primary` en heet de vlakkleur voor zweven en aanwijzen
     `accent`. Hier heet de merkkleur al `--accent`, met een onderbouwing die
     eronder ligt, en die naam blijft. shadcn's `accent` heet hier `--zweefvlak`.

       shadcn            hier
       background        --achter
       foreground        --tekst
       card / popover    --kaart / --zweef
       muted             --vlak
       muted-foreground  --zacht
       accent            --zweefvlak     (zweven en aanwijzen)
       primary           --accent        (de merkkleur, zie hierboven)
       secondary         --tweede
       border            --rand
       input             --veldrand
       ring              --ring */
  --vlak: #f1f5f4;
  --tweede: #e7edec;
  --zweef: #ffffff;
  --zweefvlak: rgba(16, 34, 40, .05);
  --veldrand: rgba(16, 34, 40, .16);
  --veldvlak: transparent;
  /* De focusring. shadcn neemt hier bewust een neutrale grijstint, los van de
     merkkleur. Dat doen we niet: "waar je nu bent" is in dit palet al de
     betekenis van het accent, en focus is precies dat. Het onderzoek dat er
     ligt wint hier van de gewoonte van shadcn. */
  --ring: var(--accent);
  /* De zachte halo eromheen. shadcn zet ring-[3px] op ring/50: een brede,
     halfdoorzichtige gloed in plaats van een harde lijn. Die gloed komt hier
     als tweede laag bovenop een gewone outline, niet in plaats daarvan; zie de
     regel bij :focus-visible verderop voor waarom. */
  --ringzacht: color-mix(in srgb, var(--ring) 35%, transparent);

  /* doorschijnende lagen: de chrome zweeft boven de inhoud */
  --glas: rgba(245, 249, 248, .72);
  --glasrand: rgba(255, 255, 255, .6);
  --glasblur: blur(24px) saturate(180%);

  /* Schaduw, overgenomen van shadcn/ui en daarmee platter dan hiervoor.

     Wat hier stond tilde een kaart 20 tot 44 punten van de pagina af. Dat
     leest als los materiaal dat zweeft, en bij twintig kaarten onder elkaar
     als onrust. shadcn houdt de schaduw kort en laat de rand het werk doen:
     een kaart ligt op de pagina, hij hangt er niet boven. Dat is het grootste
     deel van de rust die je bij shadcn ziet.

     De inkt blijft de koele toon van dit platform (16, 34, 40) in plaats van
     zuiver zwart, zodat de schaduw bij de groenblauwe ondertoon past. */
  --schaduwklein: 0 1px 2px 0 rgba(16, 34, 40, .05);
  --schaduw: 0 1px 3px 0 rgba(16, 34, 40, .1), 0 1px 2px -1px rgba(16, 34, 40, .1);
  --schaduwmiddel: 0 4px 6px -1px rgba(16, 34, 40, .1), 0 2px 4px -2px rgba(16, 34, 40, .1);
  --schaduwdik: 0 10px 15px -3px rgba(16, 34, 40, .1), 0 4px 6px -4px rgba(16, 34, 40, .1);

  /* maatvoering in rem, zodat de tekstinstelling de indeling meeneemt */
  --r1: .25rem;  --r2: .5rem;   --r3: .75rem;  --r4: 1rem;
  --r5: 1.5rem;  --r6: 2rem;    --r7: 3rem;

  /* De hoekenreeks van shadcn: één grondmaat, de rest eruit afgeleid.

     Waarom dit beter is dan twee losse waarden. Hiervoor stonden er twee
     ronding-variabelen die los van elkaar gekozen waren, plus een handvol
     losse getallen (2px, 3px, 4px) die nergens aan hingen. shadcn zet één
     grondmaat en leidt de rest af, zodat een knop in een kaart in een paneel
     zichtbaar bij elkaar horen. De vermenigvuldigers zijn die van shadcn. */
  /* De grondmaat ging van .625rem naar .8rem: dezelfde reeks, alleen ronder,
     want grote ronde vormen zijn precies het speelse dat hier bij moest.
     --rond krijgt daarnaast zijn eigen, nog grotere maat, zodat een kaart
     duidelijk ronder oogt dan een knop in plaats van dezelfde afgeleide. */
  --rondgrond: .8rem;                            /* 12,8px */
  --rond1: calc(var(--rondgrond) * .6);          /* ~7,7px */
  --rond2: calc(var(--rondgrond) * .8);          /* ~10,2px */
  --rond3: var(--rondgrond);                     /* 12,8px */
  --rond4: calc(var(--rondgrond) * 1.4);         /* ~17,9px */
  /* De twee namen die al door de hele opmaak heen staan, nu op de reeks. */
  --rondklein: .75rem;                     /* knoppen en velden */
  --rond: 1rem;                               /* kaarten en panelen, 20px */
  --rondknop: 1rem;                              /* de hoofdknop, 16px */

  /* Maatvoering van bedieningselementen, overgenomen van shadcn.

     shadcn zet een knop en een invoerveld op 2,25rem hoog (h-9), met .75rem
     ruimte opzij (px-3) en tekst op .875rem (text-sm). Dat is de maat die het
     geheel zo rustig maakt: alles wat je kunt bedienen is even hoog.

     Maar 2,25rem is 36 punten, en Apple houdt 44 aan voor wat je met een
     vinger raakt. Die twee spreken elkaar tegen. De oplossing staat verderop:
     op een aanraakscherm gaat --regelhoog naar --raakvlak. Dus shadcn's
     verhoudingen op een laptop, Apple's ondergrens op een telefoon. */
  --regelhoog: 2.25rem;
  --regelhoogklein: 2rem;
  --regelhooggroot: 2.5rem;
  --regelpad: .75rem;
  --regelpadgroot: 1rem;
  --regeltekst: .875rem;
  --raakvlak: 2.75rem;

  --breed: 56rem;
  /* Breedtetokens (afspraken-lc-2026-09-15 §3), gedeeld met het oefenscherm.
     --inhoud-breedte: de inhoudskolom naast het zijmenu. Was 56rem; op een
     MacBook bleef er naast de zijbalk links en rechts een lege strook over
     ("overal te veel witruimte"). --tekst-breedte: een leesregel, ongeveer 70
     tekens (LY-02). */
  --inhoud-breedte: 64rem;
  --tekst-breedte: 30em;

  /* De drie schermgrenzen (LY-01, SPEC B-61), de vensterklassen van Material:
     onder 600 een telefoon, vanaf 600 een tablet of klein venster, vanaf 840
     ruimte voor twee kolommen, vanaf 1200 een groot scherm. Een @media-regel
     kan geen var() lezen, dus daar staan dezelfde getallen letterlijk;
     web/schermmaat.js leest deze tokens, zodat JavaScript nooit een eigen
     grens heeft. "Smaller dan" schrijven we als `not all and (min-width: …)`:
     dat is het exacte tegendeel van de brede regel, zodat er geen breedte
     bestaat waarop beide gelden (op 608 px gold eerst max- én min-width: 38rem). */
  --bp-medium: 37.5rem;
  --bp-expanded: 52.5rem;
  --bp-large: 75rem;

  /* Vaste lagen (LY-05). Wat vast of plakkend in beeld staat, heeft hier een
     hoogte en een laag. Zo rekent elke regel die ruimte vrijhoudt met dezelfde
     maat, en schuift er nooit een balk over een andere. De getallen zijn de
     z-indexen die er al stonden; alleen hebben ze nu een naam. De hoogtes zijn
     gemeten op 14-09 (kop 41 px op de telefoon en 61 px breed, tabbalk 55 px). */
  --kop-hoog: 3.875rem;
  --tabbalk-hoog: 3.5rem;
  --antwoordbalk-hoog: 4rem;
  --laag-inhoud: 5;      /* plakkend binnen een scherm: padgereedschap, speler */
  --laag-subbalk: 10;    /* de rij tabs onder de kop */
  --laag-balk: 20;       /* de kop */
  --laag-navigatie: 25;  /* zijbalk, antwoordbalk */
  --laag-vast: 30;       /* tabbalk, voortgangsblok */
  --laag-paneel: 40;     /* menupaneel */
  --laag-melding: 45;    /* korte melding */
  --laag-deur: 60;       /* voordeur, rondleiding, sleepblok: boven alles */
}

/* Springt de focus met Tab of een ankerlink naar een element, dan houdt de
   browser deze randen vrij: niets landt onder de kop of de tabbalk (WCAG 2.4.11). */
html {
  scroll-padding-block: calc(var(--kop-hoog) + var(--r2)) var(--r4);
}
@media not all and (min-width: 37.5rem) {
  :root { --kop-hoog: 2.625rem; }
  html:has(body.mettabbalk) {
    scroll-padding-block-end: calc(var(--tabbalk-hoog) + env(safe-area-inset-bottom) + var(--r4));
  }
  html:has(body.mettabbalk #scherm-oefenen.aan) {
    scroll-padding-block-end: calc(var(--tabbalk-hoog) + var(--antwoordbalk-hoog) + env(safe-area-inset-bottom) + var(--r4));
  }
}

/* Op een aanraakscherm wint de ondergrens van Apple van de maat van shadcn.
   Zie de uitleg bij --regelhoog hierboven.

   Waarom hier ook een breedte staat en niet alleen pointer: coarse. Niet elk
   toestel dat met een vinger bediend wordt meldt zich als aanraakscherm; er
   stond verderop in dit bestand al een regel die daar rekening mee hield, met
   de opmerking dat sommige toestellen zich als muis melden maar toch getikt
   worden. Op alleen pointer: coarse vertrouwen liet de hoofdknop op zulke
   toestellen op 40 punten uitkomen, gemeten, en dat is onder de 44. Een scherm
   dat smaller is dan --bp-medium is een telefoon, hoe hij zich ook meldt. */
@media (pointer: coarse), not all and (min-width: 37.5rem) {
  :root {
    --regelhoog: var(--raakvlak);
    --regelhoogklein: var(--raakvlak);
    --regelhooggroot: var(--raakvlak);
  }
}

@media (prefers-color-scheme: dark) {
  :root {
    /* In het donker draait de redenering om: daar is de achtergrond al rustig
       en moeten de kleuren juist licht genoeg zijn om leesbaar te blijven.
       Dezelfde vijf betekenissen, dezelfde kea-tinten, alleen opgehelderd. */
    --achter: #101519;
    --kaart: #19212a;
    --rand: rgba(255, 255, 255, .12);
    --randzacht: rgba(255, 255, 255, .07);
    --tekst: #e8eef0;
    --zacht: #9aabb4;
    --accent: #9bc46b;
    --accentzacht: rgba(155, 196, 107, .16);
    --opaccent: #101519;
    --goed: #4dc5a1;
    --goedzacht: rgba(77, 197, 161, .16);
    --fout: #f28b78;
    --foutzacht: rgba(242, 139, 120, .15);
    --waarschuw: #f0985a;
    --waarschuwzacht: rgba(240, 152, 90, .16);
    --onbehandeld: #93a5b5;
    --onbehandeldzacht: rgba(147, 165, 181, .16);

    --accentvol: #9bc46b;
    --accentdonker: #82a658;
    --uitgeschakeld: #273240;
    --uitgeschakeldtekst: #9aabb4;
    --kaartrand: rgba(255, 255, 255, .14);

    /* De vlakkenlaag in het donker. shadcn zet in het donker een doorzichtige
       vulling in invoervelden (input/30) in plaats van niets: een leeg veld is
       dan te zien zonder dat er een rand omheen hoeft te schreeuwen. Dat is
       overgenomen. */
    --vlak: #212b35;
    --tweede: #273240;
    --zweef: #1e2731;
    --zweefvlak: rgba(255, 255, 255, .07);
    --veldrand: rgba(255, 255, 255, .16);
    --veldvlak: rgba(255, 255, 255, .04);

    --glas: rgba(18, 25, 30, .72);
    --glasrand: rgba(255, 255, 255, .09);

    /* In het donker draagt schaduw nauwelijks, want er is geen licht om weg te
       nemen. shadcn laat hem daarom staan maar leunt op de rand. Wel dieper
       dan in het licht, omdat de ondergrond zelf donker is. */
    --schaduwklein: 0 1px 2px 0 rgba(0, 0, 0, .3);
    --schaduw: 0 1px 3px 0 rgba(0, 0, 0, .4), 0 1px 2px -1px rgba(0, 0, 0, .4);
    --schaduwmiddel: 0 4px 6px -1px rgba(0, 0, 0, .45), 0 2px 4px -2px rgba(0, 0, 0, .45);
    --schaduwdik: 0 10px 15px -3px rgba(0, 0, 0, .5), 0 4px 6px -4px rgba(0, 0, 0, .5);
  }
}

* { box-sizing: border-box; }

[hidden] { display: none !important; }

/* Nunito, lokaal (DS-02, SIL OFL, web/fonts/OFL.txt). Geen extern laden. */
@font-face {
  font-family: 'Nunito';
  src: url('fonts/nunito-latin.woff2') format('woff2');
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Nunito';
  src: url('fonts/nunito-latin-ext.woff2') format('woff2');
  font-weight: 200 1000;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

html {
  -webkit-text-size-adjust: 100%;
  font: 100%/1.5 "Nunito", -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, "Segoe UI", Roboto, sans-serif;
}

body {
  margin: 0;
  background: var(--achter);
  color: var(--tekst);
  font-size: var(--tekst-basis);
  font-weight: var(--gewicht-gewoon);
  font-optical-sizing: auto;
  padding-bottom: env(safe-area-inset-bottom);
  overscroll-behavior-y: none;
}

/* Typografie: grote tekst wil krappere letterafstand en krappere regelafstand,
   kleine tekst juist iets ruimer. Eén vaste waarde is altijd ergens fout. */

h1 {
  font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: -.021em;
  font-weight: 700;
  margin: 0 0 var(--r2);
}

h2 {
  font-size: 1.06rem;
  line-height: 1.25;
  letter-spacing: -.012em;
  font-weight: 650;
  margin: 0 0 var(--r3);
}

h3 {
  font-size: .75rem;
  line-height: 1.35;
  letter-spacing: .045em;
  text-transform: uppercase;
  font-weight: 620;
  color: var(--zacht);
  margin: var(--r5) 0 var(--r2);
}

/* ------------------------------------------------------------------ balk */

.balk {
  position: sticky;
  top: 0;
  z-index: var(--laag-balk);
  display: flex;
  align-items: center;
  gap: var(--r3);
  padding: var(--r2) var(--r4);
  padding-top: calc(var(--r2) + env(safe-area-inset-top));
  background: var(--glas);
  backdrop-filter: var(--glasblur);
  -webkit-backdrop-filter: var(--glasblur);
  border-bottom: 1px solid var(--glasrand);
}

.balk .titel { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.balk .titel strong,
.balk .titel span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.balk .titel strong { font-size: 1rem; letter-spacing: -.011em; font-weight: 640; }
.balk .titel span { font-size: .8125rem; color: var(--zacht); letter-spacing: .002em; }

.terug {
  position: relative;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--tekst);
  border-radius: var(--rondklein);
  padding: var(--r1) var(--r3);
  font: inherit;
  font-size: .875rem;
  cursor: pointer;
  flex-shrink: 0;
  transform: scale(1);
  transition: transform 110ms ease-out, border-color 140ms ease-out, color 140ms ease-out;
}
/* Het onzichtbare raakvlak, dezelfde truc als bij .uitlegknop. De knop zelf is
   30 punten hoog en dat leest rustig in de balk; groter maken zou hem naast de
   titel laten schreeuwen. Acht punten onzichtbaar boven en onder brengt hem op
   46 en daarmee voorbij de 44 die Apple aanhoudt, ook in de smalle variant
   hieronder die op 28 uitkomt. Alleen verticaal, want links en rechts staan de
   titel en de meter, en die wil je niet per ongeluk raken. Breed is de knop al
   ruim boven de 44. Bewust buiten pointer: coarse, want een iPad met trackpad
   meldt zich als muis terwijl er nog steeds met een vinger op getikt wordt. */
.terug::after { content: ""; position: absolute; inset: -.5rem 0; }
.terug:hover { border-color: var(--accent); color: var(--accent); }
.terug:active { transform: scale(.96); }

.meter { display: flex; align-items: center; gap: var(--r2); flex-shrink: 0; }
.meterstreep {
  width: 8rem;
  height: .5625rem;
  border-radius: 99px;
  background: var(--onbehandeldzacht);
  overflow: hidden;
}
.meterstreep i {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: 99px;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(0);
  will-change: transform;
}
.meter span {
  font-size: .8125rem;
  color: var(--zacht);
  font-variant-numeric: tabular-nums;
  letter-spacing: .004em;
}

/* het dagdoel: een ring die vol loopt met wat je vandaag hebt gedaan */
.dagdoel { position: relative; width: 2rem; height: 2rem; flex-shrink: 0; }
.dagdoel svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.dagdoel circle { fill: none; stroke-width: 3.5; }
.dagdoel .baan { stroke: var(--randzacht); }

/* De ring en de meter zijn voortgang, en voortgang volgt overal hetzelfde
   systeem: vulling in het accent, want de vorm draagt de betekenis al. Een
   ring is geen knop, dus het accent kan hier geen verwarring geven. Zodra het
   dagdoel gehaald is springt hij naar groen, de kleur van "dit klopt". */
.dagdoel .vulling {
  stroke: var(--accent);
  stroke-linecap: round;
  transition: stroke .3s ease-out;
}
.dagdoel.gehaald .vulling { stroke: var(--goed); }
.dagdoel span {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: .6875rem;
  font-weight: 640;
  font-variant-numeric: tabular-nums;
  color: var(--zacht);
}
.dagdoel.gehaald span { color: var(--goed); }

.meterstreep.breed { width: 100%; height: .625rem; margin: var(--r2) 0; }

/* ------------------------------------------------------------------ tabs */

.tabs {
  position: sticky;
  top: 0;
  z-index: var(--laag-subbalk);
  display: flex;
  gap: var(--r1);
  padding: var(--r2) var(--r4);
  background: var(--glas);
  backdrop-filter: var(--glasblur);
  -webkit-backdrop-filter: var(--glasblur);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* een zachte rand waar de inhoud onder de chrome verdwijnt, geen harde lijn */
  box-shadow: 0 1px 0 var(--randzacht), 0 12px 12px -12px rgba(20, 30, 50, .16);
}
.tabs::-webkit-scrollbar { display: none; }

.tabs button {
  border: 0;
  background: transparent;
  color: var(--zacht);
  padding: var(--r2) var(--r3);
  border-radius: var(--rondklein);
  font: inherit;
  font-size: .9375rem;
  letter-spacing: -.004em;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transform: scale(1);
  transition: transform 110ms ease-out, color 140ms ease-out, background-color 160ms ease-out;
}
.tabs button:hover { color: var(--tekst); }
.tabs button:active { transform: scale(.96); }
/* De tab waar je op staat komt bij shadcn omhoog: hij krijgt de kaartkleur en
   een lichte schaduw, terwijl de balk eronder juist gedempt blijft. Die lichte
   verhoging is hier overgenomen. De accenttint blijft er wel op staan, want in
   dit palet betekent het accent "waar je nu bent", en dat is precies wat een
   actieve tab zegt. De schaduw is de tweede drager naast de kleur. */
.tabs button.aan {
  background: var(--accentzacht);
  color: var(--accent);
  font-weight: 620;
  box-shadow: var(--schaduwklein);
}

/* ------------------------------------------------------------- schermen */

.verbinding {
  margin: 0;
  padding: var(--r2) var(--r4);
  background: var(--foutzacht);
  color: var(--fout);
  font-size: .8125rem;
  text-align: center;
}

main { max-width: var(--inhoud-breedte); margin: 0 auto; padding: var(--r4) var(--r4) var(--r7); }
/* main krijgt focus via de skip-link; een rand om het hele scherm helpt dan niemand. */
main:focus { outline: none; }

/* Naar de inhoud (LY-04). Buiten beeld tot hij focus krijgt; dan linksboven,
   boven de kop en de zijbalk. */
.naardeinhoud {
  position: fixed;
  top: calc(var(--r2) + env(safe-area-inset-top));
  left: var(--r2);
  z-index: var(--laag-deur);
  padding: var(--r2) var(--r4);
  min-height: var(--raakvlak);
  display: inline-flex;
  align-items: center;
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font-weight: 700;
  transform: translateY(calc(-100% - var(--r6)));
}
.naardeinhoud:focus-visible { transform: none; }

/* Ruimte onderaan zolang het toetsenbord open staat.

   iOS schuift het veld waarin je typt netjes boven het toetsenbord, en houdt
   daar op. De knop eronder, bij een invulvraag dus Nakijken, viel erachter, en
   dan kon de pagina niet verder omlaag omdat er onderaan niets meer stond om
   naartoe te scrollen. Deze regel geeft precies zoveel extra ruimte als het
   toetsenbord bedekt; app.js meet dat en schuift dan naar de knop toe. Zonder
   toetsenbord is --toetsenbord nul en verandert er niets. */
main { padding-bottom: calc(var(--r7) + var(--toetsenbord, 0px)); }

.scherm { display: none; }
.scherm.aan { display: block; }

.uitleg { color: var(--zacht); margin: 0 0 var(--r5); font-size: 1rem; }

/* Leesbreedte (LY-02). Een regel van meer dan 75 tekens is moeilijk terug te
   vinden; op 1280 px liepen alinea's hier tot 102 tekens door. GOV.UK en de
   leesonderzoeken houden 60 à 75 aan. Het rapport noemde 68ch, maar in Nunito
   is de 0 (waar ch op rust) breder dan een gemiddelde letter: 68ch gaf gemeten
   91 tekens. 30em geeft er ongeveer 70, en groeit mee met de lettergrootte.
   Gecentreerde blokken (.leeg) houden hun midden via margin-inline. */
main p, main li, main dd { max-inline-size: var(--tekst-breedte); }
main .leeg p { margin-inline: auto; }

/* De kaart, op de vorm van shadcn/ui.

   Nu de schaduw plat is (zie --schaduw) moet de rand het werk doen, anders
   zweeft er niets meer maar staat er ook niets meer afgebakend. Daarom gaat de
   rand van --randzacht naar --rand: dat is precies de ruil die shadcn maakt.
   Een kaart ligt op de pagina in plaats van erboven te hangen. */
.kaart {
  background: var(--kaart);
  border: 2px solid var(--kaartrand);
  border-bottom-width: var(--lip);
  border-radius: var(--rond);
  box-shadow: none;
  padding: var(--r5);
  margin-bottom: var(--r5);
}

.kaart .kaart { border-bottom-width: 2px; }

@media not all and (min-width: 37.5rem) {
  /* Zijmarge 16 px (LY-02): met 12 px raakte de tekst bijna de rand van het
     toestel, en in een hoesje valt een duim er dan overheen. */
  main { padding: var(--r4) var(--r4) var(--r6); }
  .kaart { padding: var(--r4) var(--r3); }
  .balk { gap: var(--r2); padding: var(--r2) var(--r3); padding-top: calc(var(--r2) + env(safe-area-inset-top)); }
  .balk .titel span { display: none; }
  .tabs { padding: var(--r2) var(--r3); }
  .meterstreep { width: 3.25rem; }
  .meter { gap: var(--r1); }
  .meter span { font-size: .75rem; }
  .terug { padding: var(--r1) var(--r2); font-size: .8125rem; }
}

/* ------------------------------------------------------- trajectenkeuze */

.kaarten { display: grid; gap: var(--r4); grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }

/* Elk traject zijn eigen kleur, zodat wiskunde en economie in één oogopslag
   verschillen. --bandkleur is decoratief en draagt geen oordeel — dat blijft
   voorbehouden aan accent/goed/fout/waarschuw — dus hij staat los van dat
   systeem en cirkelt gewoon door de zes bandkleuren hierboven. Omdat het een
   CSS-variabele is die de kaart zelf zet, kunnen elementen erbinnen (de
   voortgangsbalk, het merkje) er zonder extra selectors gebruik van maken. */
.trajectkaart { --bandkleur: var(--traject1); }

.trajectkaart {
  background: var(--kaart);
  border: 2px solid var(--kaartrand);
  border-bottom-width: var(--lip);
  border-top: .375rem solid var(--bandkleur);
  border-radius: var(--rond);
  box-shadow: none;
  padding: var(--r5) var(--r4) var(--r4);
  cursor: pointer;
  text-align: left;
  color: inherit;
  font: inherit;
  display: flex;
  flex-direction: column;
  gap: var(--r3);
  transform: scale(1);
  transition: transform 130ms ease-out, box-shadow 180ms ease-out, border-color 180ms ease-out;
}
.trajectkaart:hover { border-color: var(--rand); box-shadow: var(--schaduwdik); }
.trajectkaart:active { transform: scale(.985); }
.trajectkaart b { font-size: 1.125rem; font-weight: 750; letter-spacing: -.014em; }
.trajectkaart .sub { font-size: .8125rem; color: var(--zacht); }
.trajectkaart p { margin: 0; font-size: .875rem; color: var(--zacht); line-height: 1.5; }

/* Drie kaarten die er precies hetzelfde uitzien geven geen enkele aanwijzing
   waar je moet beginnen. De kaart waar je gebleven was krijgt daarom de
   accentrand, en elke kaart een slotregel die zegt wat een tik oplevert. */
.trajectkaart.aanbevolen { border-color: var(--accent); box-shadow: var(--schaduwdik); }
.trajectmerk {
  align-self: flex-start;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accentzacht);
  border-radius: 999px;
  padding: .15rem .5rem;
}
.trajectstand {
  margin-top: auto;
  padding-top: var(--r2);
  font-size: .8125rem;
  font-weight: 600;
  color: var(--accent);
}

/* Zelf een traject maken staat ingeklapt, zodat het keuzescherm één vraag
   stelt. Open ziet het eruit als altijd. */
.nieuwtrajectblok { margin-top: var(--r5); }
.nieuwtrajectblok > summary {
  cursor: pointer;
  font-size: .9375rem;
  font-weight: 600;
  color: var(--zacht);
  padding: var(--r3) 0;
  list-style-position: inside;
}
.nieuwtrajectblok > summary:hover { color: var(--accent); }

/* ------------------------------------------------------------ lege staten

   Een lege lijst zei tot nu toe alleen dát hij leeg was. Het onderzoek vraagt
   drie dingen op dezelfde plek: wat hier komt te staan, waarom er nu niets is,
   en precies één knop die de kortste weg erheen neemt. Zie
   rapporten/Bruikbaar voor wie het niet kent.md, regel 6 tot en met 10. */

.leegstaat {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  box-shadow: var(--schaduw);
  padding: var(--r5);
  margin: var(--r4) 0;
  max-width: 34rem;
}
.leegstaat h2 { margin: 0 0 var(--r2); font-size: 1.0625rem; letter-spacing: -.013em; }
.leegstaat p { margin: 0; color: var(--zacht); font-size: .9375rem; line-height: 1.6; }
.leegstaat .hoofdknop { margin-top: var(--r4); }

/* De drie stappen in de lege staat. Genummerd en niet met bolletjes, want de
   volgorde is hier de boodschap: zonder onderwerpen valt er geen materiaal te
   koppelen, en zonder materiaal komen er geen vragen. */
.leegstappen {
  margin: var(--r3) 0 0;
  padding-left: 1.2em;
  color: var(--zacht);
  font-size: .9375rem;
  line-height: 1.6;
}
.leegstappen li { margin-bottom: var(--r1); }
.leegstappen li:last-child { margin-bottom: 0; }
.leegproefzin { margin-top: var(--r4) !important; }
.leegdaarna { margin-top: var(--r3) !important; font-size: .875rem !important; }

/* Een traject zonder vragen. Dezelfde plek als de meter die hij vervangt, en
   in dezelfde toon als de andere regels op de kaart: het is geen fout en geen
   waarschuwing, het is de stand van zaken plus de eerstvolgende stap. */
.dashleeg {
  display: block;
  margin: var(--r3) 0 var(--r2);
  color: var(--zacht);
  font-size: .875rem;
  line-height: 1.55;
}

/* De regel boven de allereerste vraag. Hij mag opvallen, want hij staat er maar
   één keer, en hij mag niets blokkeren, want de vraag eronder is de hoofdzaak. */
.eerstekeer {
  background: var(--accentzacht);
  border-radius: var(--rond);
  padding: var(--r4);
  margin-bottom: var(--r4);
  max-width: 34rem;
}
.eerstekeer b { display: block; margin-bottom: var(--r1); font-size: .9375rem; }
.eerstekeer p { margin: 0; font-size: .875rem; line-height: 1.6; color: var(--zacht); }

/* De eerstvolgende stap op het leerpad, als knop in plaats van als zin. */
.padstart { margin-top: var(--r3); }
.padstartwenk { margin: var(--r2) 0 0; font-size: .8125rem; color: var(--zacht); }

/* De uitweg onder een aanbevolen knop: even breed, duidelijk minder nadruk.
   Niemand wordt tegengehouden, maar er is geen twijfel welke van de twee de
   bedoelde weg is. */
.kleineknop.tweedeknop {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  margin-top: var(--r2);
  padding: var(--r3) var(--r4);
  font-size: .9375rem;
}

/* ------------------------------------------------------------- oefenen */

.onderdeelkop {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--r2) var(--r3);
  margin-bottom: var(--r4);
}
.onderdeelkop b { font-size: 1.125rem; letter-spacing: -.014em; }
.onderdeelkop .stand { font-size: .875rem; color: var(--zacht); }

/* Hoe ver het oefenexamen is. Neemt de hele regel, want naast de tekst zou hij
   op een telefoon een streepje van twee centimeter worden en dan zegt hij
   niets. Zie volgendeExamenvraag in app.js. */
.examenbaan {
  flex: 1 0 100%;
  height: .375rem;
  border-radius: 999px;
  background: var(--randzacht);
  overflow: hidden;
}
.examenbaan i {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: inherit;
  transition: width 220ms ease-out;
}

/* UI-02: de voortgangsbalk van de ronde. Vulling en waarde komen van
   rondebalk.js (B-12); de kleur is die van het actieve traject (B-54.2),
   dezelfde --bandkleur-truc als de trajectkaart en de dagdoelmeter. Radius
   op .rondebalk zelf (toegestaan in de lijst); de rest van de opmaak op
   .rondebalk-opmaak, zodat er geen twee redenen voor dezelfde regel zijn. */
.rondebalk-opmaak {
  height: 1rem;
  margin-bottom: var(--r3);
  background: var(--onbehandeldzacht);
  overflow: hidden;
}
.rondebalk { border-radius: 999px; }
.rondebalk-opmaak i {
  display: block;
  height: 100%;
  background: var(--bandkleur, var(--accent));
  border-radius: inherit;
}
@media (prefers-reduced-motion: no-preference) {
  :root:not(.minder-beweging) .rondebalk-opmaak i { transition: width .4s var(--vulcurve); }
}
/* UI-02 AC 9: met reduced motion springt de balk meteen (0s), ook al geeft
   de algemene regel onder toegankelijkheid elke overgang .12s. */
@media (prefers-reduced-motion: reduce) {
  .rondebalk-opmaak i { transition-duration: 0s !important; }
}

/* De vraagkaart mag gesleept worden, dus hij moet zelf de horizontale
   aanraking afhandelen en niet meescrollen. */
.kaart.vraag, .kaart.uitleg {
  touch-action: pan-y;
  will-change: transform;
}

/* --------------------------------------------- rekenmachine-plek (eis d)

   web/rekenmachine.js zet deze knoop zelf neer, alleen bij een traject met
   het veld `rekenmachine` (QRM1, Wiskunde B, Proeftraject). .vraagrij is de
   wikkel die hetzelfde bestand om #vraagblok heen zet zodra de plek er is;
   zonder plek bestaat .vraagrij niet en verandert er niets aan de bestaande
   opmaak van andere trajecten.

   Vanaf --bp-expanded (twee kolommen, afspraak met leerplatform-d9's
   breedtetokens): de plek staat rechts naast de vraagkaart, als paneel.
   Daaronder, en met nadruk op 375 px: hij wordt een knop in de vraagkop zelf
   in plaats van een eigen regel, anders past het oefenscherm niet meer op
   één scherm (afspraak met leerplatform-ad). */
.vraagrij { display: block; }

@media (min-width: 52.5rem) {
  .vraagrij {
    display: flex;
    align-items: flex-start;
    gap: var(--r4);
    max-width: var(--inhoud-breedte);
  }
  .vraagrij > .kaart.vraag { flex: 1 1 auto; min-width: 0; }
  .rekenmachineplek-paneel {
    flex: 0 0 14rem;
    position: sticky;
    top: var(--r4);
    background: var(--kaart);
    border: 2px solid var(--kaartrand);
    border-bottom-width: var(--lip);
    border-radius: var(--rond);
    padding: var(--r4);
    text-align: center;
  }
  .rekenmachineplek-paneel .rekenmachineplek-knop { width: 100%; }
}

/* Smal (ook 375 px): geen paneel, geen eigen regel — de plek is dan een knop
   die rekenmachine.js zelf in .vraagkop heeft gezet. .vraagkop is al een
   flex-rij met wrap (zie hierboven); "display: contents" laat de wikkel zelf
   uit de doos verdwijnen, zodat alleen de knop daarin meetelt als flex-item
   en er geen extra laagje in de vraagkop bijkomt. */
.rekenmachineplek-knopvorm { display: contents; }

/* ------------------------------------------- de kaart die er nog niet is

   Het skelet dat op het oefenscherm staat zolang de stof van een traject
   onderweg is. De maten zijn met opzet die van de echte vraagkaart hierboven:
   een kopregel van .8125rem, vier regels vraagtekst van 1.0625rem met
   regelafstand 1.5, en vier antwoordrijen. Klopt de maat niet, dan verspringt
   het scherm op het moment dat de vraag binnenkomt, en dat is precies het
   ongemak dat je met een skelet probeert weg te nemen.

   De glans loopt van links naar rechts en niet als een klopping. Een klopping
   trekt het oog naar zich toe alsof er iets aan de hand is; een glans die
   doorloopt zegt alleen dat er iets gaande is. Wie beweging heeft uitgezet
   krijgt hem niet, en houdt gewoon de grijze vorm. */
.vraagskelet { overflow: hidden; }

.skeletregel, .skeletoptie {
  background: var(--achter);
  border-radius: var(--r1);
  /* De glans zelf: een lichte veeg die over het grijs heen schuift. */
  background-image: linear-gradient(90deg,
    transparent 0%, rgba(255, 255, 255, .85) 50%, transparent 100%);
  background-repeat: no-repeat;
  background-size: 40% 100%;
  background-position: -60% 0;
  animation: skeletglans 1400ms ease-in-out infinite;
}

.skeletregel { height: 1.0625rem; margin-bottom: calc(1.0625rem * .5); }
/* De kopregel is kleiner en staat op afstand, net als .merk en .vorm samen. */
.skeletregel.kop { height: .8125rem; width: 45%; margin-bottom: var(--r3); }
.skeletregel.kort { width: 62%; margin-bottom: var(--r4); }

.skeletoptie {
  height: 2.75rem;
  border-radius: var(--r2);
  margin-bottom: var(--r2);
}
.skeletoptie:last-of-type { margin-bottom: 0; }

.skeletlang {
  margin: var(--r4) 0 0;
  color: var(--zacht);
  font-size: .875rem;
  line-height: 1.6;
}

@keyframes skeletglans {
  from { background-position: -60% 0; }
  to   { background-position: 160% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .skeletregel, .skeletoptie { animation: none; background-image: none; }
}

/* De regel op het startscherm als het openen van een traject niet lukte.
   Dezelfde kleuren als de balk "Zonder verbinding" bovenaan, want het is
   hetzelfde soort bericht: er is niets stuk, er is alleen even geen Mac. */
.trajectfout {
  margin: 0 0 var(--r4);
  padding: var(--r3) var(--r4);
  background: var(--foutzacht);
  color: var(--fout);
  border-radius: var(--rond);
  font-size: .9375rem;
  line-height: 1.6;
}
.trajectfout button {
  display: block;
  margin-top: var(--r2);
  padding: .35rem .9rem;
  border: 1px solid currentColor;
  border-radius: 99px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: .875rem;
  cursor: pointer;
}

.vraagkop { display: flex; justify-content: space-between; gap: var(--r2); margin-bottom: var(--r3); flex-wrap: wrap; align-items: center; }
.merk { font-size: .8125rem; color: var(--zacht); letter-spacing: .002em; }
.vorm {
  font-size: .75rem;
  background: var(--accentzacht);
  color: var(--accent);
  padding: .15rem .55rem;
  border-radius: 99px;
  letter-spacing: .006em;
  font-weight: 560;
}

/* VR-06: een teruggekomen vraag zegt dat erbij, in dezelfde toon als de
   andere "dit onderwerp kan een opfrisser gebruiken"-plekken (zie .opfris
   hierboven). rondebalk.js zet hidden en de pop-in. */
.herhaalbadge {
  font-size: .75rem;
  background: var(--waarschuwzacht);
  color: var(--waarschuw);
  padding: .15rem .55rem;
  border-radius: 99px;
  letter-spacing: .006em;
  font-weight: 560;
}

.vraagtekst { font-size: 1.0625rem; line-height: 1.5; letter-spacing: -.006em; margin-bottom: var(--r4); }
.vraagtekst p { margin: 0 0 var(--r2); }
.vraagtekst code, .lopend code, .leerrij code, .waar code {
  background: var(--achter);
  padding: .05em .35em;
  border-radius: var(--r1);
  font-size: .9em;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

table.opties {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--r3);
  font-size: .9375rem;
}
table.opties th {
  text-align: left;
  font-size: .6875rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--zacht);
  font-weight: 620;
  padding: var(--r1) var(--r3);
  border-bottom: 1px solid var(--randzacht);
}
table.opties td { padding: 0; border-bottom: 1px solid var(--randzacht); vertical-align: top; }
table.opties tr:last-child td { border-bottom: 0; }

table.opties .kiesrij { cursor: pointer; }
table.opties .kiesrij td { border-bottom: var(--lipklein) solid var(--kaartrand); }
table.opties .kiesrij td { transition: background-color 130ms ease-out; }
table.opties .kiesrij:hover td { background: var(--accentzacht); }
/* de terugkoppeling zit op het indrukken, niet op het loslaten */
table.opties .kiesrij.druk td { background: var(--accentzacht); }

/* nowrap omdat de letter en het merkje ernaast bij elkaar horen. Zonder dit
   viel het merkje in een smalle kolom onder de letter en werd elke rij twintig
   punten hoger dan nodig. */
table.opties td.letter { width: 3.5rem; font-weight: 620; padding: var(--r3); font-variant-numeric: tabular-nums; white-space: nowrap; }
table.opties td.tekst { padding: var(--r3); line-height: 1.45; }
table.opties td.merkje { width: 5.5rem; padding: var(--r3); font-size: .8125rem; text-align: right; white-space: nowrap; }

table.opties tr.gekozen td { background: var(--accentzacht); }
table.opties tr.gekozen td.letter { color: var(--accent); }

/* Wat je gekozen hebt mag niet alleen aan kleur te zien zijn.

   Hiervoor was het verschil tussen een gekozen en een niet-gekozen rij precies
   twee dingen: een achtergrond van veertien procent accentkleur en de letter in
   diezelfde kleur. Gemeten geeft die achtergrond tegen de kaart ongeveer 1,2 op
   1 aan contrast, waar WCAG voor iets wat geen tekst is 3 op 1 vraagt, en beide
   signalen zijn kleur. Wie kleuren niet onderscheidt, en iedereen die buiten in
   de zon op zijn telefoon kijkt, zag dus niet waar hij op getikt had.

   Daarom komt er een vórm bij: een leeg bolletje voor de letter dat volloopt
   zodra je de rij aantikt. Leeg tegen vol is te zien zonder één kleur te
   hoeven benoemen. Rond bij een vraag met één juist antwoord en vierkant bij
   meerdere, zoals een keuzerondje en een aankruisvakje overal werken; dat zegt
   meteen dat je er meer dan één mag aanwijzen. */
table.opties .kiesrij td.letter::after {
  content: "";
  display: inline-block;
  width: .8125rem;
  height: .8125rem;
  margin-left: .4375rem;
  vertical-align: -.0625rem;
  /* --zacht en niet --rand. Gemeten geeft --rand op de kaart 1,27 op 1, en dan
     is het lege bolletje er wel maar zie je het niet; WCAG vraagt voor iets wat
     geen tekst is 3 op 1. --zacht komt op 6,15 uit. */
  border: 2px solid var(--zacht);
  border-radius: 50%;
  background: transparent;
  box-sizing: border-box;
  transition: background-color 130ms ease-out, border-color 130ms ease-out;
}
table.opties.meervoudig .kiesrij td.letter::after { border-radius: 3px; }
table.opties .kiesrij.gekozen td.letter::after {
  border-color: var(--accent);
  /* De volle kern met een ring van de kaartkleur ertussen: dat is de vorm die
     iedereen als "deze staat aan" leest, ook in zwart-wit. */
  background: var(--accent);
  box-shadow: inset 0 0 0 2px var(--kaart);
}

/* De rij is met een toetsenbord en met VoiceOver te bereiken, dus moet ook te
   zien zijn welke rij de aandacht heeft. */
table.opties .kiesrij:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

table.opties tr.juist td { background: var(--goedzacht); }
table.opties tr.juist td.letter, table.opties tr.juist td.merkje { color: var(--goed); font-weight: 620; }
table.opties tr.misser td { background: var(--foutzacht); }
table.opties tr.misser td.letter, table.opties tr.misser td.merkje { color: var(--fout); font-weight: 620; }

@media not all and (min-width: 37.5rem) {
  /* Ruim genoeg voor de letter met het merkje ernaast en geen punt meer. */
  table.opties td.letter { width: 3.1rem; padding: var(--r3) var(--r2); }
  table.opties td.tekst { padding: var(--r3) var(--r2); }
  table.opties td.merkje { width: 2rem; padding: var(--r3) var(--r2); }
  table.opties td.merkje span { display: none; }
  .vraagtekst { font-size: 1rem; }

  /* De width van 2.6rem hierboven deed niets. Een tabel verdeelt zijn kolommen
     naar de breedste inhoud, en de breedste inhoud van de eerste kolom was niet
     de letter maar de kop "Letter" erboven. Gemeten op een telefoon van 320
     punten breed at die kop 70 punten op: bijna een kwart van het scherm voor
     één letter, en de antwoordtekst ernaast liep daardoor over meer regels dan
     nodig. Het woord verdwijnt hier dus; de kolom blijft staan en de letters
     eronder zeggen zelf wel wat het zijn.

     Het blijft een th en niet niets, want de kolom moet ergens onder hangen en
     de tabel moet ook zonder opmaak leesbaar blijven. */
  table.opties th:first-child {
    font-size: 0;
    padding-left: var(--r2);
    padding-right: var(--r2);
  }
}

.hint { font-size: .8125rem; color: var(--zacht); margin: 0 0 var(--r3); }

/* De knoppen, op de maatvoering van shadcn/ui.

   Wat er verandert en waarom. Hiervoor bepaalde de binnenruimte de hoogte, en
   die liep per knop uiteen: de een werd 48 punten, de ander 30. shadcn zet in
   plaats daarvan een vaste hoogte en centreert de inhoud erbinnen. Daardoor is
   elke knop naast elk invoerveld naast elke keuzeknop even hoog, en dat is het
   grootste deel van wat een shadcn-scherm ordelijk maakt: niet de kleur, maar
   dat alles op dezelfde lijn ligt.

   De hoofdknop volgt shadcn's grote maat (h-10), de kleine knop de kleine
   maat (h-8). Op een aanraakscherm gaan ze allebei naar 44; zie --regelhoog. */
/* De hoofdknop krijgt hier het enige echte "spel"-element van deze opmaak: een
   dikke onderrand in een donkerder tint van dezelfde kleur, die bij een tik
   inzakt in plaats van alleen te verkleuren. color-mix rekent die donkere tint
   uit --accent zelf, dus een andere hoofdkleur kleurt de dieprand automatisch
   mee. De knop zelf verschuift bij :active mee omlaag, zodat het indrukken
   ook voelt als indrukken. Onder prefers-reduced-motion valt dat terug op
   transform: none via de regel verderop in dit bestand; de dieprand zelf
   blijft staan, want een kleurverschil is geen beweging. */
.hoofdknop {
  --diep: var(--accentdonker);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--r2);
  min-height: var(--regelhooggroot);
  background: var(--accent);
  color: var(--opaccent);
  border: 0;
  border-radius: var(--rondknop);
  padding: var(--r2) var(--r5);
  box-shadow: 0 var(--lip) 0 0 var(--diep);
  font: inherit;
  /* Blijft 1rem waar shadcn .875rem zet. shadcn rekent op een compacte knop
     tussen andere bediening; dit is de enige hoofdhandeling op het scherm en
     op een telefoon staat hij schermbreed. Kleiner maken zou hem moeilijker
     raakbaar maken zonder dat er iets rustiger van wordt. Het gewicht ging
     van 620 naar 720: stevige letters horen bij een knop met diepte. */
  font-size: 1rem;
  font-weight: var(--gewicht-vet);
  /* Hoofdletters, zoals Duolingo's knoppen: gevraagd op 11-09-2026, samen met
     de zijbalk en het spelpad. De letterafstand gaat iets open (van -.006em
     naar .01em), want hoofdletters op elkaar gepakt lezen minder makkelijk dan
     kleine letters op elkaar gepakt. */
  text-transform: uppercase;
  letter-spacing: .01em;
  cursor: pointer;
  width: 100%;
  transform: translateY(0);
  transition: transform 110ms ease-out, filter 140ms ease-out, opacity 140ms ease-out,
              box-shadow 110ms ease-out;
}
.hoofdknop:disabled {
  background: var(--uitgeschakeld);
  color: var(--uitgeschakeldtekst);
  box-shadow: none;
  cursor: default;
}
/* shadcn dempt de merkkleur bij zweven (bg-primary/90) in plaats van hem
   op te lichten. Dat leest rustiger: de knop zakt onder je muis in plaats van
   dat hij oplicht. */
@media (hover: hover) {
  .hoofdknop, .kleineknop { transition: transform 110ms ease-out, filter .2s, box-shadow 110ms ease-out; }
  .hoofdknop:not(:disabled):hover, .kleineknop:not(:disabled):hover { filter: brightness(1.1); }
}
.hoofdknop:not(:disabled):active {
  transform: translateY(var(--lip));
  box-shadow: none;
}

@media (min-width: 37.5rem) { .hoofdknop { width: auto; min-width: 12.5rem; } }

.kleineknop {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--r1);
  min-height: var(--regelhoogklein);
  border: 2px solid var(--kaartrand);
  border-bottom-width: var(--lip);
  background: var(--kaart);
  color: var(--accent);
  font-weight: var(--gewicht-vet);
  border-radius: var(--rondklein);
  padding: var(--r1) var(--regelpad);
  box-shadow: none;
  font: inherit;
  /* .8125rem was kleiner dan shadcn's text-sm; op de maat van de reeks gezet
     leest hij beter en staat hij gelijk met de velden ernaast. */
  font-size: var(--regeltekst);
  cursor: pointer;
  transform: scale(1);
  transition: transform 110ms ease-out, background-color 140ms ease-out,
              border-color 140ms ease-out, color 140ms ease-out;
}
/* Onzichtbaar bijvullen tot de 44 punten die Apple aanhoudt, zonder dat de
   knop zwaarder gaat wegen in beeld: dit is de knop voor het bijzaakje naast
   de hoofdknop, en zichtbaar even groot maken zou dat verschil wegpoetsen.
   Alleen verticaal: deze knoppen staan meestal in een rijtje naast elkaar met
   een kleine tussenruimte, en zijwaarts uitrekken laat ze over elkaar vallen
   zodat je de verkeerde tikt.

   Het bedrag rekent zichzelf uit het verschil tussen de zichtbare hoogte en de
   44. Op een aanraakscherm is dat verschil nul, want daar is de knop al 44;
   deze regel vangt de toestellen op die zich als muis melden maar toch met een
   vinger bediend worden. */
.kleineknop::after {
  content: "";
  position: absolute;
  inset: calc((var(--raakvlak) - var(--regelhoogklein)) / -2) 0;
}
/* shadcn's outline-knop verandert bij zweven van vlak, niet van kleur
   (hover:bg-accent). Dat is rustiger dan een rand en letters die ineens indigo
   worden, en het houdt de merkkleur voor waar je werkelijk bent. */
.kleineknop:active { transform: translateY(2px); border-bottom-width: 2px; }
.kleineknop.gevaar:hover { border-color: var(--fout); color: var(--fout); background: var(--foutzacht); }

.oordeel { font-size: 1.1875rem; font-weight: 700; letter-spacing: -.015em; margin-bottom: var(--r1); }
.oordeel.goed { color: var(--goed); }
.oordeel.fout { color: var(--fout); }
/* VR-07: bijna-goed krijgt de waarschuwkleur, niet groen en niet rood. */
.bijnaregel { color: var(--waarschuw); }

.keuzeregel {
  background: var(--achter);
  border-radius: var(--rondklein);
  padding: var(--r3) var(--r4);
  font-size: .9375rem;
  margin: var(--r1) 0 0;
}

/* Wat ging hier mis. Zie web/misging.js.

   De knoppen staan onder elkaar zodra er geen ruimte is en naast elkaar zodra
   die er wel is. Op een telefoon is een rij van vijf knoppen naast elkaar een
   rij van vijf knoppen die je geen van alle kunt lezen, en dan wordt er
   willekeurig getikt en is het antwoord waardeloos. */
#misgingblok {
  margin: var(--r3) 0 0;
  padding: var(--r3) var(--r4);
  border-left: 3px solid var(--waarschuw);
  border-radius: var(--rondklein);
  background: var(--randzacht);
}
#misgingblok h3 { margin: 0 0 var(--r1); font-size: .9375rem; }
#misgingblok .hint { margin: 0 0 var(--r2); }
.redenen { display: flex; flex-wrap: wrap; gap: var(--r2); }
.redenknop {
  flex: 1 1 11rem;
  /* Op een breed scherm passen er vier naast elkaar en zou de vijfde de hele
     regel vullen. Een knop van tachtig tekens breed met vier woorden erin leest
     als iets anders dan zijn buren, terwijl hij dat niet is. */
  max-width: 18rem;
  min-height: 2.75rem;
  padding: var(--r2) var(--r3);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  font-size: .875rem;
  text-align: left;
  cursor: pointer;
  transition: border-color .16s ease, color .16s ease, transform .11s ease-out;
}
.redenknop:active { transform: scale(.97); }
.redenknop.stil {
  color: var(--zacht);
  flex-basis: 100%;
  max-width: none;  /* overslaan mag altijd, en staat dus op zijn eigen regel */
  text-align: center;
}
@media (hover: hover) {
  .redenknop:hover { border-color: var(--accent); color: var(--accent); }
}
.gatvraag { margin-top: var(--r2); }
.gatvraag label { display: block; font-size: .875rem; margin-bottom: var(--r1); }
.gatregel { display: flex; flex-wrap: wrap; gap: var(--r2); }
.gatregel input {
  flex: 1 1 12rem;
  min-width: 0;
  min-height: 2.75rem;
  padding: var(--r2) var(--r3);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  font-size: 1rem;  /* onder de 16px zoomt iOS het scherm in bij het tikken */
}
.gatregel .kleineknop { min-height: 2.75rem; }
.misgingstand {
  margin: var(--r2) 0 0;
  font-size: .875rem;
  color: var(--zacht);
}

/* Waar je vastloopt, op het profielscherm. Een teller links en twee regels
   tekst rechts: wat je aangaf, en wat het platform ermee doet. */
.vastlooplijst { display: flex; flex-direction: column; gap: var(--r2); }
.vastlooprij {
  display: flex;
  align-items: flex-start;
  gap: var(--r3);
  padding: var(--r2) 0;
  border-top: 1px solid var(--rand);
}
.vastlooprij:first-child { border-top: 0; }
.vastloopteller {
  flex: 0 0 auto;
  min-width: 2.25rem;
  font-weight: 680;
  font-size: 1rem;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.vastloopteksten { display: flex; flex-direction: column; gap: .125rem; min-width: 0; }
.vastloopnaam { font-size: .9375rem; font-weight: 560; }
.vastloopwat { font-size: .8125rem; line-height: 1.45; color: var(--zacht); }

.lopend { font-size: .9375rem; line-height: 1.6; }
.lopend.beslis {
  background: var(--accentzacht);
  border-left: 3px solid var(--accent);
  padding: var(--r3) var(--r4);
  border-radius: 0 var(--rondklein) var(--rondklein) 0;
}

/* Staat sinds de mobiele ronde bovenaan de uitleg in plaats van onder de knop
   helemaal onderaan. Zie de opmerking bij #veegwenk in index.html. */
.veegwenk {
  font-size: .8125rem;
  color: var(--zacht);
  margin: 0 0 var(--r3);
  text-align: center;
}

.kaart.klaar { text-align: center; }
.kaart.klaar h2 { margin: 0 0 var(--r2); }

/* ----------------------------------------------------------- voortgang */

.samenvatting {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  box-shadow: var(--schaduw);
  padding: var(--r5);
  margin-bottom: var(--r4);
}
.groot {
  font-size: clamp(2.25rem, 1.8rem + 2vw, 2.75rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.028em;
  font-variant-numeric: tabular-nums;
}
.groot small { font-size: 1rem; font-weight: 400; color: var(--zacht); letter-spacing: -.006em; }

.statusrij { display: flex; flex-wrap: wrap; gap: var(--r2); margin-top: var(--r3); }
.bolletje {
  display: inline-flex;
  align-items: center;
  gap: var(--r1);
  font-size: .8125rem;
  background: var(--achter);
  border-radius: 99px;
  padding: .28rem .7rem;
}
.bolletje i { width: .5rem; height: .5rem; border-radius: 99px; display: block; }
.st-beheerst { background: var(--goed); }
.st-opweg { background: var(--accent); }
.st-zwak { background: var(--fout); }
/* "niet behandeld" is precies de vierde rol uit het palet: geen oordeel, wat
   nog niet gemeten is. */
.st-nieuw { background: var(--onbehandeld); }

.domeinrij {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  box-shadow: var(--schaduwklein);
  padding: var(--r4);
  margin-bottom: var(--r2);
}
.domeinrij .top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--r2); flex-wrap: wrap; }
.domeinrij b { font-size: 1rem; letter-spacing: -.011em; }
.domeinrij .gewicht { font-size: .8125rem; color: var(--zacht); }
.domeinrij .cijfer { font-size: 1.125rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.016em; }
.domeinrij .cijfer.gehaald { color: var(--goed); }

.staaf { display: flex; height: .75rem; border-radius: 99px; overflow: hidden; margin-top: var(--r3); background: var(--onbehandeldzacht); }
.staaf i { display: block; height: 100%; }

.onderwerprij {
  display: flex;
  align-items: center;
  gap: var(--r3);
  padding: var(--r2) var(--r1);
  border-bottom: 1px solid var(--randzacht);
  font-size: .875rem;
}
.onderwerprij:last-child { border-bottom: 0; }
.onderwerprij .code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: .75rem; color: var(--zacht); width: 2.75rem; flex-shrink: 0;
}
.onderwerprij .naam { flex: 1; min-width: 0; }
.onderwerprij .stip { width: .5rem; height: .5rem; border-radius: 99px; flex-shrink: 0; }
.onderwerprij .tel { font-size: .75rem; color: var(--zacht); font-variant-numeric: tabular-nums; }

/* hoe stevig een onderwerp nu staat: loopt leeg naarmate je het langer niet
   hebt geoefend. Een voortgangsbalk, dus de vulling volgt het systeem: accent,
   en amber zodra het wegzakt; het woord "zakt weg" staat er dan naast, zodat
   de kleur nooit de enige drager is. */
.onderwerprij .sterkte {
  width: 3rem;
  height: .3125rem;
  border-radius: 99px;
  background: var(--randzacht);
  overflow: hidden;
  flex-shrink: 0;
}
.onderwerprij .sterkte i {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--accent);
  transform-origin: left center;
  border-radius: 99px;
}
.onderwerprij .sterkte.opfris i { background: var(--waarschuw); }

.bolletje.opfris { color: var(--waarschuw); }

.ronderesultaat { margin: var(--r2) 0 var(--r4); text-align: left; }

.leerrij.vervallen { opacity: .62; }
.leerrij.vervallen .naam { text-decoration: line-through; text-decoration-color: var(--rand); }
.vervallenmerk {
  font-size: .6875rem;
  background: var(--achter);
  color: var(--zacht);
  padding: .12rem .5rem;
  border-radius: 99px;
  white-space: nowrap;
}

.uitklap { margin-top: var(--r4); }
.uitklap summary { cursor: pointer; font-weight: 620; padding: var(--r3) 0; font-size: .9375rem; }

/* ------------------------------------------------------------- leerstof */

#zoek {
  width: 100%;
  padding: var(--r3) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  font-size: 1rem;
  margin-bottom: var(--r4);
}
#zoek:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.leerdomein { margin-bottom: var(--r6); }

.leerrij {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rondklein);
  box-shadow: var(--schaduwklein);
  padding: var(--r3) var(--r4);
  margin-bottom: var(--r2);
}
.leerrij .kop { display: flex; gap: var(--r2); align-items: baseline; }
.leerrij .code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: .75rem; color: var(--zacht);
}
.leerrij .naam { font-weight: 620; flex: 1; letter-spacing: -.008em; }
.leerrij .kern { margin: var(--r2) 0 0; font-size: .875rem; line-height: 1.55; }
.leerrij .waar { margin: var(--r2) 0 0; font-size: .8125rem; color: var(--zacht); line-height: 1.5; }
.leerrij .mist { color: var(--waarschuw); }

/* -------------------------------------------------------------- leerpad */

/* Het leerpad is een lijst en geen slingerend pad meer. De vraag die het moet
   beantwoorden is "waar sta ik nog onder de grens en waar begin ik", en die
   beantwoordt een lijst met getallen beter dan een route met bolletjes. */

.padkiezer {
  display: flex;
  gap: var(--r2);
  overflow-x: auto;
  padding-bottom: var(--r2);
  margin-bottom: var(--r4);
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  /* op de telefoon mag de rij tot aan de rand doorlopen */
  margin-inline: calc(var(--r4) * -1);
  padding-inline: var(--r4);
}
.padkiezer::-webkit-scrollbar { display: none; }

/* Boven de telefoongrens mag de rij afbreken in plaats van doorschuiven.
   Op een breed scherm zijn vijf onderdelen samen 1223 punten en het venster
   896: het vijfde onderdeel stond dan buiten beeld, zonder randje of pijltje
   dat verraadt dat er meer is. Dat is precies het bezwaar waarom de navigatie
   op een telefoon geen schuivende rij meer is (zie web/navigatie.js), en het
   gold hier nog steeds. Op een telefoon blijft het schuiven: daar is een rij
   van vijf brede knoppen onder elkaar te lang, en daar staat sowieso al de
   keuzelijst uit .padkiezer.alslijst. */
@media (min-width: 37.5rem) {
  .padkiezer { flex-wrap: wrap; overflow-x: visible; }
}

.padknop {
  flex-shrink: 0;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  align-items: flex-start;
  border: 1px solid var(--randzacht);
  background: var(--kaart);
  color: var(--zacht);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  font-size: .8125rem;
  cursor: pointer;
  min-height: 2.75rem;
  transform: scale(1);
  transition: transform 110ms ease-out, border-color 150ms ease-out, color 150ms ease-out;
}
.padknop:active { transform: scale(.97); }
.padknop.aan { border-color: var(--accent); color: var(--accent); background: var(--accentzacht); }
.padknop .padnaam { font-weight: 600; white-space: nowrap; }
.padknop .padscore {
  display: flex;
  align-items: baseline;
  gap: .3rem;
  font-variant-numeric: tabular-nums;
  font-size: .75rem;
}
.padknop .padscore b { font-size: .9375rem; }
.padknop .padscore.gehaald b { color: var(--goed); }
.padknop .padvan { opacity: .65; }

/* ------------------------------------------------------------- de kop */

.padkop { margin-bottom: var(--r5); }
.padkop h2 {
  display: flex;
  align-items: center;
  gap: var(--r2);
  font-size: 1.375rem;
  letter-spacing: -.019em;
  margin-bottom: var(--r2);
}

.padfeiten {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r1) var(--r3);
  color: var(--zacht);
  font-size: .875rem;
  margin-bottom: var(--r3);
}
.padfeiten span { display: inline-flex; align-items: center; gap: .3rem; }
/* een puntje tussen de feiten, behalve voor het eerste */
.padfeiten span + span::before { content: "•"; margin-right: .3rem; opacity: .5; }

.padbalk {
  position: relative;
  height: .875rem;
  border-radius: 999px;
  background: var(--onbehandeldzacht);
  overflow: hidden;
  margin-bottom: var(--r3);
  transition: box-shadow 140ms ease-out;
}
.padvulling {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--bandkleur, var(--accent));
  transition: width 420ms cubic-bezier(.32, .72, 0, 1);
}
.padbalk.gehaald .padvulling { background: var(--goed); }
/* dezelfde groene halo als bij de dashboardmeter: een gehaalde grens ziet er
   ook echt uit als gehaald. */
.padbalk.gehaald { box-shadow: 0 0 0 3px var(--goedzacht); }
/* het streepje waar de grens ligt */
.padgrens {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 2px;
  background: var(--tekst);
  opacity: .45;
}

.paduitkomst { font-size: .9375rem; color: var(--zacht); line-height: 1.55; }
.paduitkomst.gehaald { color: var(--goed); }

/* ------------------------------------------------------ filters en zoeken */

.padgereedschap {
  position: sticky;
  top: 3.25rem;
  z-index: var(--laag-inhoud);
  background: var(--achter);
  padding: var(--r2) 0 var(--r3);
  margin-bottom: var(--r2);
}

.padfilters {
  display: flex;
  gap: var(--r2);
  overflow-x: auto;
  scrollbar-width: none;
  margin-bottom: var(--r2);
  margin-inline: calc(var(--r4) * -1);
  padding-inline: var(--r4);
}
.padfilters::-webkit-scrollbar { display: none; }

.filterknop {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--r2);
  border: 1px solid var(--randzacht);
  background: var(--kaart);
  color: var(--zacht);
  border-radius: 999px;
  padding: var(--r2) var(--r3);
  font: inherit;
  font-size: .8125rem;
  min-height: 2.5rem;
  cursor: pointer;
  transition: border-color 150ms ease-out, color 150ms ease-out, background 150ms ease-out;
}
.filterknop.aan { border-color: var(--accent); color: var(--accent); background: var(--accentzacht); font-weight: 600; }
.filterknop.zonder { opacity: .45; }
/* de tekst van een filter hoort op één regel te blijven */
.filterknop { white-space: nowrap; }
.filtertelling {
  font-variant-numeric: tabular-nums;
  background: var(--achter);
  border-radius: 999px;
  padding: .05rem .4rem;
  font-size: .75rem;
}
.filterknop.aan .filtertelling { background: var(--kaart); }

.padzoek {
  width: 100%;
  border: 1px solid var(--randzacht);
  background: var(--kaart);
  color: var(--tekst);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  /* 16px voorkomt dat Safari op de iPhone inzoomt bij het tikken */
  font-size: 1rem;
  min-height: 2.75rem;
}
.padzoek:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* --------------------------------------------------------- de lijst zelf */

.padlijst { display: flex; flex-direction: column; gap: var(--r2); padding-bottom: var(--r6); }

.padrij {
  display: flex;
  align-items: center;
  gap: var(--r3);
  width: 100%;
  text-align: left;
  border: 1px solid var(--randzacht);
  border-left: 3px solid var(--rand);
  background: var(--kaart);
  border-radius: var(--rond);
  padding: var(--r3);
  font: inherit;
  color: var(--tekst);
  cursor: pointer;
  box-shadow: var(--schaduwklein);
  transform: scale(1);
  transition: transform 110ms ease-out, border-color 150ms ease-out, box-shadow 150ms ease-out;
}
.padrij:active { transform: scale(.99); }
@media (hover: hover) {
  .padrij:hover { border-color: var(--accent); box-shadow: var(--schaduw); }
}
.padrij:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.padrij.st-beheerst { border-left-color: var(--goed); }
.padrij.st-opweg { border-left-color: var(--accent); }
.padrij.st-zwak { border-left-color: var(--fout); }
.padrij.st-nieuw { border-left-color: var(--onbehandeld); }
.padrij.opfrissen { border-left-color: var(--waarschuw); border-left-style: dashed; }

.padrijlinks { display: flex; align-items: flex-start; gap: var(--r3); flex: 1; min-width: 0; }

.padcode {
  flex-shrink: 0;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: .75rem;
  font-weight: 640;
  color: var(--zacht);
  background: var(--achter);
  border-radius: var(--rondklein);
  padding: .2rem .4rem;
}

.padrijtekst { display: flex; flex-direction: column; gap: var(--r1); min-width: 0; }
.padrijnaam {
  font-size: .9375rem;
  line-height: 1.35;
  font-weight: 500;
  /* de hele naam mag er staan; afkappen was juist het probleem */
  overflow-wrap: break-word;
}

.padmerken { display: flex; flex-wrap: wrap; align-items: center; gap: var(--r1) var(--r2); }
.padstatus {
  display: inline-flex;
  align-items: center;
  gap: .2rem;
  font-size: .75rem;
  border-radius: 999px;
  padding: .1rem .45rem;
  background: var(--achter);
  color: var(--zacht);
}
.padstatus.st-beheerst { background: var(--goedzacht); color: var(--goed); }
.padstatus.st-opweg { background: var(--accentzacht); color: var(--accent); }
.padstatus.st-zwak { background: var(--foutzacht); color: var(--fout); }
.padstatus.st-nieuw { background: var(--onbehandeldzacht); color: var(--onbehandeld); }
.padstatus.opfris { color: var(--waarschuw); }
.padvragen { font-size: .75rem; color: var(--zacht); opacity: .8; }
/* "nog geen vragen" is geen gewoon bijschrift maar een waarschuwing: tikken op
   die rij levert een melding op. Cursief en iets bleker, zodat het als een
   kanttekening leest en niet als een telling. */
.padvragen.geenvragen { font-style: italic; opacity: .65; }

.padrijrechts {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--r1);
  width: 4.5rem;
}
.padpercentage {
  display: inline-flex;
  align-items: center;
  gap: .15rem;
  font-variant-numeric: tabular-nums;
}
.padpercentage b { font-size: 1.0625rem; letter-spacing: -.014em; }
.padpercentage.boven b { color: var(--goed); }

.padrijbalk {
  display: block;
  width: 100%;
  height: .5rem;
  border-radius: 999px;
  background: var(--onbehandeldzacht);
  overflow: hidden;
}
.padrijbalk i { display: block; height: 100%; border-radius: 999px; background: var(--accent); }
.padrij.st-beheerst .padrijbalk i { background: var(--goed); }
.padrij.st-zwak .padrijbalk i { background: var(--fout); }
.padrij.st-nieuw .padrijbalk i { background: var(--onbehandeld); }

/* -------------------------------------------------------------- podcast */

.speler {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  box-shadow: var(--schaduw);
  padding: var(--r4);
  margin-bottom: var(--r4);
  position: sticky;
  top: 4rem;
  z-index: var(--laag-inhoud);
}
.spelerkop { display: flex; flex-direction: column; margin-bottom: var(--r3); }
.spelerkop strong { font-size: 1rem; letter-spacing: -.011em; }
.spelerkop span { font-size: .8125rem; color: var(--zacht); }
.speler audio { width: 100%; }
.speler pre {
  margin: var(--r2) 0 0;
  padding: var(--r3);
  background: var(--achter);
  border-radius: var(--rondklein);
  font-size: .8125rem;
  line-height: 1.6;
  white-space: pre-wrap;
  max-height: 22rem;
  overflow: auto;
}

.afleveringrij {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r3);
  width: 100%;
  text-align: left;
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rondklein);
  box-shadow: var(--schaduwklein);
  padding: var(--r3) var(--r4);
  margin-bottom: var(--r2);
  font: inherit;
  color: inherit;
  cursor: pointer;
  transform: scale(1);
  transition: transform 110ms ease-out, border-color 150ms ease-out;
}
.afleveringrij:hover { border-color: var(--accent); }
.afleveringrij:active { transform: scale(.99); }
.aflinks { display: flex; align-items: center; gap: var(--r3); min-width: 0; }
.afnummer {
  width: 2rem; height: 2rem; flex-shrink: 0;
  border-radius: 50%;
  background: var(--accentzacht);
  color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  font-size: .8125rem; font-weight: 640;
  font-variant-numeric: tabular-nums;
}
.afmidden { display: flex; flex-direction: column; min-width: 0; }
.afmidden b { font-size: .9375rem; }
.afonderwerpen {
  font-size: .75rem; color: var(--zacht);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.afduur { font-size: .8125rem; color: var(--zacht); flex-shrink: 0; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- bronnen */

.bronrij {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rondklein);
  box-shadow: var(--schaduwklein);
  padding: var(--r3) var(--r4);
  margin-bottom: var(--r2);
}
.bronrij b { display: block; font-size: .9375rem; letter-spacing: -.008em; }
.bronrij .waarvoor { font-size: .875rem; color: var(--zacht); margin-top: var(--r1); line-height: 1.5; }
.bronrij .stand { font-size: .8125rem; margin-top: var(--r2); display: inline-block; padding: .18rem .6rem; border-radius: 99px; background: var(--achter); }
.bronrij .stand.open { color: var(--waarschuw); }

/* de stand van de officiele studiegids, bovenaan het bronnenscherm */
.gidsstand {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-left: 3px solid var(--randzacht);
  border-radius: var(--rondklein);
  box-shadow: var(--schaduwklein);
  padding: var(--r3) var(--r4);
  margin-bottom: var(--r3);
}
.gidsstand.let-op { border-left-color: var(--waarschuw); }
.gidsstand .wanneer { font-size: .9375rem; font-weight: 600; letter-spacing: -.008em; }
.gidsstand .melding { font-size: .875rem; color: var(--zacht); margin-top: var(--r1); line-height: 1.5; }
.gidsstand .gidswijzigingen { margin: var(--r2) 0 0; padding-left: 1.1rem; }
.gidsstand .gidswijzigingen li { font-size: .875rem; line-height: 1.5; margin-bottom: .15rem; }
.gidsstand .waar { font-size: .8125rem; color: var(--zacht); margin-top: var(--r2); }

/* ----------------------------------------------------------------- foto */

.opnameknop {
  display: block;
  border: 2px dashed var(--rand);
  border-radius: var(--rond);
  padding: var(--r6) var(--r5);
  text-align: center;
  cursor: pointer;
  color: var(--accent);
  font-weight: 620;
  font-size: 1rem;
  background: var(--kaart);
  transform: scale(1);
  transition: transform 130ms ease-out, border-color 160ms ease-out, background-color 160ms ease-out;
}
.opnameknop:hover { border-color: var(--accent); background: var(--accentzacht); }
.opnameknop:active { transform: scale(.985); }

.fotostand { margin: var(--r3) 0; font-size: .875rem; color: var(--zacht); }

/* Wat er staat als iets alleen op de Mac kan en die er niet is. Geen rode
   foutkleur: er is niets kapot, dit is een kopie van het platform die wel kan
   overhoren maar geen stof kan maken. Zie web/webwortel.js. */
.zondermac {
  margin: var(--r3) 0;
  padding: var(--r3) var(--r4);
  border-left: 3px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--randzacht);
  font-size: .875rem;
  line-height: 1.5;
  color: var(--zacht);
}

/* nieuw traject aanmaken */
.nieuwtraject .veld { display: flex; flex-direction: column; gap: var(--r1); margin-bottom: var(--r3); }
.nieuwtraject .veld span { font-size: .8125rem; color: var(--zacht); }

/* De drie stappen van het formulier. De kop van een stap staat in de kleur van
   de tekst en niet in het zachte grijs van een bijschrift: hij is de vraag die
   gesteld wordt, en de regel eronder is het antwoord op "hoe dan". */
.nieuwtraject .veldkop {
  font-size: .9375rem !important;
  font-weight: 600;
  color: var(--tekst) !important;
}
.nieuwtraject .veldkop em { font-style: normal; font-weight: 400; color: var(--zacht); }
.nieuwtraject .veldhulp {
  margin: 0 0 var(--r2);
  /* 16 px (LY-02): dit is de uitleg die je moet lezen om het formulier goed in
     te vullen, geen voetnoot. */
  font-size: 1rem;
  line-height: 1.55;
  color: var(--zacht);
}
.nieuwtraject .veldof {
  margin: var(--r1) 0;
  font-size: .8125rem;
  color: var(--zacht);
}
.nieuwtraject textarea {
  padding: var(--r3) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--achter);
  color: var(--tekst);
  font: inherit;
  font-size: .9375rem;
  line-height: 1.5;
  resize: vertical;
  min-height: 8rem;
}
.nieuwtraject textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.nieuwtraject .veldknoppen { display: flex; gap: var(--r2); margin-top: var(--r1); }
.nieuwtraject code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em;
  background: var(--randzacht);
  border-radius: 3px;
  padding: 0 .25em;
}

/* Waarom de knop uit staat. Staat direct onder de knop, want dat is waar je
   kijkt als er niets gebeurt. Geen rood: er is niets fout gegaan, er ontbreekt
   iets, en dat is een ander bericht. */
.nieuwontbreekt {
  margin: var(--r2) 0 0;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--zacht);
}

/* Wat er zojuist gebeurde, in gewone woorden, boven het verslag van de Mac.
   Bij een mislukking krijgt hij een streep in de foutkleur; de tekst zelf zegt
   ook zonder die kleur dat er niets gemaakt is, want kleur alleen is geen
   boodschap. */
.nieuwconclusie {
  margin: var(--r3) 0 var(--r2);
  padding: var(--r3) var(--r4);
  border-left: 3px solid var(--accent);
  border-radius: var(--rondklein);
  background: var(--accentzacht);
  font-size: .875rem;
  line-height: 1.55;
}
.nieuwconclusie.mis {
  border-left-color: var(--fout);
  background: var(--foutzacht);
}
.nieuwtraject input[type="text"] {
  padding: var(--r3) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--achter);
  color: var(--tekst);
  font: inherit;
  font-size: 1rem;
}
.nieuwtraject input[type="text"]:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.opnameknop.klein {
  padding: var(--r3) var(--r4);
  font-size: .9375rem;
  margin-bottom: var(--r2);
  border-width: 1px;
}
.nieuwtraject pre {
  margin: var(--r3) 0 0;
  padding: var(--r3);
  background: var(--achter);
  border-radius: var(--rondklein);
  font-size: .75rem;
  line-height: 1.55;
  white-space: pre-wrap;
  max-height: 18rem;
  overflow: auto;
}

.voetnoot { margin-top: var(--r5); font-size: .8125rem; color: var(--zacht); line-height: 1.6; }
.voetnoot code { background: var(--kaart); padding: .05em .35em; border-radius: var(--r1); }

.leeg { padding: var(--r7) var(--r5); text-align: center; color: var(--zacht); }

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

/* Minder beweging betekent niet geen terugkoppeling, maar een rustiger vorm:
   overvloeien in plaats van verschuiven, en geen doorschieten. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .12s !important;
    scroll-behavior: auto !important;
  }
  .terug:active, .tabs button:active, .hoofdknop:not(:disabled):active,
  .kleineknop:active, .trajectkaart:active, .opnameknop:active { transform: none; }
}
.minder-beweging .hoofdknop:not(:disabled):active, .minder-beweging .kleineknop:active,
.minder-beweging .trajectkaart:active { transform: none; }

/* Lippen uit de kleur zelf (KL-04): 0,09 donkerder in OKLCH en iets minder
   verzadigd. De hex-terugvallen in :root gelden waar dit niet bestaat. */
@supports (color: oklch(from red l c h)) {
  :root {
    --accentdonker: oklch(from var(--accent) calc(l - 0.09) calc(c * 0.9) h);
    --goeddonker: oklch(from var(--goedvol) calc(l - 0.09) calc(c * 0.9) h);
    --foutdonker: oklch(from var(--foutvol) calc(l - 0.09) calc(c * 0.9) h);
  }
}

/* Minder doorschijnendheid betekent vaster materiaal: hogere dekking, geen blur. */
@media (prefers-reduced-transparency: reduce) {
  :root { --glas: var(--kaart); }
  .balk, .tabs { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--kaart); }
  .tabs { box-shadow: 0 1px 0 var(--rand); }
}

/* Meer contrast betekent vaste achtergronden met een duidelijke rand. */
@media (prefers-contrast: more) {
  :root {
    --rand: rgba(20, 30, 50, .4);
    --randzacht: rgba(20, 30, 50, .28);
    --zacht: #3b4759;
    --glas: var(--kaart);
    --accent: #366209;
    --goed: #00634b;
    --fout: #a72023;
    --waarschuw: #874500;
    --onbehandeld: #465967;
  }
  .balk, .tabs { backdrop-filter: none; -webkit-backdrop-filter: none; }
  .kaart, .trajectkaart, .domeinrij, .leerrij, .bronrij, .samenvatting {
    border-color: var(--rand);
  }
}

@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
  :root {
    --rand: rgba(255, 255, 255, .4);
    --randzacht: rgba(255, 255, 255, .28);
    --zacht: #c2ced4;
    --accent: #9bc46b;
    --goed: #4dc5a1;
    --fout: #f9917e;
    --waarschuw: #f0985a;
    --onbehandeld: #9eb0c0;
  }
}

/* De focusring, naar het voorbeeld van shadcn maar met een andere techniek.

   shadcn tekent zijn ring met box-shadow: focus-visible:ring-[3px] op
   ring-ring/50, plus een rand die de ringkleur aanneemt. Dat ziet er goed uit,
   maar een box-shadow verdwijnt in de hoogcontrastmodus van Windows: die modus
   gooit alle schaduwen weg en houdt alleen randen en outlines over. Wie op die
   modus aangewezen is ziet dan niet meer waar hij is.

   Daarom staat hier een gewone outline van 2 punten in de volle ringkleur, die
   in elke modus overeind blijft en zelfstandig de 3:1 haalt die WCAG 2.2 voor
   een focusaanduiding vraagt, met de zachte gloed van shadcn eromheen als
   tweede laag. Valt de gloed weg, dan is de aanduiding nog steeds in orde.

   Dit is dus de vorm van shadcn overnemen zonder zijn zwakke plek mee te
   nemen. */
:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--rond1);
  box-shadow: 0 0 0 4px var(--ringzacht);
}

/* ------------------------------------------------------------------ velden */

/* Eén vorm voor alles waar je in typt of uit kiest, naar shadcn/ui.

   Waarom dit als één regel staat en niet per scherm. De invoervelden waren
   over acht plekken in dit bestand apart opgemaakt, elk met een eigen rand,
   eigen achtergrond en een eigen focusrand die naar binnen viel. Los van
   elkaar klopte elk ervan; naast elkaar gezet waren het acht velden. shadcn
   heeft er één, en dat is het punt van een ontwerptaal.

   Wat overgenomen is: de hoogte van de reeks, de rand in de veldkleur, de
   lichte schaduw eronder (shadow-xs) en dezelfde ring als bij de rest bij
   focus, aan de buitenkant in plaats van naar binnen.

   Wat niet overgenomen is: shadcn zet velden op .875rem met md:text-sm, dus 16
   pixels op een telefoon en 14 op een laptop. Hier blijft het overal 16, want
   de regel die dat afdwingt staat verderop bij de valkuilen op de iPhone en
   heeft !important. Die was er eerder en om een gemeten reden; 14 pixels op
   een laptop is geen winst die het waard is die reden te ondergraven. */
.nieuwtraject input[type="text"],
#opschrijfblok textarea,
#scherm-examen textarea,
#scherm-toevoegen textarea,
#scherm-toevoegen input[type="text"],
#scherm-uitwisselen input[type="text"],
#scherm-uitwisselen select,
.invulblok input[type="text"],
#zoek,
.padzoek {
  border: 1px solid var(--veldrand);
  border-radius: var(--rondklein);
  box-shadow: var(--schaduwklein);
  transition: border-color 140ms ease-out, box-shadow 140ms ease-out;
}

/* Velden waar je één regel in typt krijgen de hoogte van de reeks, zodat ze
   naast een knop even hoog staan. Een textarea niet: die mag meegroeien met
   wat erin staat. */
.nieuwtraject input[type="text"],
#scherm-toevoegen input[type="text"],
#scherm-uitwisselen input[type="text"],
#scherm-uitwisselen select,
.invulblok input[type="text"],
#zoek,
.padzoek {
  min-height: var(--regelhoog);
}

/* Bij focus dezelfde ring als overal, aan de buitenkant. Hiervoor viel hij met
   outline-offset: -1px naar binnen over de rand heen, waardoor het veld
   optisch kromp op het moment dat je erin ging typen. */
.nieuwtraject input[type="text"]:focus,
#opschrijfblok textarea:focus,
#scherm-examen textarea:focus,
#scherm-toevoegen textarea:focus,
#scherm-toevoegen input[type="text"]:focus,
#scherm-uitwisselen input[type="text"]:focus,
#scherm-uitwisselen select:focus,
.invulblok input[type="text"]:focus,
#zoek:focus,
.padzoek:focus {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
  border-color: var(--ring);
  box-shadow: 0 0 0 4px var(--ringzacht);
}

/* ------------------------------------------------- weet-niet en opschrijven */

.knoprij { display: flex; gap: var(--r2); flex-wrap: wrap; align-items: stretch; }
.knoprij .hoofdknop { flex: 1 1 12rem; }
.kleineknop.breed {
  flex: 1 1 10rem;
  display: flex; align-items: center; justify-content: center;
  padding: var(--r3) var(--r4);
  font-size: .9375rem;
}

#opschrijfblok textarea,
#scherm-examen textarea,
#scherm-toevoegen textarea {
  width: 100%;
  padding: var(--r3);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--achter);
  color: var(--tekst);
  font: inherit;
  line-height: 1.5;
  resize: vertical;
  margin-bottom: var(--r2);
}
/* Hier stond font-size: .9375rem. Die won op specificiteit van de
   zoombeveiliging onderaan dit bestand, waardoor juist de twee grootste
   tekstvakken op 15px stonden en iOS bij elke tik inzoomde. De maat komt nu
   van font: inherit plus die beveiliging; zet hier geen font-size meer neer. */
#opschrijfblok textarea:focus,
#scherm-examen textarea:focus,
#scherm-toevoegen textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

#scherm-toevoegen .veld,
#scherm-uitwisselen .veld { display: flex; flex-direction: column; gap: var(--r1); margin-bottom: var(--r3); }
#scherm-toevoegen .veld span,
#scherm-uitwisselen .veld span { font-size: .8125rem; color: var(--zacht); }
#scherm-toevoegen input[type="text"],
#scherm-uitwisselen input[type="text"],
#scherm-uitwisselen select {
  padding: var(--r3) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--achter);
  color: var(--tekst);
  font: inherit;
  font-size: 1rem;
}

.lopend.bron {
  font-size: .8125rem;
  color: var(--zacht);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  word-break: break-word;
}

.bronrij.af { opacity: .55; }
.bronrij .kleineknop { margin-top: var(--r2); }

/* één filmpje op een regel in de lijst bij Opnemen: wanneer en hoe lang het
   was, met de deelknop ernaast */
.filmregel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r2);
  margin-top: var(--r2);
  padding-top: var(--r2);
  border-top: 1px solid var(--randzacht);
}

/* twee lagen navigatie: hoogstens zes keuzes per laag */
.tabs.onder {
  top: 2.9rem;
  z-index: calc(var(--laag-subbalk) - 1);
  padding-top: var(--r1);
  padding-bottom: var(--r2);
  box-shadow: 0 1px 0 var(--randzacht), 0 12px 12px -12px rgba(20, 30, 50, .16);
}
.tabs.onder button { font-size: .875rem; padding: var(--r1) var(--r3); }
.tabs.hoofd { box-shadow: none; }
.tabs.hoofd button { font-weight: 560; }

/* het schrijfblok: wat je overschrijft blijft hangen */
.schrijfkaart {
  background: var(--accentzacht);
  border: 1px solid var(--accent);
  border-radius: var(--rondklein);
  padding: var(--r3) var(--r4);
}
.schrijfkaart ul { margin: 0; padding-left: var(--r4); }
.schrijfkaart li { font-size: .9375rem; line-height: 1.55; margin-bottom: var(--r2); }
.schrijfkaart li:last-child { margin-bottom: 0; }
.schrijfknoppen { display: flex; gap: var(--r2); align-items: center; flex-wrap: wrap; margin-top: var(--r3); }
.bronregel { margin-bottom: var(--r1); }

/* Voorleesknop bij de uitleg. Hij was 20 tot 22 pixels hoog en dat is te klein:
   WCAG 2.5.8 houdt 24 bij 24 aan en Apple 44 bij 44, en juist deze knoppen
   staan per twee naast elkaar, dus de uitzondering voor knoppen met veel lucht
   eromheen gaat hier niet op. De zichtbare knop is nu minstens 24 pixels hoog;
   op een aanraakscherm groeit hij verderop in dit bestand door naar 44. */
.luisterknop {
  margin-left: var(--r2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 1.5rem;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--accent);
  border-radius: 99px;
  padding: .2rem .7rem;
  font: inherit;
  font-size: .6875rem;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  vertical-align: middle;
}
/* Het onzichtbare raakvlak, dezelfde truc als bij .uitlegknop hieronder, maar
   alleen naar boven en beneden. Zijwaarts uitrekken zou de twee knoppen van
   het luisterpaar over elkaar heen laten vallen en dan tik je de verkeerde
   taal aan. Verticaal staat er alleen tekst, dus daar kan het wel: 24 pixels
   knop plus twee keer 10 onzichtbaar is de 44 die Apple aanhoudt. Dit staat
   los van pointer: coarse, want een iPad met trackpad meldt zich als muis
   terwijl er nog steeds met een vinger op getikt wordt. */
.luisterknop { position: relative; }
.luisterknop::after { content: ""; position: absolute; inset: -.625rem 0; }
.luisterknop:hover { border-color: var(--accent); }
.luisterknop:disabled { opacity: .5; cursor: default; }
#uitleggeluid { width: 100%; margin-top: var(--r3); }

/* vragen die buiten het curriculum lijken te vallen: jij beslist */
.buitenrij {
  padding: var(--r3) 0;
  border-bottom: 1px solid var(--randzacht);
}
.buitenrij:last-child { border-bottom: 0; }
.buitenrij .naam { font-size: .9375rem; line-height: 1.5; }
.buitenknoppen {
  display: flex; gap: var(--r2); align-items: center;
  flex-wrap: wrap; margin-top: var(--r2);
}
.leerdoelkiezer {
  flex: 1 1 16rem;
  padding: var(--r1) var(--r2);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  /* geen eigen font-size: een keuzemenu onder de 16 pixels laat iOS ook
     inzoomen, en de zoombeveiliging zou hem toch overrulen */
}

/* ------------------------------------------------------------- uitleg */

/* Het ronde vraagteken achter een woord. Klein genoeg om niet te storen,
   groot genoeg om op een telefoon te raken: de knop meet 1.5rem, oftewel de
   24 bij 24 pixels die WCAG 2.5.8 als ondergrens stelt, en heeft een
   onzichtbare rand van 10 pixels eromheen die hem op de 44 punten brengt die
   Apple aanhoudt voor een raakvlak. Hij stond op 1.25rem en haalde daarmee
   geen van beide. */
.uitlegknop {
  position: relative;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--zacht);
  border-radius: 50%;
  font: inherit;
  font-size: .6875rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  vertical-align: middle;
  transition: color 150ms ease-out, border-color 150ms ease-out;
}
.uitlegknop::after {
  /* het onzichtbare raakvlak: 24 + 2 x 10 = 44 pixels */
  content: "";
  position: absolute;
  inset: -.625rem;
}
@media (hover: hover) {
  .uitlegknop:hover { color: var(--accent); border-color: var(--accent); }
}
.uitlegknop:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* wie de vraagtekens niet wil ziet ze niet, maar de uitleg blijft bereikbaar
   via het instellingenscherm */
.zonder-uitlegknoppen .uitlegknop { display: none; }

.uitlegpaneel {
  width: min(34rem, calc(100vw - 2rem));
  max-height: min(80vh, 44rem);
  overflow-y: auto;
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  background: var(--kaart);
  color: var(--tekst);
  box-shadow: var(--schaduwdik);
  padding: var(--r5);
  /* onder de notch en boven de thuisbalk vandaan */
  margin-bottom: env(safe-area-inset-bottom);
}
.uitlegpaneel::backdrop { background: rgba(10, 14, 22, .45); backdrop-filter: blur(3px); }

/* De titelregel van het uitlegpaneel: de titel links, Sluiten rechts.

   WAAROM HIER center STAAT EN GEEN flex-start (17 augustus 2026)

   Er stond flex-start, en daardoor lag de regel zichtbaar scheef. De twee
   vakken zijn namelijk niet even hoog: de h2 is 20 pixels groot met een
   regelhoogte van 1,25, dus een vak van 25 pixels, en de knop Sluiten heeft
   min-height 2,25rem, dus 36 pixels. Met flex-start liggen de bovenkanten van
   die twee vakken gelijk, maar de tekst zit in allebei in het midden van zijn
   eigen vak. Het gevolg: de titel staat hoger dan het woord Sluiten ernaast.

   Nagemeten in Chrome op http://localhost:8765/, paneel "Hoe lang je nog nodig
   hebt", met het midden van de tekst zelf (Range.getBoundingClientRect) en niet
   van het vak eromheen:

       flex-start   titel 447,8   knop 453,3   scheef  5,5 px
       baseline     titel 450,5   knop 453,3   scheef  2,8 px
       center       titel 453,3   knop 453,3   recht   0,0 px

   baseline lijkt de voor de hand liggende keuze en is hier de op één na beste:
   de knop heeft door zijn min-height meer ruimte onder zijn tekst dan erboven,
   dus zijn basislijn ligt niet in het midden. center legt de twee vakken op
   elkaar en omdat de tekst in allebei gecentreerd staat, vallen de teksten dan
   precies samen. Breekt de titel ooit over twee regels, dan blijft de knop
   netjes in het midden van dat blok staan. */
.uitlegkop { display: flex; align-items: center; justify-content: space-between; gap: var(--r3); }
.uitlegkop h2 { font-size: 1.25rem; letter-spacing: -.018em; margin: 0; }
.uitlegsluit {
  flex-shrink: 0;
  border: 1px solid var(--rand);
  background: var(--achter);
  color: var(--zacht);
  border-radius: 999px;
  padding: var(--r1) var(--r3);
  font: inherit;
  font-size: .8125rem;
  min-height: 2.25rem;
  cursor: pointer;
}
.uitlegkort {
  margin: var(--r3) 0 var(--r4);
  font-size: 1rem;
  font-weight: 500;
  color: var(--accent);
  line-height: 1.5;
}
.uitleglang p { font-size: .9375rem; line-height: 1.65; color: var(--zacht); margin-bottom: var(--r3); }
.uitleglang p:last-child { margin-bottom: 0; }

.uitlegzieook { display: flex; flex-wrap: wrap; align-items: center; gap: var(--r2); margin-top: var(--r4); }
.uitlegzieook:empty { display: none; }
.zieooklabel { font-size: .75rem; color: var(--zacht); text-transform: uppercase; letter-spacing: .05em; }
.zieookknop {
  border: 1px solid var(--randzacht);
  background: var(--achter);
  color: var(--accent);
  border-radius: 999px;
  padding: var(--r1) var(--r3);
  font: inherit;
  font-size: .8125rem;
  min-height: 2.25rem;
  cursor: pointer;
}

/* ------------------------------------------------------- instellingen */

.instelgroep { margin-bottom: var(--r4); }
.instelgroep h2 {
  display: flex;
  align-items: center;
  gap: var(--r2);
  font-size: 1.125rem;
  letter-spacing: -.014em;
  margin-bottom: var(--r2);
}
.instelgroep .uitleg { margin-bottom: var(--r4); font-size: .875rem; }

.instelrij {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r4);
  padding: var(--r3) 0;
  border-top: 1px solid var(--randzacht);
  min-height: 3rem;
}
.instelrij:first-of-type { border-top: 0; }
.instelrij.proef { justify-content: flex-start; }

.insteltekst { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.insteltekst strong { font-size: .9375rem; font-weight: 600; }
.insteltekst .hint { font-size: .8125rem; line-height: 1.45; }

/* de schakelaar: dezelfde vorm als in de systeeminstellingen */
.schakelaar { flex-shrink: 0; position: relative; display: inline-block; width: 3.25rem; height: 2rem; }
.schakelaar input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.schuifje {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--rand);
  transition: background 200ms ease-out;
  pointer-events: none;
}
.schuifje::before {
  content: "";
  position: absolute;
  top: .1875rem;
  left: .1875rem;
  width: 1.625rem;
  height: 1.625rem;
  border-radius: 50%;
  background: #fff;
  box-shadow: var(--schaduwklein);
  transition: transform 200ms cubic-bezier(.32, .72, 0, 1);
}
.schakelaar input:checked + .schuifje { background: var(--goed); }
.schakelaar input:checked + .schuifje::before { transform: translateX(1.25rem); }
.schakelaar input:focus-visible + .schuifje { outline: 2px solid var(--accent); outline-offset: 2px; }

.keuzerij { display: flex; gap: var(--r2); flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
/* De keuzeknop was een pil. shadcn houdt de volle ronding voor merkjes en
   balken, en geeft alles wat je bedient dezelfde hoek als de knoppen ernaast.
   Een filter is bediening, geen merkje, dus hij komt op de reeks. Daarmee
   staat hij ook echt in dezelfde familie als de knop en het veld waar hij
   naast staat, in plaats van als los element.

   De 2,75rem blijft staan: dat is de ondergrens van Apple en die haalt hij nu
   via --regelhoog, die op een aanraakscherm dezelfde waarde aanneemt. */
.keuzeknop {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--r1);
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--zacht);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--regelpad);
  box-shadow: var(--schaduwklein);
  font: inherit;
  font-size: var(--regeltekst);
  min-height: 2.75rem;
  cursor: pointer;
  transition: background-color 140ms ease-out, border-color 140ms ease-out, color 140ms ease-out;
}
.keuzeknop:hover { background: var(--zweefvlak); color: var(--tekst); }
.keuzeknop.aan { border-color: var(--accent); color: var(--accent); background: var(--accentzacht); font-weight: 600; }

.schuifbalk { flex-shrink: 0; width: 10rem; accent-color: var(--accent); height: 2.75rem; }

/* grotere letters: één knop die de hele indeling meeneemt, want alle maten
   staan in rem */
.grote-tekst { font-size: 118%; }

/* -------------------------------------------- laptop, tablet en telefoon */

/* Raakvlakken van minstens 44 punten, zoals Apple aanhoudt. Op een muis mag
   het kleiner, op een vinger niet. */
@media (pointer: coarse) {
  .kleineknop, .filterknop, .keuzeknop, .luisterknop, .zieookknop, .uitlegsluit {
    min-height: 2.75rem;
  }
  .luisterknop { padding: var(--r2) var(--r3); font-size: .8125rem; }
  /* de knop is hier zelf al 44 hoog, dus het onzichtbare raakvlak eromheen mag
     inklappen; anders steekt het nodeloos over de tekst erboven en eronder */
  .luisterknop::after { inset: 0; }
  /* om dezelfde reden: .kleineknop haalt hierboven al 44 met min-height, dus
     het onzichtbare randje eromheen zou er alleen nog overheen steken */
  .kleineknop::after { inset: 0; }
}

@media not all and (min-width: 37.5rem) {
  /* de vraagkop mag omlopen zodra de voorleesknop er niet meer naast past */
  .vraagkop { flex-wrap: wrap; gap: var(--r2); }
  .luisterknop { margin-left: 0; }

  /* de percentagekolom smaller, de naam krijgt de ruimte */
  .padrijrechts { width: 3.5rem; }
  .padrij { padding: var(--r3) var(--r2); gap: var(--r2); }
  .padrijlinks { gap: var(--r2); }
  .padkop h2 { font-size: 1.1875rem; }

  /* het uitlegpaneel komt van onderen, zoals een blad in iOS */
  .uitlegpaneel {
    width: 100%;
    max-width: none;
    max-height: 88vh;
    margin: auto auto 0;
    border-radius: var(--rond) var(--rond) 0 0;
    padding: var(--r4) var(--r4) calc(var(--r5) + env(safe-area-inset-bottom));
  }

  /* een instelling met een lange naam zet zijn knop eronder in plaats van
     ernaast, anders wordt de tekst tot één woord per regel geknepen */
  .instelrij { flex-wrap: wrap; }
  .insteltekst { flex: 1 1 12rem; }
  .schuifbalk { width: 100%; }
  .keuzerij { flex: 1 1 100%; justify-content: flex-start; }
}

/* niets mag de pagina breder maken dan het scherm; een tabel met lange
   antwoorden is de gebruikelijke boosdoener.

   Hier staat break-word en niet anywhere. Die twee breken allebei een te lang
   woord af, maar anywhere telt ook mee in de kleinst mogelijke breedte van het
   element. In een flex-rij mag zo'n element dan tot één letter breed worden
   geknepen, en dan staat de naam verticaal. */
/* Let op: hier staat clip en niet hidden. overflow-x: hidden op zowel html als
   body maakt van body een scroll-container, en dan scrollt het muiswiel de
   pagina niet meer. clip snijdt af zonder die bijwerking. */
html, body { max-width: 100%; overflow-x: clip; }
.opties td, .padrijnaam, .lopend { overflow-wrap: break-word; }

/* elke aflevering in twee talen naast elkaar */
.afleveringrij { cursor: default; }
.afleveringrij:hover { border-color: var(--randzacht); }
.afleveringrij:active { transform: none; }

.taalknoppen { display: flex; gap: var(--r2); flex-shrink: 0; }
.taalknop {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .05rem;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--tekst);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  cursor: pointer;
  min-width: 6.5rem;
  transform: scale(1);
  transition: transform 110ms ease-out, border-color 150ms ease-out, background-color 150ms ease-out;
}
.taalknop:hover { border-color: var(--accent); background: var(--accentzacht); }
.taalknop:active { transform: scale(.96); }
.taalknop .taalnaam { font-size: .875rem; font-weight: 620; }
.taalknop .taalduur { font-size: .75rem; color: var(--zacht); font-variant-numeric: tabular-nums; }
.taalknop.engels .taalnaam { color: var(--accent); }
.taalknop.wacht { opacity: .5; }
.taalknop.wacht:hover { border-color: var(--rand); background: var(--kaart); }

@media not all and (min-width: 37.5rem) {
  .afleveringrij { flex-direction: column; align-items: stretch; gap: var(--r2); }
  .taalknoppen { width: 100%; }
  .taalknop { flex: 1; min-width: 0; align-items: center; }
}

/* de snelheidsknoppen onder de podcastspeler */
.snelheidrij {
  display: flex;
  align-items: center;
  gap: var(--r3);
  flex-wrap: wrap;
  margin-top: var(--r3);
}
.keuzeknop.klein {
  padding: var(--r1) var(--r2);
  min-height: 2.25rem;
  font-variant-numeric: tabular-nums;
}
/* Dezelfde reden als bij --regelhoog: alleen op pointer: coarse vertrouwen
   laat deze knop op 36 punten staan op een toestel dat zich als muis meldt
   maar wel getikt wordt. Gemeten op 375 punten breed met een muis. */
@media (pointer: coarse), not all and (min-width: 37.5rem) { .keuzeknop.klein { min-height: 2.75rem; } }

/* de code in een leerpadrij is aanklikbaar voor uitleg */
.padcode { cursor: help; }

/* een onderwerp zonder meting: streepje in plaats van een percentage */
.padpercentage.ongemeten b { color: var(--zacht); opacity: .7; font-weight: 500; }

/* ------------------------------------------------- valkuilen op de iPhone */

/* Safari zoomt in zodra je in een veld tikt waarvan de letters kleiner zijn
   dan 16 pixels, en zoomt daarna niet vanzelf terug. Alle invoervelden dus
   op minstens 1rem.

   Het !important staat er omdat deze regel het eerder verloor van een
   ID-selector eerder in het bestand (#scherm-toevoegen textarea op .9375rem).
   Een gewone regel op elementen wint het nooit van een ID, hoe ver naar
   achteren hij ook staat, dus kon een nieuwe kleine maat de beveiliging
   stilletjes uitschakelen. Met !important kan dat niet meer gebeuren.
   De 100% blijft erin zodat de knop voor grotere letters de velden nog
   steeds meeneemt; alleen kleiner dan 16 pixels is uitgesloten. */
input, textarea, select { font-size: max(1rem, 100%) !important; }

/* vh rekent op iOS met het scherm inclusief de adresbalk, dus een paneel van
   88vh valt er deels achter. dvh volgt de balk die er echt is. */
.uitlegpaneel { max-height: min(80dvh, 44rem); }
@media not all and (min-width: 37.5rem) { .uitlegpaneel { max-height: 88dvh; } }

/* uitleg in lopende tekst onder de kop van het leerpad */
.padcodewenk, .padnaast {
  font-size: .875rem;
  line-height: 1.55;
  color: var(--zacht);
  margin-top: var(--r3);
}
.padnaast { padding-top: var(--r3); border-top: 1px solid var(--randzacht); }

/* een knop die eruitziet als een link, voor uitleg midden in een zin */
.tekstknop {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: .15em;
  cursor: pointer;
}
.tekstknop:hover { text-decoration-thickness: 2px; }

/* de twee getallen naast elkaar: wat je kent, en wat dat op het examen doet */
.padcijfers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--r3);
  margin: var(--r4) 0;
}
.padcijfer {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding: var(--r3) var(--r4);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  background: var(--kaart);
}
.padcijfer b {
  font-size: 1.75rem;
  letter-spacing: -.022em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}
.padcijfer.gehaald b { color: var(--goed); }
.padcijfer.tweede b { color: var(--zacht); }
.padcijfernaam {
  display: flex;
  align-items: center;
  gap: var(--r2);
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--zacht);
}
.padcijferhint { font-size: .8125rem; color: var(--zacht); line-height: 1.4; }

/* het tweede getal op een onderdeelknop */
.padtweede { font-size: .6875rem; opacity: .75; }

/* ------------------------------------------- podcast bijwerken */

/* De knop en de balk staan bij elkaar boven de afleveringen. Inspreken duurt
   minuten, dus zonder zichtbare voortgang lijkt er niets te gebeuren; de balk
   loopt per aflevering vol en zegt er in woorden bij waar hij is. */

.bijwerkrij {
  display: flex;
  align-items: center;
  gap: var(--r2);
  flex-wrap: wrap;
  margin: var(--r2) 0;
}

/* een knop die je met je duim raakt moet minstens 44 pixels hoog zijn; dat is
   de maat die Apple aanhoudt en op een telefoon merk je het verschil meteen */
.bijwerkrij button { min-height: 2.75rem; padding-inline: var(--r4); }

.bijwerkrij .hint { flex: 1 1 14rem; }

.bijwerkstand {
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  padding: var(--r2);
  margin-bottom: var(--r3);
  background: var(--kaart);
}

.bijwerktekst {
  font-size: .875rem;
  color: var(--zacht);
  margin-bottom: var(--r1);
}

.bijwerkbalk {
  height: .5rem;
  border-radius: 99px;
  background: var(--randzacht);
  overflow: hidden;
}

.bijwerkbalk i {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: 99px;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform .4s ease;
}

/* zolang er nog geen enkele aflevering klaar is weet niemand hoe ver het is;
   dan schuift er een streep heen en weer in plaats van een lege balk */
.bijwerkbalk.onbekend i {
  transform: none;
  width: 35%;
  animation: schuiven 1.6s ease-in-out infinite;
}

@keyframes schuiven {
  0%   { margin-left: 0; }
  50%  { margin-left: 65%; }
  100% { margin-left: 0; }
}

.minder-beweging .bijwerkbalk.onbekend i { animation: none; width: 100%; opacity: .4; }

/* ------------------------------------------------ bediening van de speler */

/* Drie knoppen op een rij: terug, spelen, vooruit. De speelknop staat in het
   midden en is de grootste, want die gebruik je het vaakst. */

.bedieningrij {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--r4);
  margin: var(--r3) 0 var(--r2);
}

.speelknop {
  flex: 0 1 auto;
  min-width: 8rem;
  min-height: 3rem;
}

.rondeknop {
  /* zonder dit knijpt de flexrij ze op een smal scherm plat, en dan mis je ze
     met je duim */
  flex: 0 0 auto;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 999px;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  font-weight: 600;
  font-size: .9375rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .05em;
  box-shadow: var(--schaduwklein);
}

.rondeknop span { font-size: .6875rem; color: var(--zacht); }
.rondeknop:hover { border-color: var(--accent); color: var(--accent); }
.rondeknop:active { transform: scale(.94); }

/* de tijd links en rechts, de balk ertussen */
.tijdrij {
  display: flex;
  align-items: center;
  gap: var(--r3);
}

.tijd {
  font-variant-numeric: tabular-nums;
  font-size: .8125rem;
  color: var(--zacht);
  min-width: 2.75rem;
  text-align: center;
}

.spoelbalk {
  flex: 1;
  -webkit-appearance: none;
  appearance: none;
  height: 1.5rem;             /* ruim aan te raken, ook met een duim */
  background: transparent;
  cursor: pointer;
}

.spoelbalk::-webkit-slider-runnable-track {
  height: .375rem;
  border-radius: 99px;
  background: var(--randzacht);
}

.spoelbalk::-moz-range-track {
  height: .375rem;
  border-radius: 99px;
  background: var(--randzacht);
}

.spoelbalk::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: -.375rem;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: var(--schaduwklein);
}

.spoelbalk::-moz-range-thumb {
  width: 1.125rem;
  height: 1.125rem;
  border: none;
  border-radius: 999px;
  background: var(--accent);
}

.spoelbalk:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

/* Het geluid zelf blijft onzichtbaar, maar niet met display:none: een browser
   mag een weggehaald media-element anders behandelen, en juist bij spelen op de
   achtergrond wil je daar niet van afhangen. Hij staat er dus wel, alleen niet
   in beeld. */
#geluid {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* de code verraadt met een stippellijn dat er uitleg achter zit */
.padcode {
  cursor: help;
  border-bottom: 1px dotted var(--zacht);
}
@media (hover: hover) {
  .padcode:hover { color: var(--accent); border-bottom-color: var(--accent); }
}

/* ---------------------------------------------------------- stof toevoegen */

.neerzetvak {
  position: relative;
  border: 2px dashed transparent;
  border-radius: var(--rond);
  transition: border-color 150ms ease-out, background-color 150ms ease-out;
}
.neerzetvak.erboven {
  border-color: var(--accent);
  background: var(--accentzacht);
}
.neerzetvak textarea { margin-bottom: var(--r1); }
.neerzetwenk { margin-bottom: var(--r4); }

.verslagkop { font-size: .9375rem; font-weight: 600; margin: 0 0 var(--r3); }
.koppellijst { margin-bottom: var(--r3); }
.buitenrij.gedaan { opacity: .55; }

/* ------------------------------------------------------------- voorkennis */

/* De regel "leer eerst P08". Hij moet opvallen zonder als fout te lezen: het
   is geen verwijt maar een kortere weg, dus geen rood maar de waarschuwkleur
   en een streep aan de zijkant zoals bij de andere blokken die iets aanraden. */
.voorkennisregel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--r2);
  margin: var(--r2) 0 0;
  padding: var(--r2) var(--r3);
  border-left: 3px solid var(--waarschuw);
  border-radius: var(--r2);
  background: var(--randzacht);
}
.voorkennisregel .leerlabel {
  font-size: .8125rem;
  font-weight: 640;
  color: var(--waarschuw);
  letter-spacing: -.006em;
}
.voorkennisregel .leerwaarom {
  flex-basis: 100%;
  font-size: .75rem;
  line-height: 1.45;
  color: var(--zacht);
}

/* De stap waar je nu mee bezig bent staat dikker omlijnd. Kleur alleen zou het
   verschil niet dragen: de stip erin heeft al een kleur, en twee betekenissen
   in een kleur leest niemand. */
.voorkennisknop.nubezig {
  border-color: var(--accent);
  border-width: 2px;
}
.voorkennisknop .stapteller {
  font-size: .75rem;
  color: var(--zacht);
  white-space: nowrap;
}

/* Een knop en geen link, want er verandert niets aan het adres: je springt
   binnen de app naar dat onderwerp. */
.voorkennisknop {
  display: inline-flex;
  align-items: center;
  gap: var(--r2);
  padding: var(--r1) var(--r2);
  border: 1px solid var(--rand);
  border-radius: 99px;
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  font-size: .8125rem;
  text-align: left;
  cursor: pointer;
}
.voorkennisknop .stip {
  width: .5rem;
  height: .5rem;
  border-radius: 99px;
  flex-shrink: 0;
}
.voorkennisknop .code { font-weight: 660; font-size: .8125rem; color: var(--zacht); }
.voorkennisknop .naam { font-weight: 500; font-size: .8125rem; }
@media (hover: hover) {
  .voorkennisknop:hover { border-color: var(--accent); color: var(--accent); }
}

/* De regel met de stand en het vraagteken ernaast. */
.bijwerkkop {
  display: flex;
  align-items: flex-start;
  gap: var(--r2);
  margin-bottom: var(--r1);
}

.bijwerkkop .bijwerktekst { flex: 1; margin-bottom: 0; }

/* De wachttijd onder een knop: hoe lang bovenaan, hoe laat eronder. Twee
   regels, want "over 40 min" en "klaar om 14:35" beantwoorden verschillende
   vragen en je wilt ze allebei in één oogopslag. */
.taalknop .taalduur { display: block; }
.wachtduur { display: block; }
.wachtklok {
  display: block;
  font-size: .75rem;
  opacity: .75;
  font-variant-numeric: tabular-nums;
}

/* Twee voorleesknoppen naast elkaar: Nederlands en Engels, over dezelfde stof.
   Dezelfde opzet als bij de podcast, zodat je niet hoeft te leren waar wat zit. */
.luisterpaar {
  display: inline-flex;
  gap: var(--r1);
  align-items: center;
}

.luisterknop.engels {
  color: var(--accent);
  font-style: normal;
}

/* --------------------------------------------- navigatie op een telefoon */

/* Zes hoofdkopjes passen niet in 375 punten. Horizontaal scrollen was de vorige
   oplossing en die werkte niet: wat rechts buiten beeld valt bestaat voor de
   meeste mensen niet, en Instellingen stond helemaal achteraan. Op een smal
   scherm staat er daarom een knop die zegt waar je bent en die bij een tik
   alle elf schermen tegelijk toont. */

.tabs.alsknop {
  display: block;
  overflow: visible;
  padding: var(--r2) var(--r4);
}

.menuknop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r3);
  width: 100%;
  min-height: 2.75rem;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--tekst);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  cursor: pointer;
  text-align: left;
}
.menuknop:active { transform: scale(.99); }

.menutekst { display: flex; flex-direction: column; gap: .05rem; min-width: 0; }
.menutekst b { font-size: 1rem; font-weight: 640; letter-spacing: -.011em; }
.menugroep { font-size: .75rem; color: var(--zacht); }

.menupijl { color: var(--zacht); font-size: 1.125rem; line-height: 1; flex-shrink: 0; }
.menuknop[aria-expanded="true"] .menupijl { transform: rotate(180deg); }

/* het paneel zelf: alles tegelijk in beeld, niets verborgen */
.menupaneel {
  /* top wordt in navigatie.js gezet, vlak onder de knop waar je op tikte */
  position: fixed;
  left: 0;
  right: 0;
  z-index: var(--laag-paneel);
  overflow-y: auto;
  /* Een zwevend vlak, en dat heeft bij shadcn een eigen kleur (popover) los
     van de kaartkleur. In het licht zijn ze hier gelijk; in het donker is het
     zwevende vlak een tint lichter, zodat het losser van de pagina staat dan
     een kaart die er plat op ligt. De schaduw is shadow-md, want een menu
     hangt hoger dan een kaart maar lager dan een venster. */
  background: var(--zweef);
  border-bottom: 1px solid var(--rand);
  border-radius: 0 0 var(--rond) var(--rond);
  box-shadow: var(--schaduwmiddel);
  padding: var(--r4) var(--r4) calc(var(--r4) + env(safe-area-inset-bottom));
  animation: menuomlaag 180ms cubic-bezier(.32, .72, 0, 1);
  transform-origin: top center;
}
@keyframes menuomlaag {
  from { opacity: 0; transform: translateY(-.5rem); }
  to { opacity: 1; transform: translateY(0); }
}
.minder-beweging .menupaneel { animation: none; }

.menugroepblok { margin-bottom: var(--r3); }

/* Korte namen naast elkaar in plaats van onder elkaar. Zo past het hele menu
   op een telefoon, en dat is waar het om ging: wat je moet scrollen om te zien
   vind je niet. */
.menurijen.tweekolommen {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--r1);
}
/* een oneven laatste knop pakt de hele breedte, anders staat er een gat */
.menurijen.tweekolommen > .menurij:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* Een vangnet voor het liggende scherm en voor een heel korte telefoon, waar het
   paneel niet altijd past: een schaduw onderaan die zegt dat er nog iets onder
   zit.

   Alleen met de klasse .scrolt, die navigatie.js erop zet zodra het paneel
   werkelijk meer inhoud heeft dan hoogte. Hij stond hier onvoorwaardelijk, en
   dat was tot voor kort waar omdat het paneel altijd te lang was. Nu het past
   zou diezelfde schaduw beloven dat er meer onder staat terwijl daar niets is,
   en een aanwijzing die liegt is erger dan geen aanwijzing. */
.menupaneel.scrolt {
  background-image: linear-gradient(to top, rgba(16, 34, 40, .12), rgba(16, 34, 40, 0) 1.5rem);
  background-position: bottom;
  background-repeat: no-repeat;
  background-size: 100% 1.5rem;
  background-attachment: local;
}
.menugroepblok:last-child { margin-bottom: 0; }

.menugroepnaam {
  display: block;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--zacht);
  margin-bottom: var(--r2);
}

.menurij {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 2.75rem;
  border: 0;
  background: none;
  color: var(--tekst);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  font-size: 1rem;
  text-align: left;
  cursor: pointer;
}
.menurij.aan { background: var(--accentzacht); color: var(--accent); font-weight: 620; }
.menurij:active { background: var(--achter); }
.menuvink { font-size: .875rem; }

/* de filters op het leerpad mogen omlopen in plaats van wegscrollen */
@media not all and (min-width: 37.5rem) {
  .padfilters {
    flex-wrap: wrap;
    overflow-x: visible;
    margin-inline: 0;
    padding-inline: 0;
  }
}

/* de onderdelen als keuzelijst op een telefoon */
.padkiezer.alslijst { display: block; overflow: visible; margin-inline: 0; padding-inline: 0; }
.padlijstkiezer {
  width: 100%;
  min-height: 2.75rem;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--tekst);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  font-size: 1rem;
}
.padlijsthint { font-size: .8125rem; color: var(--zacht); margin: var(--r2) 0 0; }

/* ------------------------------------------- rekenplek en tijdsaanduiding */

/* De keuze waar het zware werk gebeurt, met beide tijden erbij. */
.keuzepaneel {
  width: min(30rem, calc(100vw - 2rem));
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  background: var(--kaart);
  color: var(--tekst);
  box-shadow: var(--schaduwdik);
  padding: var(--r5);
}
.keuzepaneel::backdrop { background: rgba(10, 14, 22, .45); }
.keuzepaneel h2 { font-size: 1.1875rem; margin-bottom: var(--r2); }

.keuzeblokken { display: grid; gap: var(--r3); margin: var(--r4) 0; }
.keuzeblok {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  text-align: left;
  border: 1px solid var(--randzacht);
  background: var(--achter);
  color: var(--tekst);
  border-radius: var(--rond);
  padding: var(--r3) var(--r4);
  font: inherit;
  cursor: pointer;
  min-height: 2.75rem;
}
.keuzeblok:hover { border-color: var(--accent); }
.keuzeblok b { font-size: 1rem; }
.keuzetijd { color: var(--accent); font-size: .9375rem; font-weight: 600; }
.keuzehint { font-size: .8125rem; color: var(--zacht); line-height: 1.45; }

.onthoudrij { display: flex; align-items: center; gap: var(--r2); font-size: .875rem; color: var(--zacht); }
.onthoudrij input { width: 1.1rem; height: 1.1rem; }
.keuzeknoppen { display: flex; justify-content: flex-end; margin-top: var(--r4); }

/* De voortgangsbalk met tijdsaanduiding. Zweeft rechtsonder zodat je gewoon
   door kunt werken terwijl er iets loopt. */
.voortgangsblok {
  position: fixed;
  right: var(--r4);
  bottom: calc(var(--r4) + env(safe-area-inset-bottom));
  z-index: var(--laag-vast);
  width: min(22rem, calc(100vw - 2rem));
  background: var(--kaart);
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  box-shadow: var(--schaduwdik);
  padding: var(--r3) var(--r4);
}
.voortgangsblok.gedaan { border-color: var(--goed); }

.voortgangkop { display: flex; align-items: center; justify-content: space-between; gap: var(--r3); }
.voortgangtitel { font-size: .9375rem; }
.voortgangsluit {
  border: 0; background: none; color: var(--zacht);
  font: inherit; font-size: .75rem; cursor: pointer; padding: var(--r1);
}

.voortgangbalk {
  height: .375rem;
  border-radius: 999px;
  background: var(--randzacht);
  overflow: hidden;
  margin: var(--r2) 0;
}
.voortgangbalk i {
  display: block; height: 100%; width: 0;
  border-radius: 999px; background: var(--accent);
  transition: width 300ms ease-out;
}
.voortgangsblok.gedaan .voortgangbalk i { background: var(--goed); }

.voortgangregel {
  display: flex; justify-content: space-between; gap: var(--r3);
  font-size: .8125rem; color: var(--zacht);
  font-variant-numeric: tabular-nums;
}

/* De melding stond 24 pixels boven de onderrand, en daar zit met het iOS
   toetsenbord open 300 pixels toetsenbord. Je typte dus en zag nooit wat het
   programma terugzei. --toetsenbord houdt bij hoeveel van het venster op dit
   moment door het toetsenbord bedekt wordt; app.js meet dat met visualViewport
   en zet het hier neer. Zonder toetsenbord is het nul en verandert er niets. */
.kortemelding {
  position: fixed;
  left: 50%; transform: translateX(-50%);
  bottom: calc(var(--r5) + env(safe-area-inset-bottom) + var(--toetsenbord, 0px));
  transition: bottom 180ms ease-out;
  z-index: var(--laag-melding);
  background: var(--tekst); color: var(--kaart);
  border-radius: var(--rond);
  padding: var(--r3) var(--r4);
  font-size: .875rem;
  box-shadow: var(--schaduwdik);
  max-width: min(28rem, calc(100vw - 2rem));
}

@media not all and (min-width: 37.5rem) {
  .voortgangsblok { left: var(--r4); right: var(--r4); width: auto; }
}

/* de tijd die nog nodig is, boven het oefenen */
.tijdregel {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--r1) var(--r4);
  margin-top: var(--r2);
  font-size: .875rem;
  color: var(--zacht);
}
.tijdstuk { display: inline-flex; align-items: baseline; gap: .35rem; }
.tijdstuk b { color: var(--accent); font-weight: 640; }
.tijdmarge { flex: 1 1 100%; font-size: .8125rem; opacity: .85; }

/* Op een telefoon past "tussen 3 uur en 32 minuten en 14 uur" niet naast zijn
   label. Als flexrij werden het dan twee smalle kolommen die allebei over twee
   regels braken en langs elkaar heen lazen. Als blok lopen het getal en het
   label weer als één zin door: "tussen 3 uur en 32 minuten en 14 uur tot je
   alles kent". De marge rechts van het vette deel vervangt de gap, want die
   geldt niet meer zodra de kinderen gewone inline-tekst zijn. */
@media not all and (min-width: 37.5rem) {
  .tijdregel .tijdstuk { display: block; }
  .tijdregel .tijdstuk > b { margin-right: .35rem; }
}

/* ------------------------------- de podcast voorgelezen door het toestel */

/* De keuze tussen de opname van de Mac en de stem van dit toestel. Hij staat
   boven de lijst en niet weggestopt in de instellingen, want welke van de twee
   je hoort is het verschil tussen Piper en de systeemstem, en dat hoor je
   liever niet als verrassing. */
.stemrij {
  display: flex;
  align-items: center;
  gap: var(--r2);
  flex-wrap: wrap;
  margin: var(--r2) 0 var(--r3);
}
.stemrij .stemlabel { font-size: .8125rem; color: var(--zacht); font-weight: 620; }
.stemrij .keuzerij { justify-content: flex-start; flex-shrink: 1; }
.stemrij .hint { flex: 1 1 18rem; }

/* Meelezen bij het voorlezen. Het stuk dat nu klinkt is gemarkeerd, en elk stuk
   is aanklikbaar om daar verder te gaan; daarmee is de tekst zelf de spoelbalk. */
.meelezen {
  margin: var(--r2) 0 0;
  padding: var(--r3);
  background: var(--achter);
  border-radius: var(--rondklein);
  font-size: .875rem;
  line-height: 1.75;
  max-height: 22rem;
  overflow: auto;
  scroll-behavior: smooth;
}
.meelezen span {
  cursor: pointer;
  border-radius: 4px;
  padding: .05em .15em;
  transition: background .18s ease, color .18s ease;
}
.meelezen span:hover { background: var(--randzacht); }
.meelezen span.nu {
  background: var(--accentzacht);
  color: var(--accent);
  font-weight: 600;
}
.minder-beweging .meelezen { scroll-behavior: auto; }
.minder-beweging .meelezen span { transition: none; }

/* De ronde spring-knoppen van deze speler dragen een pijl in plaats van een
   getal; die staat te hoog als hij dezelfde regelhoogte krijgt als "15". */
.toestelspeler .rondeknop { font-size: .8125rem; line-height: 1.1; }

/* Een aflevering zonder opname is niet leeg zolang het toestel de tekst kan
   voorlezen; dan hoort hij ook niet half doorzichtig te zijn. */
.taalknop.wacht.voorleesbaar { opacity: .85; }
.taalknop.wacht.voorleesbaar:hover { border-color: var(--accent); background: var(--accentzacht); }

/* ------------------------------------------------------------- het profiel

   Je eigen geschiedenis op één scherm. De opmaak leunt zoveel mogelijk op wat
   er al staat (.kaart, .uitleg, .hint, de statuskleuren), zodat een profiel er
   niet uitziet als een ander product. Wat hier bij komt zijn drie dingen die
   nergens anders voorkomen: een rij grote getallen, een klok van vierentwintig
   staafjes, en een lijst met onderwerpen die je aan kunt tikken. */

.profielkop { margin: 0 0 var(--r5); }
.profielkop h2 { margin: 0 0 var(--r2); }
.profielkaart { margin-bottom: var(--r4); }
.profielkaart h2 { margin: 0 0 var(--r3); font-size: 1.0625rem; }

/* De grote getallen. Ze wikkelen vanzelf, dus op een telefoon staan er twee
   naast elkaar en op een breed scherm alle drie. Een vaste kolomindeling zou
   op 375 pixels drie getallen naast elkaar persen die dan niet meer leesbaar
   zijn, en juist deze getallen zijn de kern van de kaart. */
.profielcijfers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r4) var(--r5);
  margin: 0 0 var(--r3);
}
.profielcijfer { display: flex; flex-direction: column; min-width: 6.5rem; flex: 1 1 6.5rem; }
.profielcijfer b {
  font-size: 1.75rem;
  font-weight: 660;
  line-height: 1.1;
  color: var(--accent);
  letter-spacing: -.02em;
}
.profielcijfer span { font-size: .8125rem; color: var(--zacht); margin-top: var(--r1); }

/* Een getal dat in woorden staat, zoals "ruim een week geleden", past niet op
   dezelfde regelhoogte als een cijfer van twee tekens. */
.profielcijfer b { overflow-wrap: anywhere; }

/* Je week (GW-01): zeven dagen; de stand staat ook als teken en in aria-label (KL-07). */
.weekstrook { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--r1); margin: var(--r3) 0 var(--r2); }
.weekdag { display: flex; flex-direction: column; align-items: center; gap: 2px; min-height: 3rem; padding: var(--r1) 0; border: 2px solid var(--kaartrand); border-radius: var(--rondklein); color: var(--zacht); font-size: .8125rem; }
.weekdag b { font-weight: 700; color: inherit; }
.weekdag-gedaan { background: var(--goedzacht); border-color: var(--goed); color: var(--goed); }
.weekdag-rust { border-style: dashed; }

/* De klok: één staafje per uur van de dag. De hoogte is het aandeel van dat
   uur, niet het aantal, want anders zou de klok van iemand met tienduizend
   beurten anders schalen dan die van iemand met vijftig. */
.profielklok {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 4rem;
  margin: var(--r3) 0 var(--r1);
}
.profielstaaf {
  flex: 1 1 0;
  height: 100%;
  display: flex;
  align-items: flex-end;
  background: var(--randzacht);
  border-radius: 2px;
  overflow: hidden;
}
.profielstaaf i { display: block; width: 100%; background: var(--accent); opacity: .55; border-radius: 2px; }
.profielstaaf.piek i { opacity: 1; }
.profielklokschaal {
  display: flex;
  justify-content: space-between;
  font-size: .6875rem;
  color: var(--zacht);
  margin: 0 0 var(--r3);
}

/* De verdeling over de statussen als één balk, met de kleuren die overal in
   het platform dezelfde betekenis hebben. */
.profielverdeling {
  display: flex;
  height: .625rem;
  border-radius: 999px;
  overflow: hidden;
  background: var(--randzacht);
  margin: 0 0 var(--r3);
}
.profielverdeling i { display: block; height: 100%; }
.profielverdeling .profielkleur-beheerst { background: var(--goed); }
.profielverdeling .profielkleur-opweg { background: var(--accent); }
.profielverdeling .profielkleur-zwak { background: var(--fout); }
.profielverdeling .profielkleur-nieuw { background: var(--rand); }

.profiellegenda { display: flex; flex-wrap: wrap; gap: var(--r2) var(--r4); margin: 0 0 var(--r3); }
.profielpost { display: inline-flex; align-items: baseline; gap: var(--r1); font-size: .8125rem; color: var(--zacht); }
.profielpost b { font-size: 1rem; font-weight: 640; color: var(--tekst); }
.profielpost.profielkleur-beheerst b { color: var(--goed); }
.profielpost.profielkleur-opweg b { color: var(--accent); }
.profielpost.profielkleur-zwak b { color: var(--fout); }

/* De onderwerpen waar de meeste winst zit. Elke regel is een knop die er
   meteen een vraag over stelt, dus hij moet er ook als een knop uitzien en op
   een telefoon groot genoeg zijn om met een duim te raken. */
.profielfouten { display: flex; flex-direction: column; gap: var(--r2); }
.profielfoutrij {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r3);
  width: 100%;
  padding: var(--r3);
  min-height: 3rem;
  text-align: left;
  background: var(--kaart);
  border: 1px solid var(--rand);
  border-left: 3px solid var(--rand);
  border-radius: var(--rondklein);
  cursor: pointer;
  transition: border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.profielfoutrij.profielkleur-beheerst { border-left-color: var(--goed); }
.profielfoutrij.profielkleur-opweg { border-left-color: var(--accent); }
.profielfoutrij.profielkleur-zwak { border-left-color: var(--fout); }
.profielfoutrij:hover { border-color: var(--accent); box-shadow: var(--schaduwklein); }
.profielfoutrij:active { transform: scale(.99); }
.profielfoutlinks { display: flex; align-items: flex-start; gap: var(--r3); min-width: 0; }
.profielfouttekst { display: flex; flex-direction: column; min-width: 0; }
.profielfoutnaam { font-weight: 560; line-height: 1.35; }
.profielfoutteller { font-size: .75rem; color: var(--zacht); margin-top: .1rem; }
.profielfoutknop {
  flex: 0 0 auto;
  font-size: .75rem;
  font-weight: 620;
  color: var(--accent);
  background: var(--accentzacht);
  padding: var(--r1) var(--r2);
  border-radius: 999px;
}

/* De afnames van het oefenexamen naast de voorspelling. Op een smal scherm
   past dat niet op één regel, dus wikkelt het en blijft de datum vooraan. */
.profielafnames { display: flex; flex-direction: column; gap: var(--r2); margin: 0 0 var(--r3); }
.profielafname {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r1) var(--r3);
  font-size: .8125rem;
  color: var(--zacht);
  padding-bottom: var(--r2);
  border-bottom: 1px solid var(--randzacht);
}
.profielafname:last-child { border-bottom: 0; padding-bottom: 0; }
.profielafnamedatum { flex: 1 1 100%; font-weight: 620; color: var(--tekst); }
.profielafnamegemeten { color: var(--goed); font-weight: 600; }

@media (min-width: 30rem) {
  .profielafnamedatum { flex: 0 0 auto; min-width: 7rem; }
}

/* Op een telefoon staan de grote getallen dichter op elkaar, anders duwt één
   kaart de rest van het scherm weg. */
@media (max-width: 24rem) {
  .profielcijfer b { font-size: 1.5rem; }
  .profielcijfers { gap: var(--r3) var(--r4); }
}

@media (prefers-reduced-motion: reduce) {
  .profielfoutrij { transition: none; }
  .profielfoutrij:active { transform: none; }
}
.minder-beweging .profielfoutrij { transition: none; }
.minder-beweging .profielfoutrij:active { transform: none; }

/* ------------------------------------------------ filmpjes: opnemen en feed

   Twee schermen die met dezelfde opnames werken maar het tegenovergestelde
   doen. Opnemen is een werkbank: het script moet leesbaar zijn, de klok moet
   opvallen, de knoppen moeten binnen duimbereik liggen. De feed is het
   tegendeel van een werkbank; daar telt alleen het beeld, en alle uitleg is
   overlay die je desnoods negeert. */

/* --------------------------------------------------------------- opnemen */

.filmkaart { display: block; }
.filmkop b { display: block; font-size: .9375rem; letter-spacing: -.008em; }
.filmkop .stand {
  font-size: .8125rem;
  color: var(--zacht);
  display: inline-block;
  margin-top: var(--r1);
}

/* Het beeld staat rechtop, want zo houd je een telefoon vast en zo komt het
   in de feed terecht. Een liggend voorbeeldbeeld dat straks staand wordt
   afgespeeld leert je de verkeerde kaderering aan. */
.filmbeeld {
  display: block;
  width: 100%;
  max-width: 22rem;
  aspect-ratio: 9 / 16;
  /* Zodat het beeld op een laag venster niet de knoppen en het script
     wegduwt: je moet de klok en de eerste zin kunnen zien terwijl je praat.
     Op een telefoon is dat krap, dus daar mag het beeld kleiner; wie zichzelf
     opneemt kijkt toch in de lens en niet naar zijn eigen gezicht. */
  max-height: 40vh;
  margin: var(--r4) auto;
  background: #000;
  border-radius: var(--rond);
  object-fit: cover;
}

/* Voor de camera aangaat staat hier geen zwart vlak maar een zin die vertelt
   waarom er nog niets te zien is. */
.filmwacht {
  margin: var(--r4) auto;
  padding: var(--r6) var(--r4);
  max-width: 22rem;
  text-align: center;
  font-size: .875rem;
  color: var(--zacht);
  background: var(--achter);
  border-radius: var(--rond);
}

/* De klok. Vijftien tot dertig seconden is korter dan het voelt, dus het getal
   staat groot en het kleurt: te kort, goed, te lang. Zonder die kleur leest
   niemand een lopende teller tijdens het praten. */
.opnamebalk {
  display: flex;
  align-items: center;
  gap: var(--r3);
  flex-wrap: wrap;
  margin-bottom: var(--r3);
}
.tijdklok {
  font-variant-numeric: tabular-nums;
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -.02em;
  min-width: 3.2rem;
}
.tijdklok.tekort { color: var(--zacht); }
.tijdklok.goed { color: var(--goed); }
.tijdklok.telang { color: var(--waarschuw); }

/* De streep toont waar je bent, met het bedoelde stuk als lichter vlak erin.
   De grenzen komen uit JavaScript, want ze horen bij het script en niet bij de
   opmaak. */
.tijdstreep {
  position: relative;
  flex: 1 1 8rem;
  height: .5rem;
  border-radius: 99px;
  background: var(--randzacht);
  overflow: hidden;
}
.tijdstreep::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 var(--vanaf, 25%);
  width: calc(var(--tot, 50%) - var(--vanaf, 25%));
  background: var(--goedzacht);
}
.tijdstreep i {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--accent);
  transition: width .1s linear;
}
.minder-beweging .tijdstreep i { transition: none; }

.filmknoppen {
  display: flex;
  gap: var(--r2);
  flex-wrap: wrap;
  align-items: center;
  margin: var(--r3) 0;
}

/* De teleprompter. Zin voor zin, want per zin vertellen leest anders dan een
   alinea afwerken: bij een blok tekst ga je meelezen, en dan formuleer je niet
   meer zelf. De zin die aan de beurt is staat groot en de rest zakt weg, zodat
   je met een halve blik ziet waar je bent. */
.teleprompter {
  margin-top: var(--r4);
  padding: var(--r4);
  background: var(--achter);
  border-radius: var(--rond);
  max-height: 16rem;
  overflow: auto;
  scroll-behavior: smooth;
}
.minder-beweging .teleprompter { scroll-behavior: auto; }
.prompterzin {
  margin: 0 0 var(--r3);
  font-size: 1.0625rem;
  line-height: 1.55;
  color: var(--zacht);
  transition: color .25s ease, opacity .25s ease;
}
.prompterzin:last-child { margin-bottom: 0; }
.prompterzin.nu {
  color: var(--tekst);
  font-weight: 600;
}
.prompterzin.gehad { opacity: .45; }
.minder-beweging .prompterzin { transition: none; }

/* Geen camera is geen storing maar een eigenschap van het adres in de balk.
   Dat verdient uitleg in plaats van een zwart vlak, dus het staat er als
   gewone tekst en niet als foutmelding in rood. */
.geencamera {
  border-left: 3px solid var(--waarschuw);
  background: var(--waarschuwzacht);
}
.geencamera b { display: block; margin-bottom: var(--r2); }
.geencamera p { margin: 0 0 var(--r2); font-size: .9375rem; line-height: 1.55; }
.geencamera p:last-child { margin-bottom: 0; }

.misrij .filmknoppen { margin-bottom: 0; }

/* ------------------------------------------------------------------ de feed */

/* De feed neemt alles in wat er onder de balken over is. Alles eromheen is
   weg: geen kop, geen uitleg, geen witruimte. Dat is niet om het op een
   tijdverdrijf te laten lijken maar omdat een filmpje van dertig seconden op
   een telefoon anders half onder de tabbalk verdwijnt.

   --feedhoog wordt door feed.js gemeten en gezet. 100dvh staat er alleen als
   terugval voor het ogenblik voordat die meting binnen is. */
.feedhouder { margin: calc(var(--r5) * -1) calc(var(--r4) * -1) 0; position: relative; }

/* De schakelaar tussen dit traject en alle trajecten.

   Hij ligt over het beeld en niet erboven. Een balk erboven zou de kaart korter
   maken, en wat er dan afvalt is precies de onderrand met de reden en de
   knoppen; datzelfde probleem staat bij pasHoogteAan in feed.js beschreven. De
   donkere achtergrond met vervaging houdt de letters leesbaar boven een licht
   beeld, want welk filmpje eronder staat is niet te voorspellen. */
.feedbereik {
  position: absolute;
  top: var(--r3);
  left: 50%;
  transform: translateX(-50%);
  z-index: calc(var(--laag-inhoud) - 2);
  display: flex;
  gap: 0.15rem;
  padding: 0.15rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  max-width: calc(100% - var(--r4) * 2);
}
.feedbereikknop {
  border: 0;
  border-radius: 999px;
  padding: 0.35rem 0.75rem;
  /* 2,75rem is elders de maat voor een raakvlak; hier mag het kleiner omdat de
     knop over het beeld ligt, maar niet zo klein dat je hem mist. */
  min-height: 2rem;
  background: transparent;
  color: rgba(255, 255, 255, 0.75);
  font: inherit;
  font-size: 0.8rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.feedbereikknop.aan {
  background: #fff;
  color: #000;
  font-weight: 600;
}
.feedbereikknop:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.feedbaan {
  height: var(--feedhoog, 100dvh);
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
  background: #000;
  border-radius: var(--rond);
}
.feedbaan::-webkit-scrollbar { display: none; }
.minder-beweging .feedbaan { scroll-snap-type: none; }

.feedkaart {
  position: relative;
  height: var(--feedhoog, 100dvh);
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.feedbeeld {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

/* Het hele beeld is de knop. Tikken is wat je hier doet, en een knopje in een
   hoek zoeken is dat niet. */
.feedtik {
  position: absolute;
  inset: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.feedkaart.gepauzeerd .feedtik::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  transform: translate(-40%, -50%);
  border-left: 1.4rem solid rgba(255, 255, 255, .92);
  border-top: .9rem solid transparent;
  border-bottom: .9rem solid transparent;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, .6));
}

/* De tekst ligt op het beeld, met een verloop eronder zodat hij leesbaar
   blijft op een licht én een donker filmpje. Vaste kleuren, want dit ligt op
   video en niet op de pagina: hier heeft de licht-donkerstand van het systeem
   niets te zeggen. */
.feedtekst {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--r6) var(--r4) var(--r5);
  color: #fff;
  background: linear-gradient(to top, rgba(0, 0, 0, .82), rgba(0, 0, 0, 0));
  pointer-events: none;
}
.feedtekst > * { pointer-events: auto; }
.feedtekst b { display: block; font-size: 1rem; letter-spacing: -.01em; }

/* Uit welk traject dit filmpje komt. Een klein label boven de titel: de feed
   loopt over al je trajecten heen en zonder dit weet je niet waar je naar
   kijkt. Op de kaart in de feed staat het op een donkere achtergrond, in de
   lijst met aanraders op een lichte; vandaar de tweede regel. */
.feedtraject {
  display: inline-block;
  margin-bottom: .1875rem;
  font-size: .6875rem;
  font-weight: 620;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .78);
}
.bronrij .feedtraject { color: var(--accent); }

/* Waarom dit filmpje hier staat. Dit is de belangrijkste regel van het scherm:
   een volgorde die je niet kunt navertellen vertrouw je niet. */
.feedreden {
  margin: var(--r2) 0 0;
  font-size: .9375rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, .92);
}
.feedbij {
  display: inline-block;
  margin-top: var(--r2);
  font-size: .8125rem;
  color: rgba(255, 255, 255, .68);
  font-variant-numeric: tabular-nums;
}

.feedscript {
  margin-top: var(--r2);
  font-size: .875rem;
  color: rgba(255, 255, 255, .84);
}
.feedscript summary { cursor: pointer; color: rgba(255, 255, 255, .68); }
.feedscript p { margin: var(--r2) 0 0; line-height: 1.5; }

.feedtekst .kleineknop {
  color: #fff;
  border-color: rgba(255, 255, 255, .4);
  background: rgba(255, 255, 255, .1);
}
.feedtekst .kleineknop:hover {
  color: #fff;
  border-color: #fff;
  background: rgba(255, 255, 255, .2);
}

.feedslot {
  flex-direction: column;
  gap: var(--r3);
  padding: var(--r5);
  text-align: center;
  color: #fff;
}
.feedslot p { margin: 0; max-width: 26rem; line-height: 1.6; color: rgba(255, 255, 255, .82); }

/* Op een breed scherm is beeldvullend niet hetzelfde als schermvullend: een
   staand filmpje over 1280 pixels uitrekken levert twee zwarte balken en een
   korrelig beeld. De baan blijft daarom zo breed als een telefoon. */
@media (min-width: 48rem) {
  .feedhouder { margin: 0; display: flex; justify-content: center; }
  .feedbaan { width: 26rem; max-width: 100%; }
}

/* ------------------------------------------------- vraag met ingetypt antwoord

   Het veld staat waar de antwoordtabel zou staan, en niet ergens onderaan: of je
   nu klikt of typt, je kijkt op dezelfde plek. Het is bewust breed en groot,
   want een wiskundig antwoord is soms een heel functievoorschrift en dat moet je
   kunnen nalezen voordat je nakijkt. */
.invulblok { margin: var(--r3) 0 var(--r2); }
.invulblok input[type="text"] {
  width: 100%;
  padding: var(--r3) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--achter);
  color: var(--tekst);
  font: inherit;
  font-variant-numeric: tabular-nums;
}
.invulblok input[type="text"]:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.invulblok .hint { margin: var(--r2) 0 0; }

/* Formules komen van MathML, dat de browser zelf tekent. Er is dus niets te
   stijlen behalve de ruimte eromheen: een breuk is hoger dan een regel tekst en
   zou anders tegen de regel erboven aan komen te staan. */
.formule { display: inline-block; line-height: 1; }
.formule math { font-size: 1.08em; }
.vraagtekst .formule, .lopend .formule { margin: .1em .05em; }

/* --------------------------------------------------------------------------
   De bewaarlijst: wat gaat er mee zonder verbinding.

   De podcast is 334 MB en een geinstalleerde webpagina krijgt op iOS ongeveer
   50 MB. Dat past niet, en de teller hieronder is er om dat te laten zien
   voordat het misgaat in plaats van erna.

   Kleur draagt hier nergens alleen de boodschap. Bij elke stand staat een
   getal, een woord of een teken, want een balk die van groen naar rood loopt
   zegt niets tegen wie kleuren anders ziet.
   -------------------------------------------------------------------------- */

.bewaarpaneel {
  background: var(--kaart);
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  padding: var(--r4);
  margin-bottom: var(--r4);
  box-shadow: var(--schaduwklein);
}

.bewaarkop {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r3);
  flex-wrap: wrap;
  margin-bottom: var(--r3);
}

.bewaarkop strong { font-size: .9375rem; }
.bewaarknoppen { display: flex; gap: var(--r2); flex-wrap: wrap; }

/* De meter zelf. Hij vult van links naar rechts en wisselt van kleur zodra het
   krap wordt, maar het getal ernaast blijft leidend. */
.bewaarbalk {
  height: .5rem;
  border-radius: 999px;
  background: var(--randzacht);
  overflow: hidden;
}

.bewaarbalk i {
  display: block;
  height: 100%;
  width: .5%;
  border-radius: 999px;
  background: var(--goed);
  transition: width .3s ease, background-color .3s ease;
}

.bewaarbalk.bijna i { background: var(--waarschuw); }
.bewaarbalk.krap i { background: var(--fout); }

@media (prefers-reduced-motion: reduce) {
  .bewaarbalk i { transition: none; }
}

.bewaarcijfers {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--r2) var(--r3);
  margin: var(--r2) 0 0;
  font-size: .875rem;
}

.bewaarcijfers b { font-variant-numeric: tabular-nums; }
.bewaarcijfers .bewaarvrij { color: var(--zacht); font-variant-numeric: tabular-nums; }

/* Zonder navigator.storage.estimate() is het getal een aanname, en dat hoort
   erbij te staan: wie op de trein rekent moet weten hoe hard dit is. */
.bewaarcijfers .bewaarschatting {
  flex-basis: 100%;
  color: var(--zacht);
  font-size: .8125rem;
}

.bewaarwaarschuwing {
  margin: var(--r3) 0 0;
  padding: var(--r2) var(--r3);
  border-radius: var(--rondklein);
  font-size: .8125rem;
  background: var(--waarschuwzacht);
  color: var(--waarschuw);
}

.bewaarwaarschuwing.krap { background: var(--foutzacht); color: var(--fout); }

/* Een mislukking blijft staan tot je hem wegklikt. Dat is met opzet: dit is
   precies wat je moet weten voordat je de deur uitgaat, en een balkje dat na
   vier seconden verdwijnt haalt dat niet. */
.bewaarmeldingen:empty { display: none; }
.bewaarmeldingen { display: flex; flex-direction: column; gap: var(--r2); margin-top: var(--r3); }

.bewaarmelding {
  display: flex;
  align-items: flex-start;
  gap: var(--r2);
  padding: var(--r2) var(--r3);
  border-radius: var(--rondklein);
  font-size: .8125rem;
  border: 1px solid transparent;
}

.bewaarmelding.fout { background: var(--foutzacht); color: var(--fout); border-color: var(--fout); }
.bewaarmelding.goed { background: var(--goedzacht); color: var(--goed); }
.bewaarmeldingtekst { flex: 1; min-width: 0; }

.bewaarmeldingweg {
  flex-shrink: 0;
  min-width: 1.75rem;
  min-height: 1.75rem;
  border: 0;
  background: none;
  color: inherit;
  font-size: 1.125rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 999px;
  opacity: .7;
}

.bewaarmeldingweg:hover { opacity: 1; background: var(--randzacht); }
@media (pointer: coarse) { .bewaarmeldingweg { min-width: 2.75rem; min-height: 2.75rem; } }

/* De taalknop en zijn meeneemknop horen bij elkaar, dus staan ze in een paar.
   Zonder dat zou de meeneemknop van de ene taal naast de taalknop van de
   andere kunnen belanden zodra de regel afbreekt. */
.taalpaar { display: flex; align-items: stretch; gap: .25rem; min-width: 0; }

.bewaarknop {
  flex-shrink: 0;
  min-width: 2.25rem;
  padding: 0 var(--r2);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--zacht);
  font-size: .9375rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}

.bewaarknop:hover { border-color: var(--accent); color: var(--accent); background: var(--accentzacht); }
.bewaarknop:active { transform: scale(.96); }

/* Bewaard krijgt de kleur van "dit klopt", plus het vinkje als teken. */
.bewaarknop.bewaard { border-color: var(--goed); color: var(--goed); background: var(--goedzacht); }
.bewaarknop.bewaard:hover { border-color: var(--fout); color: var(--fout); background: var(--foutzacht); }
.bewaarknop.bezig { opacity: .6; cursor: progress; }

@media (pointer: coarse) { .bewaarknop { min-width: 2.75rem; } }
@media (prefers-reduced-motion: reduce) { .bewaarknop { transition: none; } .bewaarknop:active { transform: none; } }

/* Bij de speler: staat deze aflevering op het toestel of komt hij van de Mac. */
.spelerbewaard {
  margin: var(--r3) 0 0;
  font-size: .8125rem;
  color: var(--zacht);
}

.spelerbewaard.mee { color: var(--goed); }

@media not all and (min-width: 37.5rem) {
  .taalpaar { flex: 1; }
  .taalpaar .taalknop { flex: 1; min-width: 0; }
  .bewaarkop { flex-direction: column; align-items: stretch; }
  .bewaarknoppen button { flex: 1; }
}

/* ------------------------------------------------- de foto nakijken

   Het scherm waarin een gelezen foto naast zijn tekst staat, met de plekken
   die de tekstherkenning niet zeker wist. Zie web/proeflezen.js.

   De foto en de tekst staan naast elkaar zodra er ruimte voor is en onder
   elkaar op een telefoon. Naast elkaar is hier geen opsmuk maar de hele
   bedoeling: je vergelijkt wat er staat met wat er gelezen is, en dat kan niet
   als je ervoor moet scrollen. */

.proeflezen {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  box-shadow: var(--schaduw);
  padding: var(--r5);
  margin: var(--r4) 0;
}

.proeflezen h2 { margin-top: 0; }

.proefpaar { display: grid; gap: var(--r4); grid-template-columns: 1fr; }

@media (min-width: 48rem) {
  /* De foto krijgt iets minder dan de helft: de tekst is waar gewerkt wordt,
     de foto is er om naar te kijken. */
  .proefpaar { grid-template-columns: 4fr 5fr; align-items: start; }
  .proeffoto { position: sticky; top: var(--r4); }
}

.proeffoto { margin: 0; }

.proeffoto img {
  width: 100%;
  height: auto;
  border-radius: var(--rond);
  border: 1px solid var(--randzacht);
  background: var(--achtergrond);
}

.proefkant { min-width: 0; }

.proefkant textarea {
  width: 100%;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .875rem;
  line-height: 1.5;
}

/* De stand: hoeveel er nog open staat. Open en klaar krijgen kleur, want dat is
   het enige wat je hier in een oogopslag wilt weten. */
.proefstand { margin-bottom: var(--r4); font-size: .875rem; }
.proefstand p { margin: 0 0 var(--r1); }
.proefopen { color: var(--waarschuw); font-weight: 600; }
.proefklaar { color: var(--goed); font-weight: 600; }

/* Merkjes achter de naam van een stuk: waar het heen gaat, en of het er al in
   staat. Klein en kleurloos van vorm, want ze staan naast elkaar en drie
   schreeuwende labels op een regel leest niemand meer. */
.merkje {
  display: inline-block;
  margin-left: var(--r2);
  padding: .1rem var(--r2);
  border-radius: var(--rondklein);
  font-size: .75rem;
  font-weight: 600;
  vertical-align: middle;
}
.theoriemerk { background: var(--accentzacht); color: var(--accent); }
.opgavemerk { background: var(--goedzacht); color: var(--goed); }
.dubbelmerk { background: var(--waarschuwzacht); color: var(--waarschuw); }

/* Wat het scherm van je wil, in één zin, bovenaan. Zonder deze zin wist niemand
   of het nakijken moest of mocht, en dan begin je er niet aan. */
.proefwat {
  margin: 0 0 var(--r4);
  padding: var(--r3) var(--r4);
  border-radius: var(--rond);
  background: var(--accentzacht);
  color: var(--accent);
  font-size: .9375rem;
  font-weight: 560;
}

/* Zolang er nagekeken wordt is de rest van het toevoegscherm niet aan de beurt.
   Eén ding tegelijk: het plakvak, de bestandskiezer en de twee ophaalblokken
   staan hier niets te doen en maakten van de pagina een rommeltje.

   Het selecteert op id en niet alleen op klasse, want de velden in dit scherm
   worden verderop met #scherm-toevoegen aangesproken en die weegt zwaarder. */
#scherm-toevoegen.nakijkt > *:not(#proeflezen):not(h1) { display: none; }
#scherm-toevoegen.nakijkt > #proeflezen { margin-top: var(--r4); }

/* Waar je gebleven was, boven aan het toevoegscherm. Zie web/proeflezen.js:
   137 bladzijden kijkt niemand in één zitting na. */
.hervatvak {
  margin: 0 0 var(--r4);
  padding: var(--r4);
  border: 1px solid var(--waarschuw);
  border-radius: var(--rond);
  background: var(--waarschuwzacht);
}
.hervatvak p { margin: 0 0 var(--r3); font-size: .9375rem; }

/* De keuze tussen de werklijst en de bladzijde. Twee knoppen, want er zijn twee
   manieren om dit werk te doen en niet meer. */
.proefkeuzebalk { display: flex; gap: var(--r2); margin-bottom: var(--r4); flex-wrap: wrap; }
.proefkeuzebalk .kleineknop.aan {
  background: var(--accentzacht);
  color: var(--accent);
  font-weight: 620;
}

/* ---------------- de werklijst: dezelfde markering één keer

   Dit is het hart van het scherm. Elke rij is één beslissing die op tientallen
   plekken tegelijk landt; zie de uitleg boven in web/proeflezen.js voor waarom
   het per markering gaat en niet per bladzijde. */
.proefwerk { display: flex; flex-direction: column; gap: var(--r3); }

.proefbulk {
  display: flex;
  gap: var(--r2);
  flex-wrap: wrap;
  margin-bottom: var(--r2);
}

.proefgroep {
  border: 1px solid var(--randzacht);
  border-left: 3px solid var(--rand);
  border-radius: var(--rond);
  padding: var(--r3) var(--r4);
  background: var(--kaart);
}
/* Een markering in een som verandert de opgave; een markering in een zin is een
   typefout. Die twee horen er niet hetzelfde uit te zien. */
.proefgroep.insom { border-left-color: var(--waarschuw); }
.proefgroep.intekst { border-left-color: var(--randzacht); opacity: .82; }

.proefgroepkop {
  display: flex;
  align-items: center;
  gap: var(--r2);
  flex-wrap: wrap;
  margin-bottom: var(--r2);
}
.proefmarkering {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9375rem;
  font-weight: 700;
  padding: .1rem var(--r2);
  border-radius: var(--rondklein);
  background: var(--achtergrond);
}
.proefhoeveel { font-size: .8125rem; color: var(--zacht); font-variant-numeric: tabular-nums; }
.sommerk { background: var(--waarschuwzacht); color: var(--waarschuw); }
.tekstmerk { background: var(--randzacht); color: var(--zacht); }

.proefgroepslot { display: flex; gap: var(--r3); margin-top: var(--r2); flex-wrap: wrap; }

.proefopgelost {
  margin: var(--r2) 0 0;
  color: var(--goed);
  font-weight: 600;
  font-size: .875rem;
}

/* Een knop die eruitziet als een link. Voor wat wel moet kunnen maar niet om
   aandacht hoort te vragen: overslaan, weggooien. */
.tekstknop {
  border: 0;
  background: none;
  padding: var(--r1) 0;
  font: inherit;
  font-size: .8125rem;
  color: var(--zacht);
  text-decoration: underline;
  cursor: pointer;
}
.tekstknop:hover { color: var(--accent); }

/* ---------------- door de stukken lopen

   Hier stond een rij van 141 genummerde knoppen. Wat ervoor in de plaats komt
   past op een telefoon: twee pijlen, een teller en een sprong naar het werk. */
.proefpager {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--r2);
  margin-bottom: var(--r3);
}
.proefpagermidden { text-align: center; min-width: 0; }
.proefteller {
  display: block;
  font-size: .875rem;
  font-weight: 620;
  font-variant-numeric: tabular-nums;
}
.proefnaam {
  display: block;
  font-size: .75rem;
  color: var(--zacht);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* De sprongknop en de merkjes lopen over de volle breedte onder de pijlen door,
   zodat de rij zelf op een smal scherm nooit hoeft te wikkelen. */
.proefpager > .breed { grid-column: 1 / -1; }
.proefmerkjes {
  grid-column: 1 / -1;
  display: flex;
  gap: var(--r2);
  flex-wrap: wrap;
  align-items: center;
}
.proefmerkjes .merkje { margin-left: 0; }

/* De balk die zegt hoe ver hij is. Bij 137 bladzijden is dat het verschil
   tussen doorgaan en afhaken. */
.proefbalk {
  height: .375rem;
  border-radius: 999px;
  background: var(--randzacht);
  overflow: hidden;
  margin: var(--r2) 0;
}
.proefbalkvulling {
  height: 100%;
  border-radius: 999px;
  background: var(--goed);
  transition: width .2s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .proefbalkvulling { transition: none; }
}

.proefslot { margin-top: var(--r5); align-items: center; }

/* Het overzicht van alle stukken. Staat ingeklapt achter "Naar een bepaald stuk
   springen"; de kleur zegt waar het werk zit, het nummer brengt je erheen. */
.proefoverzicht {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--r1);
  margin-bottom: var(--r4);
}
.proefoverzicht .hint { margin-right: var(--r1); }

.stukknop {
  min-width: 2rem;
  min-height: 2rem;
  padding: 0 var(--r1);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--zacht);
  font: inherit;
  font-size: .75rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.stukknop.klaarstuk { background: var(--goedzacht); color: var(--goed); }
.stukknop.openstuk { background: var(--waarschuwzacht); color: var(--waarschuw); font-weight: 700; }
.stukknop.dubbelstuk { opacity: .5; text-decoration: line-through; }
.stukknop.hier { outline: 2px solid var(--accent); outline-offset: 1px; }

/* De voortgangsbalk bij het lezen van een stapel foto's. */
.voortgangsbalk { margin: var(--r3) 0; }
.voortgangsbalk .balkbak {
  height: .75rem;
  border-radius: 999px;
  background: var(--onbehandeldzacht);
  overflow: hidden;
}
.voortgangsbalk .balkvulling {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width .2s ease-out;
}
.voortgangsbalk .balktekst {
  margin-top: var(--r1);
  font-size: .8125rem;
  color: var(--zacht);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .voortgangsbalk .balkvulling { transition: none; }
}

.proefplekken { margin-top: var(--r4); }
.proefplekken h3 { margin: 0 0 var(--r3); font-size: .9375rem; }

.proefplek {
  border-left: 3px solid var(--waarschuw);
  padding: var(--r2) 0 var(--r2) var(--r3);
  margin-bottom: var(--r3);
}

.proefregel {
  margin: 0 0 var(--r2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .8125rem;
  color: var(--zacht);
  overflow-wrap: anywhere;
}

.proefkeuzes { display: flex; gap: var(--r2); flex-wrap: wrap; align-items: center; }

.proefeigen {
  flex: 1 1 14rem;
  min-width: 0;
  font-size: .875rem;
}

/* De formulehulp staat ingeklapt: hij is er voor als je hem nodig hebt en hoort
   niet in de weg te staan bij een foto zonder formules. */
.proefformule { margin: var(--r4) 0; }
.proefformule summary { cursor: pointer; font-weight: 600; }
.proefformule > *:not(summary) { margin-top: var(--r3); }

/* Ruim gezet, want dit vak is er om te controleren of de formule klopt. Staat
   hij klein, dan zie je het verschil tussen een macht en een index niet en heeft
   het voorbeeld geen zin. */
.proefvoorbeeld {
  padding: var(--r4);
  background: var(--achtergrond);
  border-radius: var(--rond);
  border: 1px solid var(--randzacht);
  font-size: 1.375rem;
  line-height: 2;
  overflow-x: auto;
}

.proeftekens { display: flex; gap: var(--r2); flex-wrap: wrap; align-items: center; }
.proeftekens .kleineknop { font-size: 1.125rem; min-width: 2.75rem; }

@media not all and (min-width: 37.5rem) {
  .proeflezen { padding: var(--r4); }
  /* Op een telefoon is de foto boven de tekst genoeg om mee te kijken; hoger
     dan een halve schermhoogte duwt hij het tekstvak van het scherm af. */
  .proeffoto img { max-height: 45vh; object-fit: contain; }
}

/* ------------------------------------------------- voorstellen goedkeuren

   Het goedkeurscherm voor AI-voorstellen (web/voorstellen.js). Zelfde
   gedachte als het proefleesscherm: links wat de machine voorstelt, rechts
   de bron waar je het tegen nakijkt. */

.voorstelkaart { border: 1px solid var(--rand, #ccc); border-radius: var(--rondklein); padding: var(--r3, 1rem); margin-block: var(--r3, 1rem); }
.voorstelkop { display: flex; justify-content: space-between; gap: var(--r2, 0.5rem); flex-wrap: wrap; align-items: baseline; }
.voorstelpaar { display: grid; grid-template-columns: 3fr 2fr; gap: var(--r3, 1rem); margin-block: var(--r2, 0.5rem); }
.voorstelopties { list-style: none; padding: 0; }
.voorstelopties .juist { font-weight: 600; }
.voorstelbron blockquote { margin: 0.25rem 0 0.75rem; padding-left: 0.75rem; border-left: 3px solid var(--rand, #ccc); font-style: italic; }
/* --nadruk bestaat niet in dit palet; dat viel dus altijd terug op #2a6, een
   groen dat buiten de vier betekeniskleuren valt en in het donker niet
   meeschakelt. Een citaat uit je eigen stof is "dit klopt", en dat is --goed. */
.voorstelbron .voorstelcitaat { border-left-color: var(--goed); }
.voorstelwaarschuwing { font-weight: 600; color: var(--waarschuw, #815600); }
.voorstelaantalveld input { width: 4.5rem; }

/* Een nagerekende opgave verdient een ander merk dan een waarschuwing: hier is
   juist iets extra's gedaan, namelijk het antwoord langs een tweede weg
   controleren. Groen dus, in dezelfde betekenis als elders op het platform. */
.voorstelnagerekend {
  color: var(--goed, #0d7050);
  background: var(--goedzacht, rgba(13, 112, 80, .11));
  border-radius: var(--rondklein, .5rem);
  padding: var(--r2, .5rem);
  font-size: .9em;
}

/* Het merk op elke voorstelkaart. Dit hoort niet weg te vallen tussen de rest:
   wie snel door de lijst bladert moet in een oogopslag zien dat dit geen eigen
   stof is. */
.voorstelmerk {
  font-size: .78em;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--waarschuw, #815600);
  background: var(--waarschuwzacht, rgba(129, 86, 0, .12));
  border-radius: 999px;
  padding: .15rem .55rem;
  white-space: nowrap;
}

/* ---------------------------------------------------- het dekkingsoordeel

   Het platform stelt zelf vast of je de slaaggrens haalt met wat er ligt. Dat
   oordeel staat boven de knoppen, want eerst weten waar je staat en dan pas
   iets doen. Bij een tekort krijgt de kaart een gekleurde rand: niet als
   alarm, maar omdat "je komt 33 procent tekort" geen mededeling is die je
   over het hoofd mag zien. */
.dekkingkaart {
  border: 1px solid var(--rand, #ccc);
  border-left: 4px solid var(--goed, #0d7050);
  border-radius: var(--rondklein, .5rem);
  padding: var(--r3, 1rem);
  margin-block: var(--r3, 1rem);
  background: var(--kaart, #fff);
}
.dekkingtekort { border-left-color: var(--waarschuw, #815600); }
.dekkingoordeel { margin: 0 0 var(--r2, .5rem); font-weight: 500; }
.dekkingcijfers {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r3, 1rem);
  margin-block: var(--r2, .5rem);
}
.dekkinggetal { display: flex; flex-direction: column; }
.dekkinggetal strong { font-size: 1.5rem; line-height: 1.1; }
.dekkinglijst { margin: var(--r2, .5rem) 0 0; padding-left: 1.1rem; }
.dekkinglijst li { margin-bottom: .35rem; }
.dekkinglijst .hint { display: block; }

@media not all and (min-width: 37.5rem) {
  /* Op een telefoon onder elkaar: eerst de vraag, dan de bron. */
  .voorstelpaar { grid-template-columns: 1fr; }
}

/* ------------------------------------------------ tabbalk onderaan (telefoon)

   Zes knoppen onderaan: dezelfde zes als de zijbalk links op een breed scherm
   (web/schil.js) — Leren, Oefenen, Agenda, Buddy, Profiel, Instellingen.
   Waarom onderaan staat in web/tabbalk.js.

   Op een breed scherm bestaat deze balk niet. Daarom staat display: none in de
   gewone regel en komt de balk pas terug binnen de mediaregel: zo is er op een
   breed scherm werkelijk niets veranderd, ook niet als het hidden-kenmerk om
   welke reden dan ook weg zou vallen. */

.tabbalk { display: none; }

@media not all and (min-width: 37.5rem) {
  .tabbalk {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--laag-vast);
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    background: var(--glas);
    backdrop-filter: var(--glasblur);
    -webkit-backdrop-filter: var(--glasblur);
    /* een zachte rand naar boven, spiegelbeeld van de rand onder de tabs */
    box-shadow: 0 -1px 0 var(--randzacht), 0 -12px 12px -12px rgba(20, 30, 50, .16);
    /* De veilige zone: op een toestel met een streep onderaan valt anders de
       onderste rij knoppen half onder die streep. */
    padding-bottom: env(safe-area-inset-bottom);
  }

  /* Het hidden-kenmerk moet ook binnen deze mediaregel winnen; met alleen
     .tabbalk zou display: grid het overrulen. */
  .tabbalk[hidden] { display: none; }

  .tabknop {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .0625rem;
    /* 2,75rem is 44 punten: het kleinste vlak dat een duim betrouwbaar raakt.
       De knop is hoger, maar nooit lager. */
    min-height: 2.75rem;
    padding: .375rem .125rem calc(.375rem + 1px);
    border: 0;
    /* een streepje boven de actieve knop; hier alvast doorzichtig, zodat de
       knop niet een pixel verspringt zodra hij aangaat */
    border-top: 2px solid transparent;
    background: transparent;
    color: var(--zacht);
    font: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color 140ms ease-out;
  }
  .tabknop:active .tabicoon { transform: scale(.9); }

  .tabicoon {
    width: var(--icoonmaat);
    height: var(--icoonmaat);
    stroke-width: var(--icoonlijn);
    transition: transform 110ms ease-out, stroke-width 140ms ease-out;
  }
  /* De kea (Buddy-knop) tekent zichzelf al op een vierkant; hij hoeft niet nog
     eens even groot als de Iconoir-iconen te zijn om optisch te kloppen. */
  .tabknop .kea { width: 1.375rem !important; height: 1.375rem !important; }

  /* 11 px (LY-03): bij zes knoppen was dit 9 px, onder wat Apple als kleinste
     leesbare label noemt. Met vijf is er de breedte voor. */
  .tablabel {
    font-size: .6875rem;
    line-height: 1.05;
    letter-spacing: -.005em;
    font-weight: 560;
    text-transform: uppercase;
    text-align: center;
  }

  /* Welke knop aanstaat is aan vier dingen te zien: het streepje erboven, de
     dikkere lijn van het icoon, de zwaardere letter en de kleur. Kleur alleen
     zou het voor een deel van de lezers onzichtbaar maken. */
  .tabknop.aan {
    color: var(--accent);
    border-top-color: var(--accent);
  }
  .tabknop.aan .tabicoon { fill: var(--accentzacht); }
  .tabknop.aan .tablabel { font-weight: 680; }

  /* Ruimte onder de inhoud, anders schuift de laatste knop van een scherm
     onder de balk. De balk is ongeveer 3,5rem hoog plus de veilige zone. */
  body.mettabbalk main {
    padding-bottom: calc(var(--r6) + var(--tabbalk-hoog) + env(safe-area-inset-bottom) + var(--toetsenbord, 0px));
  }

  /* De filmpjesfeed meet zijn eigen hoogte en trekt de balk er al vanaf; die
     extra ruimte zou daar alleen een strook leegte onder de kaart maken. */
  body.mettabbalk main:has(#scherm-feed.aan) { padding-bottom: 0; }

  /* Wat onderaan zweeft moet boven de balk blijven zweven en niet erachter.
     De korte melding rekent zelf al met het toetsenbord; daar komt de hoogte
     van de balk bij. Staat het toetsenbord open, dan is de balk zelf niet in
     beeld, maar dan zit de melding toch al hoger dan de balk zou staan. */
  body.mettabbalk .voortgangsblok { bottom: calc(var(--r4) + var(--tabbalk-hoog) + env(safe-area-inset-bottom)); }
  body.mettabbalk .kortemelding {
    bottom: calc(var(--r3) + var(--tabbalk-hoog) + env(safe-area-inset-bottom) + var(--toetsenbord, 0px));
  }

  /* Instellingen op Profiel (LY-03, B-60): de ingang die uit de tabbalk ging.
     Rechtsboven, naast de titel, zoals het tandwiel op een profiel in de meeste
     apps. web/tabbalk.js zet de knop neer. Zwevend en niet absoluut: dan loopt
     de ondertitel eromheen in plaats van eronder te verdwijnen. */
  .profielinstellingen {
    float: inline-end;
    margin-inline-start: var(--r2);
    margin-block-end: var(--r2);
    display: inline-flex;
    align-items: center;
    gap: var(--r1);
    min-height: var(--raakvlak);
    padding: 0 var(--r3);
    border: 1px solid var(--rand);
    border-radius: var(--rondklein);
    background: var(--kaart);
    color: var(--tekst);
    font: inherit;
    font-size: .875rem;
    font-weight: 600;
    cursor: pointer;
  }
}
@media (min-width: 37.5rem) {
  .profielinstellingen { display: none; }
}

/* --------------------------------------------------- zijbalk (breed scherm)

   De vaste hoofdnavigatie links, in de geest van Duolingo: grote iconen en
   woorden in hoofdletters, de actieve knop in een lichte omkaderde pil. Zie
   web/schil.js voor de zes knoppen en waarom precies deze zes. Op een
   telefoon bestaat deze balk niet; de tabbalk onderaan (hierboven in dit
   bestand) draagt daar vijf van deze knoppen; Instellingen zit onder Profiel.

   De grens is --bp-medium (600 px), dezelfde grens als de tabbalk hierboven
   en als web/schermmaat.js aan navigatie.js geeft: samen dekken zij en dit
   bestand precies de twee kanten van diezelfde knip. */

.zijbalk { display: none; }

@media (min-width: 37.5rem) {
  :root { --zijbalkbreedte: 11.5rem; }

  .zijbalk[hidden] { display: none; }
  .zijbalk:not([hidden]) {
    display: flex;
    flex-direction: column;
    gap: var(--r1);
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: var(--zijbalkbreedte);
    padding: calc(var(--r6) + env(safe-area-inset-top)) var(--r3) var(--r4);
    background: var(--kaart);
    border-right: 1px solid var(--randzacht);
    overflow-y: auto;
    z-index: var(--laag-navigatie);
  }

  .zijknop {
    display: flex;
    align-items: center;
    gap: var(--r3);
    min-height: var(--raakvlak);
    padding: var(--r2) var(--r3);
    border: 2px solid transparent;
    border-radius: var(--rond2);
    background: transparent;
    color: var(--zacht);
    font: inherit;
    cursor: pointer;
    text-align: left;
    -webkit-tap-highlight-color: transparent;
    transform: scale(1);
    transition: background-color 140ms ease-out, border-color 140ms ease-out,
                color 140ms ease-out, transform 110ms ease-out;
  }
  .zijknop:hover { background: var(--randzacht); }
  .zijknop:active { transform: scale(.97); }

  .zijicoon {
    width: var(--icoonmaat);
    height: var(--icoonmaat);
    stroke-width: var(--icoonlijn);
    flex-shrink: 0;
    transition: stroke-width 140ms ease-out;
  }
  /* De kea (Buddy) tekent zichzelf al vierkant en hoeft geen stroke-regels. */
  .zijknop .kea { flex-shrink: 0; }

  .zijlabel {
    font-size: .8125rem;
    letter-spacing: .015em;
    font-weight: 680;
    text-transform: uppercase;
  }

  /* De pil: een lichte vlakkleur en een rand in dezelfde kleur, precies zoals
     Duolingo's actieve zijbalkknop. Niet alleen kleur: ook de rand en de
     dikkere iconenlijn dragen mee, voor wie kleur lastig onderscheidt. */
  .zijknop.aan {
    background: var(--accentzacht);
    border-color: var(--accent);
    color: var(--accent);
  }
  .zijknop.aan .zijicoon { fill: var(--accentzacht); }

  /* De inhoud schuift mee naar rechts. body-padding en niet een marge per
     element: header, .tabs, #verbinding en main staan als losse kinderen van
     body (geen gezamenlijke omvatter), en position: fixed voor de zijbalk zelf
     ontsnapt toch aan deze padding, dus die blijft precies op links 0 staan. */
  body.metzijbalk { padding-left: var(--zijbalkbreedte); }
}

@media (prefers-reduced-motion: reduce) {
  .zijknop { transition: none; }
  .zijknop:active { transform: none; }
}

/* --------------------------------------------- waarom deze vraag hier staat

   De regel boven de vraag in de opdrachtenfeed. Hij zegt uit welk traject de
   vraag komt en waarom juist dat traject aan de beurt was. Zie
   web/opdrachtenfeed.js voor de weging waar die zin uit volgt. */

.opdrachtherkomst {
  margin: 0 0 var(--r4);
  padding: var(--r3) var(--r4);
  background: var(--accentzacht);
  border-radius: var(--rondklein);
  border-left: 3px solid var(--accent);
}
.opdrachtherkomst[hidden] { display: none; }

.opdrachtreden {
  margin: 0;
  font-size: .9375rem;
  line-height: 1.45;
  color: var(--tekst);
}
.opdrachtreden b { font-weight: 660; }

.opdrachtaandeel {
  margin: var(--r2) 0 0;
  font-size: .8125rem;
  line-height: 1.4;
  color: var(--zacht);
}

/* ------------------------------------------------------- wat kan dit

   Het scherm dat uitlegt wat het platform kan en hoe je dat narekent. De vorm
   draagt hier de betekenis: elke functie is één kaart, en binnen die kaart
   staan drie dingen die je uit elkaar moet kunnen houden zonder te lezen.

     de uitleg   gewone tekst, want dat is het gewone geval
     de proef    een blok met een streep in het accent ernaast, omdat dit het
                 enige is waar je iets mee moet DOEN
     de grens    een blok in amber, want dat is de kleur voor "let op", en er
                 staat altijd het woord Grens bij zodat de kleur het niet
                 alleen hoeft te dragen

   Kleur is nergens de enige drager; zie de afweging bovenaan dit bestand. */

.kanhetgroep { margin: 0 0 var(--r6); }

/* De kop van een groep moet een stap groter zijn dan de kop van een kaart
   eronder. Die kaartkoppen zijn hier h3 maar zien er met opzet uit als gewone
   koppen (zie hieronder), en met de standaard h2 van 1,06rem ernaast waren de
   twee niveaus even groot: "Oefenen" en "De volgende vraag wordt voor je
   gekozen" lazen als kop en kop, niet als kop en onderdeel daarvan. Nu loopt
   de trap van 1,75rem naar 1,25rem naar 1rem. */
.kanhetgroep h2 {
  margin: 0 0 var(--r3);
  font-size: 1.25rem;
  letter-spacing: -.016em;
}

/* Dezelfde schaduw als .kaart en .trajectkaart, en niet de kleine van de
   lijstrijen. Dit is een kaart met volle padding, dus hij hoort ook als kaart
   te liggen; met de kleine schaduw lag "Wat kan dit?" merkbaar platter dan elk
   ander scherm ernaast. */
.kanhetkaart {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  box-shadow: var(--schaduw);
  padding: var(--r5);
  margin-bottom: var(--r3);
}
/* h3 is in dit platform een klein hoofdlettertje boven een blok. Hier is het
   de naam van een functie en dus een echte kop, die je in één oogopslag moet
   kunnen scannen langs twintig kaarten. Vandaar dat alles wat h3 tot label
   maakt hier weer uit gaat. */
.kanhetkaart h3 {
  margin: 0 0 var(--r2);
  font-size: 1rem;
  line-height: 1.3;
  letter-spacing: -.008em;
  text-transform: none;
  font-weight: 650;
  color: var(--tekst);
}
.kanhetwat { margin: 0 0 var(--r3); line-height: 1.55; }

.kanhetlabel {
  display: block;
  font-size: .75rem;
  font-weight: 660;
  letter-spacing: .04em;
  text-transform: uppercase;
  margin-bottom: var(--r1);
}

.kanhetproef {
  background: var(--accentzacht);
  border-left: 3px solid var(--accent);
  border-radius: var(--rondklein);
  padding: var(--r3);
  margin: 0 0 var(--r3);
}
.kanhetproef .kanhetlabel { color: var(--accent); }
.kanhetproef p { margin: 0; line-height: 1.55; }

/* Een grens is geen waarschuwing. Amber betekent in dit platform overal "let
   op, hier ligt werk voor je"; een grens is juist het tegenovergestelde: dit
   gaat nooit veranderen en er valt niets aan te doen. Stond hij ook in amber,
   dan zag "Dit werkt alleen als de Mac aan staat" er precies zo uit als "Dit
   moet nog gebouwd worden", en dat zijn twee heel verschillende mededelingen.
   Daarom neutraal grijs: het valt op als een ander soort blok, zonder te
   vragen om een handeling die er niet is. */
.kanhetgrens {
  background: var(--randzacht);
  border-left: 3px solid var(--zacht);
  border-radius: var(--rondklein);
  padding: var(--r3);
  margin: var(--r3) 0 0;
}
.kanhetgrens .kanhetlabel { color: var(--zacht); }
.kanhetgrens p { margin: 0; line-height: 1.55; font-size: .9375rem; }

/* De cijfers uit de stof. Twee kolommen zolang er ruimte is; op een telefoon
   onder elkaar, want een omschrijving als "Onderwerpen zonder één vraag" past
   naast een waarde niet meer op 375 punten breed. */
.kanhetcijfers {
  display: grid;
  grid-template-columns: minmax(9rem, 14rem) 1fr;
  gap: var(--r1) var(--r3);
  margin: 0 0 var(--r3);
  font-size: .875rem;
}
.kanhetcijfers dt { color: var(--zacht); }
.kanhetcijfers dd { margin: 0; font-variant-numeric: tabular-nums; }

.kanhetlijst { margin: 0; padding-left: 1.1rem; line-height: 1.55; }
.kanhetlijst li { margin-bottom: var(--r2); }

/* Wat er nog niet klopt hoort niet weggemoffeld en niet uitgeschreeuwd. Een
   linkerstreep in amber is genoeg om te zien dat dit een andere soort lijst is
   dan de vorige. */
.kanhetopen {
  border-left: 3px solid var(--waarschuw);
  padding-left: var(--r4);
}

@media not all and (min-width: 37.5rem) {
  .kanhetkaart { padding: var(--r4) var(--r3); }
  .kanhetcijfers { grid-template-columns: 1fr; gap: 0; }
  .kanhetcijfers dt { margin-top: var(--r2); }
}

/* ------------------------------------------------------------- dashboard */

/* Het startscherm is een dashboard geworden: eerst waar je staat, dan wat je
   nu doet, en pas daarna de lijst om zelf uit te kiezen. Waarom die volgorde,
   en met welke bronnen, staat in web/dashboard.js en in
   rapporten/"Het dashboard als startscherm.md". */

/* De examens naast elkaar. Met twee examens vier dagen uit elkaar is dit het
   eerste wat je wilt weten, en het past op één regel; op een telefoon vallen
   ze onder elkaar omdat een blok van drie woorden niet halveerbaar is. */
.dashexamens {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r2);
  margin-bottom: var(--r4);
}
.dashexamenblok {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  flex: 1 1 12rem;
  padding: var(--r3) var(--r4);
  border-radius: var(--rondklein);
  border: 1px solid var(--randzacht);
  background: var(--kaart);
  border-left: 3px solid var(--zacht);
}
.dashexamenblok b { font-size: .9375rem; }
.dashexamenblok span { font-size: .8125rem; color: var(--zacht); }

/* De drie afstanden. Kleur draagt hier nooit alleen de boodschap: in het blok
   staat altijd "over 2 dagen" of "morgen" in woorden, en de streep links is
   een tweede drager naast de tint. Amber betekent overal in dit platform
   hetzelfde: let op, dit vraagt om actie. */
.dashdringend { border-left-color: var(--waarschuw); }
.dashbinnenkort { border-left-color: var(--accent); }
.dashrustig { border-left-color: var(--randzacht); }

/* De Nu-kaart: één primaire knop, en eronder in gewone taal wat er gebeurt als
   je erop drukt. De wet van Hick zegt dat elke extra gelijkwaardige optie de
   beslistijd verlengt, dus dit is met opzet de enige zware knop op de pagina. */
.dashnu {
  background: var(--kaart);
  border: 1px solid var(--accent);
  border-radius: var(--rond);
  box-shadow: var(--schaduwdik);
  padding: var(--r5);
  margin-bottom: var(--r5);
}
.dashnu h2 { margin: 0 0 var(--r2); font-size: 1.125rem; }
.dashreden { margin: 0 0 var(--r4); line-height: 1.55; }
.dashstart { margin: 0; }
.dashonderknop {
  margin: var(--r3) 0 0;
  font-size: .8125rem;
  color: var(--zacht);
  line-height: 1.5;
}

/* Het dagplan, onder de Nu-kaart. Bewust rustiger dan die kaart: geen dikke
   schaduw en geen accentrand, want de Nu-kaart is waar je op drukt en dit is
   waar je even naar kijkt. Zou dit er net zo hard staan, dan concurreren twee
   blokken om dezelfde aandacht en weet je niet meer waar je moet beginnen. */
.dagplan {
  background: var(--kaart);
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  box-shadow: var(--schaduwklein);
  padding: var(--r4) var(--r5);
  margin-bottom: var(--r5);
}

/* De opdracht van vandaag: de enige zin die je 's ochtends nodig hebt, en dus
   de enige regel hier die op kopformaat staat.

   De h3 in dit platform is verder een klein opschrift in kapitalen boven een
   blok. Dit is geen opschrift maar een hele zin ("Vandaag 53 vragen en 2
   filmpjes"), en die in kapitalen zetten maakt hem juist slechter leesbaar.
   Vandaar dat de kapitalen en de letterafstand hier teruggedraaid worden; het
   blijft wel een h3, want in de opbouw van het scherm is het gewoon de kop van
   dit blok. */
.dagplankop {
  margin: 0 0 var(--r2);
  font-size: 1.0625rem;
  font-weight: 640;
  line-height: 1.4;
  text-transform: none;
  letter-spacing: normal;
}
.dagplanreden {
  margin: 0;
  font-size: .8125rem;
  color: var(--zacht);
  line-height: 1.55;
}

/* Kan de grens niet gehaald worden, dan is de rand geel in plaats van grijs en
   staat het alternatief eronder in een eigen vlak. Geel en niet rood: er is
   niets stuk, er is alleen iets niet haalbaar, en daar hoort een waarschuwing
   bij en geen foutmelding. */
.dagplanklem { border-color: var(--waarschuw); }
.dagplanalternatief {
  margin: var(--r3) 0 0;
  padding: var(--r3);
  border-radius: var(--rondklein);
  background: var(--waarschuwzacht);
  font-size: .8125rem;
  line-height: 1.55;
}

/* De twee lijstjes eronder, met dezelfde opmaak zodat ze als één geheel lezen
   en niet als twee losse mededelingen. */
.dagplanopfris,
.dagplanfilm {
  margin-top: var(--r4);
  padding-top: var(--r3);
  border-top: 1px solid var(--randzacht);
}
.dagplanopfris b,
.dagplanfilm b { font-size: .8125rem; }
.dagplanopfris ul,
.dagplanfilm ul {
  margin: var(--r2) 0 0;
  padding-left: var(--r4);
  font-size: .8125rem;
  color: var(--zacht);
  line-height: 1.6;
}
.dagplanfilm .kleineknop { margin-top: var(--r3); }

.dagplanrust {
  margin: var(--r3) 0 0;
  font-size: .8125rem;
  color: var(--goed);
  line-height: 1.55;
}

/* De keuzelijst is het tweede antwoord geworden en niet meer het eerste. Een
   kop die dat zegt scheelt de vraag of je nu iets moest kiezen of niet. */
.dashkeuzekop {
  margin: 0 0 var(--r3);
  font-size: 1rem;
  font-weight: 620;
  color: var(--zacht);
}

/* Wat er per trajectkaart bij is gekomen: de examendatum, de meter, wat er nu
   aan de beurt is, of je tempo genoeg is, en wat je vandaag gedaan hebt. */
.dashexamen {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  padding-left: var(--r3);
  border-left: 3px solid var(--randzacht);
}
.dashexamen b { font-size: .875rem; }
.dashexamen span { font-size: .8125rem; color: var(--zacht); }

/* De meter volgt het systeem van alle voortgangsbalken in dit platform: baan
   in onbehandeld (nog niet aan de beurt geweest), vulling in de bandkleur van
   dit traject, en groen zodra de grens gehaald is. De getallen staan ernaast,
   want een balk alleen is niet af te lezen. Dikker en ronder dan voorheen,
   zodat voortgang ook echt iets is om te zien. */
.dashmeter { display: flex; align-items: center; gap: var(--r3); }
.dashbaan {
  flex: 1;
  height: .75rem;
  border-radius: 999px;
  background: var(--onbehandeldzacht);
  overflow: hidden;
}
.dashbaan i {
  display: block;
  height: 100%;
  background: var(--bandkleur, var(--accent));
  border-radius: 999px;
}
.dashbaan i.gehaald { background: var(--goed); }
/* Een gehaalde grens ziet er ook echt uit als gehaald: de baan krijgt een
   zachte groene halo in plaats van alleen de vulling zelf te verkleuren, en
   het getal ernaast wordt vetter en groen. :has() is breed genoeg ondersteund
   voor dit platform, dat vrijwel alleen op recente Safari/iOS draait. */
.dashbaan:has(i.gehaald) { box-shadow: 0 0 0 3px var(--goedzacht); }
.dashmeter:has(.gehaald) .dashmetertekst { color: var(--goed); font-weight: 750; }
.dashmetertekst {
  font-size: .8125rem;
  font-weight: 620;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: color 140ms ease-out;
}

.dashonderdeel { font-size: .875rem; }
.dashtijd { font-size: .8125rem; color: var(--zacht); line-height: 1.5; }
.dashvandaag {
  font-size: .8125rem;
  color: var(--zacht);
  font-variant-numeric: tabular-nums;
}

@media not all and (min-width: 37.5rem) {
  .dashnu { padding: var(--r4) var(--r3); }
  .dagplan { padding: var(--r4) var(--r3); }
  .dashexamenblok { flex: 1 1 100%; }
}

/* ------------------------------------------------- wat kan dit traject */

/* De compleetheidscontrole per traject leent de opmaak van "Wat kan dit?",
   want het is dezelfde soort pagina: blokken met een kop, cijfers en lijsten.
   Wat erbij komt is de rij per onderdeel en de twee oordeelzinnen. */

/* Een gat is geen fout maar werk dat nog ligt. Amber, met woorden erbij, net
   als overal elders in dit platform. */
.trajectgat {
  margin: 0 0 var(--r3);
  line-height: 1.55;
  padding-left: var(--r3);
  border-left: 3px solid var(--waarschuw);
}
.trajectgoed {
  margin: 0 0 var(--r3);
  line-height: 1.55;
  padding-left: var(--r3);
  border-left: 3px solid var(--goed);
}

.checkrij {
  display: flex;
  flex-direction: column;
  gap: var(--r1);
  padding: var(--r3) 0;
  border-bottom: 1px solid var(--randzacht);
}
.checkrij:last-child { border-bottom: 0; }
.checkkop { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--r2); }
.checkkop b { font-size: .9375rem; }
.checkgewicht {
  font-size: .75rem;
  color: var(--zacht);
  font-variant-numeric: tabular-nums;
}
.checkcijfers { font-size: .8125rem; color: var(--zacht); font-variant-numeric: tabular-nums; }
.checkgedekt { font-size: .8125rem; color: var(--goed); }
.checkmist { font-size: .8125rem; color: var(--waarschuw); }

/* Het gatenbestand staat er zoals het op schijf staat, dus met de regelafbraak
   die erin zit. Op een telefoon mag het schuiven in plaats van de pagina breed
   te maken. */
.checkgaten {
  margin: 0;
  padding: var(--r3);
  background: var(--achter);
  border-radius: var(--rondklein);
  font-size: .75rem;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* De schakelaar waarmee je de teleprompter stilzet. Hij staat vlak boven de
   tekst, want daar merk je tijdens het opnemen dat het meelopen je stoort. */
.prompterschakelaar {
  display: block;
  width: 100%;
  margin: var(--r3) 0 var(--r2);
  padding: var(--r2) var(--r3);
  min-height: 2.75rem;
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  color: var(--zacht);
  font: inherit;
  font-size: .875rem;
  cursor: pointer;
}
.prompterschakelaar:hover { border-color: var(--accent); color: var(--accent); }
.prompterschakelaar[aria-pressed="true"] { color: var(--tekst); }

/* Staat hij stil, dan mag je zelf scrollen; een randje maakt zichtbaar dat de
   tekst nu van jou is en niet meer van de klok. */
.teleprompter.stilstaand {
  border-left: 3px solid var(--randzacht);
  overscroll-behavior: contain;
}

/* ---------------------------------------------- stof achter een link vandaan

   Twee blokken op het scherm Stof toevoegen: een adres plakken, en de hele
   oogst bij de bronnen van het traject. Ze zien er hetzelfde uit omdat ze
   hetzelfde doen; alleen de omvang verschilt. Zie web/oogsten.js. */

.linkvak {
  margin-top: var(--r5);
  padding-top: var(--r5);
  border-top: 1px solid var(--randzacht);
}
.linkvak h2 { margin-bottom: var(--r2); }

/* Een lijst om uit te kiezen: wat er op een pagina gevonden is, of wat er bij
   de bronnen klaarstaat. Elke rij is een label, zodat je op de hele regel kunt
   drukken en niet alleen op het vakje zelf; op een telefoon scheelt dat. */
.linklijst {
  display: flex;
  flex-direction: column;
  gap: var(--r1);
  margin: var(--r3) 0;
  max-height: 26rem;
  overflow-y: auto;
}
.linkrij {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "vink naam" "vink hint";
  gap: 0 var(--r3);
  align-items: center;
  padding: var(--r2) var(--r3);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  cursor: pointer;
}
.linkrij:hover { border-color: var(--accent); }
.linkrij input { grid-area: vink; width: 1.15rem; height: 1.15rem; }
.linkrij .naam { grid-area: naam; }
/* Het adres eronder mag afgekapt worden: het is er om te herkennen wat je
   aanvinkt, niet om over te typen. Zonder deze regel duwt een lang adres de
   hele rij breder dan het scherm. */
.linkrij .hint {
  grid-area: hint;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.linkrij input:disabled + .naam { color: var(--zacht); }

/* Een voorproefje van de tekst die binnengehaald zou worden. Scrollt in zijn
   eigen vak; anders rekt een lange regel de pagina op. */
.voorproefje {
  max-height: 12rem;
  overflow: auto;
  padding: var(--r3);
  border-radius: var(--rond);
  background: var(--accentzacht);
  font-size: .8125rem;
  white-space: pre-wrap;
}

/* De voortgangsbalk van de oogst. Loopt op het aantal afgeronde stukken en
   niet op de tijd, want een balk die op tijd loopt liegt zodra er een bron
   traag is. */
.oogstbalk {
  height: .5rem;
  margin: var(--r3) 0;
  border-radius: 999px;
  background: var(--randzacht);
  overflow: hidden;
}
.oogstvulling {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width .3s ease;
}

/* De lijst met overgeslagen dubbele stukken. Ingeklapt, want in het gewone
   geval hoef je hem niet te lezen; open als je mist wat je dacht toe te voegen. */
.dubbelenlijst { margin: var(--r3) 0; font-size: .875rem; }
.dubbelenlijst summary { cursor: pointer; color: var(--zacht); }

/* Een stuk theorie dat bij een leerdoel is gezet: leerdoel en paragraafkop op
   een regel, de kernzin eronder. Niet in de gewone onderwerprij, want die zet
   drie dingen naast elkaar en een hele zin past daar op een telefoon niet in;
   hij liep dwars door de titel heen. */
.theorierij {
  padding: var(--r2) var(--r1);
  border-bottom: 1px solid var(--randzacht);
  font-size: .875rem;
}
.theorierij:last-of-type { border-bottom: 0; }
.theorierij .theoriekop {
  display: flex;
  align-items: baseline;
  gap: var(--r2);
  flex-wrap: wrap;
}
.theorierij .code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: .75rem;
  color: var(--zacht);
}
.theorierij .naam { font-weight: 600; }
.theorierij .kernzin {
  margin-top: var(--r1);
  color: var(--zacht);
  font-size: .8125rem;
  line-height: 1.5;
}
.theorierij .kernzin.ontbreekt { color: var(--waarschuw); }

/* ==========================================================================
   Eén vraag op één telefoonscherm

   WAT HIER HET PROBLEEM WAS, GEMETEN

   Op een iPhone van 375 bij 812 punten, met de vaste balken erbij, stond het
   er zo voor:

       kopbalk boven         49 punten, sticky
       tabs (Oefenen/Leren)  75 punten, sticky
       tabbalk onder         55 punten, vast
       ------------------------------------
       wat er overblijft    633 punten

   En wat daarin moest passen:

       onderdeelkop         302 punten (md-102) tot 391 (wiskunde)
       de vraagkaart        615 punten (md-102) tot 1372 (wiskunde)

   Dus zelfs de kortste meerkeuzevraag begon 547 punten onder de bovenrand, en
   de knop Nakijken stond bij een wiskundevraag op 1797. Na het nakijken werd de
   pagina 2773 punten lang en stond de knop Volgende vraag op 2605.

   DE DRIE INGREPEN

   1. De knoppen uit de kaart, naar een vaste balk onderaan. Die telt niet mee
      in de hoogte van de pagina en staat altijd op dezelfde plek. Zo werkt
      Duolingo, en het is de enige indeling waarin antwoorden en doorgaan
      zonder scrollen kan.
   2. De onderdeelkop op een telefoon terug tot één regel. Drie alinea's
      voortgangsproza boven elke vraag is de duurste ruimte op het scherm; de
      rest staat een tik verderop.
   3. Formules in een eigen vakje dat zelf schuift. Zonder dat duwt een brede
      formule de hele pagina scheef en breekt de vaste balk mee.

   De bronnen en de afwegingen staan in rapporten/Een vraag op een telefoon.md.
   ========================================================================== */

/* ------------------------------------------------ de vaste balk onderaan */

.antwoordbalk {
  /* Op een breed scherm is er niets aan de hand: daar past alles, en een balk
     die aan de onderrand plakt zou daar alleen maar in de weg zitten. Hij doet
     dus mee in de gewone stroom en de mediaregel hieronder maakt hem vast. */
  margin-top: var(--r4);
}
.antwoordbalk[hidden] { display: none; }

.uitslagregel {
  margin: 0 0 var(--r2);
  font-size: .9375rem;
  font-weight: 620;
  letter-spacing: -.006em;
}
.antwoordbalk.goed .uitslagregel { color: var(--goed); }
.antwoordbalk.fout .uitslagregel { color: var(--fout); }

@media not all and (min-width: 37.5rem) {
  .antwoordbalk {
    position: fixed;
    left: 0;
    right: 0;
    /* Boven de tabbalk, en boven het toetsenbord zodra dat openstaat.

       --toetsenbord wordt in app.js gemeten met visualViewport. Dat is op iOS
       de enige manier: de layout viewport krimpt daar niet als het toetsenbord
       verschijnt, dus alles wat op bottom: 0 staat valt erachter. Dat is precies
       wat er gebeurde met de knop Nakijken bij een invulvraag: je typte je
       antwoord en de knop om het na te laten kijken zat onder het toetsenbord.

       env(keyboard-inset-height) zou dit netter doen, maar dat bestaat alleen
       in Chromium en niet in WebKit, en dit is een iPhone. */
    bottom: calc(var(--tabbalk-hoog) + env(safe-area-inset-bottom));
    z-index: var(--laag-navigatie);
    margin-top: 0;
    padding: var(--r3);
    padding-bottom: var(--r3);
    background: var(--glas);
    backdrop-filter: var(--glasblur);
    -webkit-backdrop-filter: var(--glasblur);
    box-shadow: 0 -1px 0 var(--randzacht), 0 -14px 14px -14px rgba(20, 30, 50, .18);
  }

  /* Staat het toetsenbord open, dan zit de tabbalk erachter en heeft het geen
     zin om er ruimte voor vrij te houden. De balk gaat dan strak op het
     toetsenbord staan. app.js zet deze klasse; zie volgHetToetsenbord. */
  html.toetsenbordopen .antwoordbalk {
    bottom: var(--toetsenbord, 0px);
  }

  /* Zonder tabbalk (die is er niet op elk scherm) zakt de balk naar de onderrand
     en houdt alleen de veilige zone vrij. */
  body:not(.mettabbalk) .antwoordbalk {
    bottom: env(safe-area-inset-bottom);
  }

  /* De twee knoppen naast elkaar in plaats van onder elkaar. Gemeten scheelt
     dat 57 punten, en "Ik weet het niet" hoeft niet even breed te zijn als
     Nakijken: het is de uitweg, niet de hoofdweg. */
  .antwoordbalk .knoprij { gap: var(--r2); flex-wrap: nowrap; }
  .antwoordbalk .knoprij .hoofdknop { flex: 1 1 auto; }
  .antwoordbalk .kleineknop.breed {
    /* 0 1 in plaats van 0 0: krimpen mag, groeien niet. Gemeten op 320 punten,
       de smalste telefoon die WCAG noemt, staan er na het nakijken twee knoppen
       in deze rij en samen liepen die negen punten over de balk heen; Volgende
       vraag kwam daardoor op drie punten van de schermrand te staan. Met
       krimpruimte past de rij, en de hoofdknop houdt zijn plek omdat hij als
       enige mag groeien. */
    flex: 0 1 auto;
    min-width: 0;
    width: auto;
    /* 2,75rem is 44 punten, het kleinste vlak dat een duim betrouwbaar raakt. */
    min-height: 2.75rem;
  }
  .antwoordbalk .knoprij[hidden] { display: none; }

  /* De pagina moet onder de balk door kunnen scrollen, anders valt het laatste
     stuk van de uitleg er permanent achter. */
  body.mettabbalk main:has(#scherm-oefenen.aan) {
    padding-bottom: calc(var(--r6) + var(--tabbalk-hoog) + var(--antwoordbalk-hoog) + env(safe-area-inset-bottom) + var(--toetsenbord, 0px));
  }
}

/* --------------------------------------------------- de opgave in stukken */

/* De vraag zelf: het enige stuk dat je altijd moet zien. Daarom is dit het
   enige stuk met een rand eromheen. Het is geen kleurtje maar een grens: alles
   erboven is aanloop, dit is wat er gevraagd wordt. */
.devraag {
  border-left: 3px solid var(--accent);
  background: var(--accentzacht);
  border-radius: var(--rondklein);
  padding: var(--r3);
  margin: var(--r3) 0 0;
  font-weight: 560;
}
.devraag p:last-child { margin-bottom: 0; }

/* De gegevens als lijst. In de bron staan de streepjes er nog in; ze zijn
   onderweg op één regel beland. Een echte <ul> is ook wat een schermlezer
   nodig heeft om te melden dat het er drie zijn (WCAG 1.3.1). */
.gegevens {
  background: var(--achter);
  border-radius: var(--rondklein);
  padding: var(--r3);
  margin-bottom: var(--r3);
}
.gegevens p { margin: 0 0 var(--r2); font-size: .9375rem; color: var(--zacht); }
.gegevens ul { margin: 0; padding-left: 1.1rem; }
.gegevens li { margin-bottom: var(--r1); line-height: 1.5; }
.gegevens li:last-child { margin-bottom: 0; }

/* De hele opgave, zoals hij op het examen staat. <details> en geen eigen
   constructie: de browser regelt dan zelf aria-expanded en houdt de inhoud
   werkelijk verborgen in plaats van alleen onzichtbaar. */
.heleopgave { margin-top: var(--r3); }
.heleopgave summary {
  cursor: pointer;
  font-size: .8125rem;
  color: var(--zacht);
  padding: var(--r2) 0;
  /* 44 punten hoog, want dit is een tikdoel. */
  min-height: 2.75rem;
  display: flex;
  align-items: center;
}
.heleopgave summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.heleopgave p { font-size: .9375rem; color: var(--zacht); line-height: 1.6; }

/* De theorie onder "Wat de stof hierover zegt". Dit is naslag terwijl je aan
   het nakijken bent, dus het moet als tekst te lezen zijn en niet als een
   citaat wegvallen: gewone tekstkleur, en de kop erboven zoals hij in de stof
   stond, zodat je hem in je eigen boek terugvindt. */
.theoriestuk {
  margin-top: var(--r3);
  /* Uit de foto's komt tekst zonder lege regels, dus één stuk wordt één lange
     alinea. Een leesbreedte eraan geeft dat weer regels van normale lengte. */
  max-width: 68ch;
}
.theoriestukkop {
  margin: 0 0 var(--r1);
  font-weight: 620;
  font-size: .875rem;
  color: var(--zacht);
}
.theoriestuk p { font-size: .9375rem; line-height: 1.6; }

.theoriemeer { margin-top: var(--r3); }
.theoriemeer summary {
  cursor: pointer;
  font-size: .8125rem;
  color: var(--zacht);
  padding: var(--r2) 0;
  /* 44 punten hoog, want dit is een tikdoel; zie .heleopgave hierboven. */
  min-height: 2.75rem;
  display: flex;
  align-items: center;
}
.theoriemeer summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* De vindplaats zakt naar een bronregel zodra de theorie zelf erboven staat:
   nog steeds na te lopen, maar niet meer het eerste wat je leest. */
.theoriebron {
  margin-top: var(--r3);
  font-size: .75rem;
  color: var(--zacht);
  word-break: break-word;
}

/* Geen theorie is geen lege ruimte: dan staat er wat er niet is. */
.theorieleeg { font-size: .875rem; color: var(--zacht); }

/* Waarom het oefenexamen op de laptop hoort. Eén zin, en hij blokkeert niets. */
.laptopwenk {
  margin: 0 0 var(--r3);
  padding: var(--r3);
  background: var(--accentzacht);
  border-radius: var(--rondklein);
  font-size: .875rem;
  line-height: 1.5;
  color: var(--tekst);
}
/* Op een laptop is de wenk overbodig: daar zit hij al. */
@media (min-width: 37.5rem) { .laptopwenk { display: none; } }

/* ------------------------------------------- de kop boven de vraag inkorten */

@media not all and (min-width: 37.5rem) {
  /* Gemeten was deze kop 302 tot 391 punten hoog: drie alinea's over hoeveel
     procent je staat en hoeveel uur je nog nodig hebt, boven elke vraag
     opnieuw. Dat is de duurste ruimte van het scherm, en het is informatie die
     je één keer per zitting wilt lezen en niet één keer per vraag.

     Alleen de naam van het onderdeel blijft staan. De rest blijft bestaan en
     is met een tik terug te halen; er gaat niets weg. */
  .onderdeelkop { position: relative; }
  .onderdeelkop .stand,
  .onderdeelkop .tijdregel { display: none; }
  .onderdeelkop.uitgeklapt .stand,
  .onderdeelkop.uitgeklapt .tijdregel { display: block; }
  .onderdeelkop b { font-size: 1rem; }
}

/* ------------------------------------------------ formules die te breed zijn */

/* Een formule uit MathML kan breder zijn dan het scherm. Stond er niets, dan
   duwde hij de hele pagina scheef: dan schuift de tekst horizontaal weg en gaat
   de vaste balk onderaan mee.

   html en body staan op overflow-x: clip, dus zichtbaar was het niet, maar het
   deel van de formule dat buiten beeld viel was ook niet meer te bereiken. Nu
   schuift de formule in zijn eigen vakje en blijft de pagina stil.

   overflow-y: hidden hoort erbij: met alleen overflow-x: auto zet de browser er
   ook een verticale schuifbalk bij en wordt een breuk aan de onderkant afgekapt.
   Dat is dezelfde regel die KaTeX zelf voorschrijft. */
.formule {
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  /* In een flexvak groeit een kind standaard nooit kleiner dan zijn inhoud, en
     dan werkt max-width niet en duwt de formule het vak toch open. */
  min-width: 0;
  /* Schuiven met de vinger mag hier horizontaal, en alleen hier. */
  touch-action: pan-x pan-y;
  /* Een strook van een paar punten onder de formule, zodat de schuifbalk op een
     laptop niet over de formule zelf valt. */
  padding-bottom: 1px;
}

/* De knop die de stand en de tijd terughaalt. Alleen op een telefoon: op een
   breed scherm staat de hele kop er gewoon, en dan zet deze knop niets aan. */
.kopmeer { display: none; }
@media not all and (min-width: 37.5rem) {
  .kopmeer {
    display: inline-flex;
    align-items: center;
    margin-top: var(--r2);
    /* 44 punten, want het is een tikdoel. */
    min-height: 2.75rem;
    padding: var(--r1) var(--r3);
    border: 1px solid var(--rand);
    border-radius: var(--rondklein);
    background: var(--kaart);
    color: var(--zacht);
    font: inherit;
    font-size: .8125rem;
    cursor: pointer;
  }
  .kopmeer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
}

/* ============================================================ rekenmachine

   De knop verschijnt alleen bij vragen waar het CvTE om een afgerond
   eindantwoord vraagt; waarom dat zo is staat in web/rekenmachine.js. Hier
   staat alleen hoe hij eruitziet, en dat is met opzet ingetogen: hij is een
   hulpmiddel naast de vraag en niet de hoofdhandeling. Nakijken blijft de
   enige knop met een volle kleur. */

.rekenknop {
  display: block;
  width: 100%;
  margin: 0 0 var(--r3);
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accentzacht);
}
.rekenknop::before { content: "= "; font-weight: 700; }

/* Het blad zelf. Op een telefoon komt het van onderen, net als het
   uitlegpaneel, en blijft de vraag erachter staan: een tik naast het blad is
   genoeg om weer bij de vraag te zijn. */
.rekenpaneel {
  width: min(30rem, calc(100vw - 2rem));
  max-height: min(86dvh, 48rem);
  overflow-y: auto;
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  background: var(--kaart);
  color: var(--tekst);
  box-shadow: var(--schaduwdik);
  padding: var(--r4);
  margin-bottom: env(safe-area-inset-bottom);
}
.rekenpaneel::backdrop { background: rgba(10, 14, 22, .45); backdrop-filter: blur(3px); }

.rekenkop { display: flex; align-items: center; justify-content: space-between; gap: var(--r3); }
.rekenkop h2 { font-size: 1.125rem; letter-spacing: -.018em; margin: 0; }
.rekensluit {
  flex-shrink: 0;
  border: 1px solid var(--rand);
  background: var(--achter);
  color: var(--zacht);
  border-radius: 999px;
  padding: var(--r1) var(--r3);
  font: inherit;
  font-size: .8125rem;
  min-height: 2.25rem;
  cursor: pointer;
}

/* De eerlijke zin. Die staat er klein maar hij staat er, want je moet niet op
   het examen ontdekken dat je een knop mist die je hier nooit gehad hebt. */
.rekeneerlijk {
  margin: var(--r2) 0 var(--r3);
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--zacht);
}

.rekentabs { display: flex; gap: var(--r2); align-items: center; margin-bottom: var(--r3); }
.rekentab {
  flex: 1 1 auto;
  border: 1px solid var(--rand);
  background: var(--achter);
  color: var(--zacht);
  border-radius: var(--rondklein);
  padding: var(--r2) var(--r3);
  font: inherit;
  font-size: .875rem;
  min-height: 2.5rem;
  cursor: pointer;
}
.rekentab.actief { border-color: var(--accent); color: var(--accent); background: var(--accentzacht); font-weight: 600; }
/* rad of graden: een schakelaar, geen tab, dus hij krijgt niet de volle breedte */
.rekenhoek {
  flex: 0 0 auto;
  min-width: 4.5rem;
  border: 1px solid var(--rand);
  background: var(--kaart);
  color: var(--tekst);
  border-radius: 999px;
  padding: var(--r2) var(--r3);
  font: inherit;
  font-size: .8125rem;
  min-height: 2.5rem;
  cursor: pointer;
}
.rekenhoek[aria-pressed="true"] { border-color: var(--waarschuw); color: var(--waarschuw); background: var(--waarschuwzacht); }

/* De band met de vorige sommen. Vaste hoogte, want een band die meegroeit
   duwt het klavier van het scherm af zodra je drie sommen hebt gedaan. */
.rekenband {
  min-height: 4.5rem;
  max-height: 7rem;
  overflow-y: auto;
  padding: var(--r2);
  border-radius: var(--rondklein);
  background: var(--achter);
  margin-bottom: var(--r2);
}
.rekenregel { display: flex; justify-content: space-between; gap: var(--r3); font-size: .8125rem; padding: .125rem 0; }
.rekensom { color: var(--zacht); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rekenuit { font-weight: 600; white-space: nowrap; }

.rekenveld {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  padding: var(--r3);
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  text-align: right;
}
.rekenveld:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.rekenformule { display: flex; align-items: center; gap: var(--r2); margin-bottom: var(--r2); }
.rekenformule > span { font-weight: 600; flex: 0 0 auto; }
.rekenformule .rekenveld { text-align: left; }

.rekenfout { margin: var(--r2) 0 0; font-size: .8125rem; color: var(--fout); }
.rekenwenk { margin: var(--r2) 0 0; font-size: .75rem; color: var(--zacht); }
.rekenaflezing {
  margin: var(--r2) 0;
  font-size: .8125rem;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  color: var(--zacht);
  min-height: 1.25rem;
}

.rekencanvas {
  display: block;
  width: 100%;
  height: 15rem;
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  /* de grafiek verschuift met de vinger, dus de pagina mag dat hier niet doen */
  touch-action: none;
}

/* Het klavier. Vijf kolommen die de breedte delen, zodat het op 375 punten
   past zonder te knijpen, en toetsen van 2,75rem hoog: dat is de maat waarop
   een duim niet mistikt. */
.rekenklavier { margin-top: var(--r3); }
.rekenfuncties { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--r1); margin-bottom: var(--r2); }
.rekenrij { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--r1); margin-bottom: var(--r1); }
.rekentoets {
  min-height: 2.75rem;
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}
.rekentoets.zacht { background: var(--achter); font-size: .8125rem; font-weight: 500; color: var(--zacht); }
.rekentoets:active { transform: scale(.95); background: var(--accentzacht); }
@media (hover: hover) {
  .rekentoets:hover { border-color: var(--accent); color: var(--accent); }
}

.rekenknoprij { display: flex; gap: var(--r2); flex-wrap: wrap; margin-top: var(--r2); }
.rekenknoprij .kleineknop { flex: 1 1 6rem; }
.rekenknoprij.onderaan .hoofdknop { flex: 1 1 8rem; min-height: 2.75rem; }

@media not all and (min-width: 37.5rem) {
  /* van onderen, zoals het uitlegpaneel: het gebaar dat hij al kent */
  .rekenpaneel {
    width: 100%;
    max-width: none;
    max-height: 92dvh;
    margin: auto auto 0;
    border-radius: var(--rond) var(--rond) 0 0;
    padding: var(--r3) var(--r3) calc(var(--r4) + env(safe-area-inset-bottom));
  }
  .rekencanvas { height: 11rem; }
  .rekenband { min-height: 3.25rem; max-height: 5rem; }
  .rekeneerlijk { font-size: .75rem; }
}

/* ---------------- de reis van je stof (web/reis.js)

   De opmaak volgt de vraag die het scherm beantwoordt. De zin bovenaan is het
   antwoord en krijgt daarom het formaat van een antwoord: groter dan de rest,
   in een kaart, zonder iets ernaast dat om aandacht vraagt. De balken eronder
   zijn de onderbouwing en zijn met opzet rustig; ze hebben geen kleur per stap,
   want een kleurcode die je moet leren is geen uitleg.

   De getallen staan rechts van de naam en niet in de balk. In de balk zouden ze
   bij een korte balk buiten de vulling vallen en dan verspringt de leesrichting
   per rij. */
.reiszin p {
  margin: 0;
  font-size: 1.125rem;
  line-height: 1.5;
}

.reisletop {
  border: 1px solid var(--waarschuw);
  background: var(--waarschuwzacht);
  border-radius: var(--rond);
  padding: var(--r3) var(--r4);
  margin: 0 0 var(--r4);
}

/* Het kaartje dat zegt wat er met je stof gebeurt.

   Het staat er altijd, ook als er niets loopt, en daarom heeft het drie
   randkleuren in plaats van één. Rustig als alles klaar is, accent als er iets
   loopt, waarschuwend als het bijwerken niet is afgemaakt. De kleur is hier
   geen versiering maar het verschil tussen "klaar" en "vastgelopen", en dat is
   precies het verschil dat maandenlang niet te zien was. */
.reisketen {
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  padding: var(--r4);
  margin-bottom: var(--r4);
}
.reisketen.bezig { border-color: var(--accent); background: var(--accentzacht); }
.reisketen.mis { border-color: var(--waarschuw); background: var(--waarschuwzacht); }

.reisketenkop {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--r2);
}
.reisketentijd {
  color: var(--zacht);
  font-size: .8125rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.reisketenzin { margin: var(--r2) 0 var(--r3); }
.reisketen .reisbalk { margin-bottom: var(--r3); }
.reisverslag {
  margin: 0 0 var(--r3);
  padding-left: var(--r4);
  font-size: .8125rem;
  color: var(--zacht);
}

/* Wat er binnenkwam: één regel per portie. Een rand per regel en niet één lijst
   met scheidingslijnen, want de porties zijn los van elkaar toegevoegd en de
   vraag gaat steeds over één ervan. */
.reisbinnen { margin-bottom: var(--r5); }
.reisbinnen h2 { font-size: 1rem; margin: 0 0 var(--r3); }
.reisporties { list-style: none; margin: 0 0 var(--r3); padding: 0; }
.reisportie {
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  padding: var(--r3);
  margin-bottom: var(--r2);
}
.reisportiekop {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--r2);
}
.reisportiedatum {
  color: var(--zacht);
  font-size: .8125rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.reisportietel {
  display: block;
  margin-top: var(--r1);
  font-size: .8125rem;
  color: var(--zacht);
  font-variant-numeric: tabular-nums;
}
.reisportie .reisstapwacht { display: block; margin-top: var(--r1); }

/* De regel onder een stap die zegt of het platform er nog mee bezig is. Het
   standwoord staat in een klein vak vooraan, zodat je een kolom standen kunt
   aflezen zonder de zinnen ernaast te lezen. */
.reiswerk {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--r2);
  margin-top: var(--r2);
  font-size: .8125rem;
  color: var(--zacht);
}
.reisstandje {
  border: 1px solid var(--randzacht);
  border-radius: 999px;
  padding: 0 var(--r2);
  font-size: .75rem;
  white-space: nowrap;
}
.reiswerk.bezig .reisstandje { border-color: var(--accent); color: var(--accent); }
.reiswerk.klaar .reisstandje,
.reiswerk.nietsnodig .reisstandje { border-color: var(--goed); color: var(--goed); }
.reiswerk.wacht .reisstandje,
.reiswerk.misgegaan .reisstandje,
.reiswerk.afgebroken .reisstandje {
  border-color: var(--waarschuw);
  color: var(--waarschuw);
}
.reiswerkzin { flex: 1 1 12rem; }
.reiswerktijd { white-space: nowrap; font-variant-numeric: tabular-nums; }
.reiswerkfout {
  flex-basis: 100%;
  margin: var(--r1) 0 0;
  color: var(--waarschuw);
  word-break: break-word;
}

/* De podcastreeks krijgt een eigen balk binnen de stap, want dat is het enige
   werk dat uit zoveel gelijke stukken bestaat dat er iets te meten valt. */
.reisreeks { flex-basis: 100%; margin: var(--r2) 0 0; }
.reisreeksnaam { display: block; margin-bottom: var(--r1); }
.reisreeksregel { display: block; margin-top: var(--r1); font-variant-numeric: tabular-nums; }

.reisstappen { margin-bottom: var(--r5); }
.reisstappen h2, .reistedoen h2, .reisopbrengst h2 {
  font-size: 1rem;
  margin: 0 0 var(--r3);
}

.reisstap { margin-bottom: var(--r4); }
.reisstapkop {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--r2);
  margin-bottom: var(--r2);
}
.reisstapnaam { font-weight: 620; }
.reisstaptel {
  color: var(--zacht);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-size: .875rem;
}

.reisbalk {
  height: .5rem;
  background: var(--rand);
  border-radius: 999px;
  overflow: hidden;
}
.reisbalk i {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width .3s ease;
}
.reisbalk i.af { background: var(--goed); }

/* Bij werk dat loopt is er geen zinnig percentage, dus schuift er een streep
   heen en weer. Een balk op nul procent zou zeggen dat er niets gebeurt. */
.reisbalk.loopt i { width: 35%; animation: reisloop 1.4s ease-in-out infinite; }
@keyframes reisloop {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}
@media (prefers-reduced-motion: reduce) {
  .reisbalk.loopt i { animation: none; width: 100%; opacity: .4; }
  .reisbalk i { transition: none; }
}

.reisstaponder {
  display: flex;
  justify-content: space-between;
  gap: var(--r2);
  margin-top: var(--r2);
  font-size: .8125rem;
  color: var(--zacht);
}
.reisstapwacht { color: var(--waarschuw); white-space: nowrap; }
.reisstap.leeg .reisstapnaam { color: var(--zacht); }

.reislijst { list-style: none; margin: 0; padding: 0; }
.reislijst li {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--r1);
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  padding: var(--r3);
  margin-bottom: var(--r2);
}
.reislijst .uitleg { margin: 0; }
.reislijst .kleineknop { margin-top: var(--r2); }
.reisniets { color: var(--goed); margin: 0; }

.reiscijfers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--r3);
}
.reiscijfer {
  border: 1px solid var(--randzacht);
  border-radius: var(--rond);
  padding: var(--r3);
}
.reiscijfer b { display: block; font-size: 1.375rem; line-height: 1.2; }
.reiscijfer span { font-size: .8125rem; color: var(--zacht); }

/* Op een telefoon van 375 punten past de naam van een stap niet naast zijn
   getal zonder dat een van beide afgeknepen wordt. Dan onder elkaar. */
@media (max-width: 26rem) {
  .reisstapkop, .reisstaponder { flex-direction: column; align-items: flex-start; }
  .reisstaptel, .reisstapwacht { white-space: normal; }
  .reiscijfers { grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); }
  /* Kop en tijd onder elkaar; naast elkaar wordt de titel van een portie op een
     telefoon tot twee woorden afgeknepen en dan weet je niet meer welke stapel
     het was. */
  .reisketenkop, .reisportiekop { flex-direction: column; align-items: flex-start; }
  .reisketentijd, .reisportiedatum { white-space: normal; }
  .reiswerktijd { white-space: normal; }
}

/* --------------------------------- de context in een vak dat zelf schuift */

/* Op een breed scherm is dit een gewoon blok: alles past er toch.
   Op een telefoon krijgt het een dak, zodat de vraag eronder en de knop in de
   balk altijd in beeld blijven terwijl je de context doorleest. */
@media not all and (min-width: 37.5rem) {
  .opgavecontext {
    /* 30svh laat bij 812 punten ongeveer 245 punten context zien: genoeg voor
       drie zinnen tegelijk, en gemeten is dat precies wat de hele vraagkaart
       binnen de leesruimte van 615 punten houdt. Bij 34svh bleef er 17 punten
       over de rand staan, en dan scrol je toch weer.

       svh en niet vh, want vh rekent op een iPhone met de browserbalken
       ingeklapt; dan is het vak hoger dan het scherm op het moment dat die
       balken er wél zijn. */
    max-height: 30svh;
    overflow-y: auto;
    /* De vinger die dit vak leegscrollt hoort daarna de pagina te pakken, niet
       halverwege te blijven hangen. */
    overscroll-behavior-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-right: var(--r2);
    /* Een streep links zegt dat dit bij elkaar hoort en waar het ophoudt. */
    border-left: 2px solid var(--randzacht);
    padding-left: var(--r3);
    margin-bottom: var(--r3);
  }
  /* Dat er meer staat moet te zien zijn zonder te proberen. Een verlopende rand
     onderaan is het rustigste teken daarvoor: hij hoort bij de tekst en vraagt
     geen tik. */
  .opgavecontext {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 1.5rem), transparent 100%);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 1.5rem), transparent 100%);
  }
  /* Wie beweging heeft uitgezet krijgt geen vervaging maar gewoon een rand:
     een aflopende tekst kan lezen lastiger maken. */
  @media (prefers-reduced-motion: reduce) {
    .opgavecontext { -webkit-mask-image: none; mask-image: none; border-bottom: 1px solid var(--randzacht); }
  }
  .opgavecontext > *:last-child { margin-bottom: var(--r4); }
}

/* ======================================================= iconen en beweging

   Toegevoegd op 11 augustus 2026. De afwegingen staan uitgeschreven in
   rapporten/Iconen en beweging.md; hieronder alleen wat je nodig hebt om deze
   regels te begrijpen.

   De iconen komen uit Iconoir (MIT) en worden gemaakt door web/iconen.js. Ze
   staan als echte svg in de pagina en tekenen met currentColor, dus ze volgen
   de tekstkleur van waar ze staan. Dat is de reden dat er geen aparte tekening
   is voor het donkere thema en geen derde voor de contrastmodus.

   Er zijn twee bewegingen, en met opzet niet meer. Een leerplatform waar je een
   uur achter elkaar in zit, is beweging duur: alles wat beweegt trekt de blik
   weg van de vraag waar je mee bezig bent. Deze twee markeren allebei een
   drempel die je maar één keer haalt. Beide luisteren naar "Minder beweging" en
   naar prefers-reduced-motion, en in beide gevallen blijft de boodschap staan;
   alleen de beweging valt weg. */

/* De grondmaat van elk icoon.

   :where() geeft deze regel specificiteit nul. Daardoor wint elke klasse die
   ergens anders in dit bestand iets over een icoon zegt, ongeacht of die regel
   boven of onder deze staat. Zonder :where() zou dit blok, dat achteraan is
   aangeplakt, de maten van .tabicoon hierboven overschrijven, en dan zou de
   tabbalk hier stilzwijgend aan hangen. */
:where(.icoon) {
  width: 1.25em;
  height: 1.25em;
  flex-shrink: 0;
  /* een lijntekening hangt anders dan een letter; dit zet hem op de x-hoogte */
  vertical-align: -.25em;
}

/* ------------------------------------------------ waar de tekens zaten */

/* De keuzeknop bovenaan. Het pijltje was het teken ⌄ in een span, en een span
   is inline: de halve draai die hierboven bij [aria-expanded="true"] staat deed
   daar niets. Een svg is een vervangen element en draait wel, dus die draai
   werkt nu pas echt. */
.menupijl { transition: transform 160ms ease-out; }
@media (prefers-reduced-motion: reduce) { .menupijl { transition: none; } }
.minder-beweging .menupijl { transition: none; }

/* Het vinkje bij het scherm waar je nu op staat. */
.menuvink { color: var(--accent); }

/* De meeneemknop bij de podcast en het kruisje op een melding houden hun icoon
   gecentreerd; ze hadden een letter in het midden en krijgen nu een tekening. */
.bewaarknop, .bewaarmeldingweg {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Het merkje in de antwoordtabel: het icoon en het woord op één regel, rechts
   uitgelijnd zoals de cel al deed. */
table.opties td.merkje {
  /* de cel blijft een tabelcel; de inhoud eromheen doet het uitlijnen */
  vertical-align: middle;
}
/* Krap gehouden, en niet uit zuinigheid. De cel is 5,5rem breed en het langste
   merkje is "juist, gekozen"; dat past er ook zonder icoon al niet in, dus de
   kolom rekt mee en neemt de breedte van de antwoordtekst ernaast af. Gemeten
   in Chrome op 11 augustus 2026: alleen de tekst 100px, met het oude teken ✓
   115px, en met deze maten 119px. Het icoon kost de tekstkolom dus vier pixels
   ten opzichte van wat er stond, en dat is de prijs voor een teken dat overal
   even dik is en met de tekstkleur meekleurt. */
table.opties td.merkje .icoon {
  width: 1rem;
  height: 1rem;
  vertical-align: -.2em;
  margin-right: .1875rem;
}
/* Op een smal scherm verdwijnt het woord (zie de regel hierboven bij
   td.merkje span) en staat de vorm er alleen. Dan hoeft er geen ruimte meer
   naast. Het woord staat nog wel als aria-label op de cel; zie app.js. */
@media not all and (min-width: 37.5rem) {
  table.opties td.merkje .icoon { margin-right: 0; }
}

/* Het beeld bij een scherm waar nog niets staat. Bewust stil: een lege staat
   hoeft geen aandacht te trekken, hij moet zeggen wat er komt te staan. De kop
   eronder doet het werk, dit wijst alleen de plek aan. */
.leegstaaticoon {
  display: block;
  width: 1.75rem;
  height: 1.75rem;
  color: var(--zacht);
  stroke-width: 1.4;
  margin-bottom: var(--r3);
}
/* Een leeg scherm omdat er niets ontbreekt is het tegenovergestelde van een
   leeg scherm omdat er nog niets is. Groen zegt dat verschil, de andere vorm
   zegt het ook, want kleur alleen zou het voor een deel van de lezers niet
   zeggen. */
.gelukticoon { color: var(--goed); }

/* ------------------------------------------------- beweging 1: het dagdoel */

/* De ring bovenaan loopt de hele dag vol. Vol raken is het enige moment dat
   iets betekent, en dat moment duurt een halve seconde.

   Waarom dit aan .netgehaald hangt en niet aan .gehaald: die tweede staat er de
   rest van de dag ook. Een animatie daaraan zou spelen bij elke keer dat de
   balk opnieuw getekend wordt, en dan springt de kop van het scherm de hele
   middag. app.js zet .netgehaald alleen bij de overgang en haalt hem er zelf
   weer af. */
@keyframes dagdoelvol {
  0%   { transform: rotate(-90deg) scale(1); }
  38%  { transform: rotate(-90deg) scale(1.16); }
  100% { transform: rotate(-90deg) scale(1); }
}
.dagdoel.netgehaald svg {
  /* de ring draait al -90 graden zodat hij bovenaan begint; de keyframes
     hierboven nemen die draai mee, anders zou hij tijdens de beweging
     terugklappen naar drie uur */
  animation: dagdoelvol 620ms cubic-bezier(.22, 1, .36, 1);
  transform-origin: 50% 50%;
}

/* Zonder beweging blijft de boodschap volledig staan: de ring is vol, de ring
   en het cijfer zijn groen, en op het scherm na de ronde staat "Dagdoel
   gehaald" in woorden. Er gaat dus niets verloren behalve de beweging zelf. */
@media (prefers-reduced-motion: reduce) {
  .dagdoel.netgehaald svg { animation: none; }
}
.minder-beweging .dagdoel.netgehaald svg { animation: none; }

/* ------------------------------------- beweging 2: een onderwerp op beheerst */

/* Op het scherm na een ronde staat welke onderwerpen zijn opgeschoven. Een
   onderwerp dat op beheerst komt is de enige stap in dit platform die je niet
   terugdraait door een keer te missen; die verdient iets anders dan de stip die
   de andere stappen krijgen.

   De lijn tekent zichzelf, en dat is niet willekeurig gekozen: het tekenen is
   precies wat er gebeurd is. Je hebt het onderwerp in twee vraagvormen goed
   gehad en daarmee de ring rond gemaakt. Eerst de ring, dan het vinkje erin,
   want in die volgorde is het gegaan.

   Er is geen bibliotheek voor nodig. stroke-dasharray maakt van de lijn een
   streepjeslijn met precies één streepje ter lengte van de hele lijn, en
   stroke-dashoffset schuift dat streepje eruit en weer erin. pathLength="1" op
   elk pad (gezet door iconen.js) maakt elke lijn rekenkundig even lang, zodat
   hier 1 kan staan in plaats van een lengte die per pad met javascript
   uitgerekend zou moeten worden. */
@keyframes tekenlijn { to { stroke-dashoffset: 0; } }

.beheerstvink {
  width: 1.125rem;
  height: 1.125rem;
  color: var(--goed);
  stroke-width: 2;
}
.beheerstvink path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: tekenlijn 460ms cubic-bezier(.65, 0, .35, 1) forwards;
}
/* Pad 1 is het vinkje, pad 2 de ring; zie de vorm 'gelukt' in iconen.js. De
   ring begint meteen, het vinkje wacht tot de ring bijna rond is. */
.beheerstvink path:nth-child(1) { animation-delay: 300ms; }

/* Zonder beweging staat het icoon er gewoon, af. De boodschap is het vinkje in
   de ring en de tekst "op weg naar beheerst" ernaast; die staan er allebei nog.
   stroke-dashoffset moet hier terug naar 0, anders blijft de lijn onzichtbaar
   omdat de animatie die hem zou intekenen niet draait. */
@media (prefers-reduced-motion: reduce) {
  .beheerstvink path { animation: none; stroke-dashoffset: 0; }
}
.minder-beweging .beheerstvink path { animation: none; stroke-dashoffset: 0; }

/* ------------------------------------------- de opgave die je zelf nakijkt

   De derde vraagsoort: maken op papier, dan de uitwerking, dan je eigen
   oordeel. Zie web/uitwerkvraag.js voor waarom die vorm bestaat.

   De vorm draagt hier het verschil met de andere twee soorten. Bij meerkeuze en
   bij een invulvraag doe je iets op het scherm; hier doe je het ernaast, en het
   scherm moet dat zeggen zonder dat je het leest. Vandaar het kader met de
   streep ernaast: dit is geen invulveld dat je over het hoofd zag. */

.uitwerkblok {
  margin: 0 0 var(--r4);
  padding: var(--r3) var(--r4);
  background: var(--accentzacht);
  border-radius: var(--rondklein);
  border-left: 3px solid var(--accent);
}
.uitwerkblok[hidden] { display: none; }

/* De bladzijde van het OPGAVENBOEKJE, met de figuur waar de vraag naar
   verwijst. Zie zetOpgaveNeer() in web/uitwerkvraag.js voor waarom hij hier
   staat en niet bij de uitwerking: 24 van de 65 wiskunde-B-vragen noemen een
   figuur, en zonder die figuur is de opgave niet te maken.

   Hij staat bovenaan het blok en krijgt daarom een streep eronder in plaats van
   erboven: alles wat eronder staat gaat over het nakijken, en die grens hoort
   zichtbaar te zijn. */
.opgaveplek {
  margin: 0 0 var(--r3);
  padding-bottom: var(--r3);
  border-bottom: 1px solid var(--rand);
}
.opgaveplek[hidden] { display: none; }

.opgaveplaat {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rondklein);
  background: #fff;
}

.uitwerkopdracht {
  margin: 0;
  font-size: .9375rem;
  line-height: 1.45;
  color: var(--tekst);
}

/* De uitwerking zelf. Elke stap op een eigen regel, want daar geeft het
   correctiemodel punt voor punt punten voor, en stap voor stap is ook hoe je
   hem naast je eigen blad legt. Hij mag zijwaarts schuiven: een integraal met
   grenzen wordt breder dan een telefoon, en dan hoort dát stuk te schuiven en
   niet de hele pagina. */
.uitwerking {
  margin: var(--r3) 0 0;
  padding: var(--r3);
  background: var(--vlak);
  border-radius: var(--rondklein);
  overflow-x: auto;
}
.uitwerking[hidden] { display: none; }

.uitwerkstap {
  margin: 0 0 var(--r2);
  font-size: .9375rem;
  line-height: 1.5;
}
.uitwerkstap:last-child { margin-bottom: 0; }

/* De twee knoppen staan naast elkaar en even zwaar. Dat is met opzet: zodra er
   één de hoofdknop wordt, stuurt de opmaak het antwoord, en het antwoord is
   juist wat we van jou willen weten. */
.uitwerkoordeel {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r2);
  margin-top: var(--r3);
}
.uitwerkoordeel[hidden] { display: none; }
.uitwerkoordeel .hint {
  flex: 1 0 100%;
  margin: 0;
  font-weight: 600;
  color: var(--tekst);
}
.uitwerkoordeel button { flex: 1 1 8rem; }

/* De bladzijde van het correctiemodel. Hij mag de volle breedte pakken en
   schaalt mee; op een telefoon is dat klein, maar knijpen om in te zoomen werkt
   en dat is precies wat je met een bladzijde wil kunnen. */
.uitwerkplaat {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rondklein);
  background: #fff;
}

.uitwerkwenk {
  margin: var(--r2) 0 0;
  font-size: .8125rem;
  line-height: 1.4;
  color: var(--zacht);
}

/* De tekstversie eronder, dichtgeklapt. Zie web/uitwerkvraag.js voor waarom hij
   er nog is nu de bladzijde er staat. */
.uitwerkalstekst { margin-top: var(--r3); }
.uitwerkalstekst summary {
  cursor: pointer;
  font-size: .875rem;
  color: var(--zacht);
}
.uitwerkalstekst .hint { margin: var(--r2) 0; font-size: .8125rem; }

/* ------------------------------------------------------------------------
   De puntenverdeling van het correctiemodel (eis G4). Zie puntenblok() in
   web/uitwerkvraag.js voor waarom hij er staat en waarom er ook iets staat als
   hij ontbreekt.

   Waarom het puntenaantal links staat en niet achter de omschrijving: de
   omschrijvingen komen uit een pdf en lopen ongelijk in lengte. Achteraan gezet
   staan de getallen dan overal op een andere plek en moet je ze stuk voor stuk
   opzoeken, terwijl je ze juist naast elkaar wil kunnen leggen: dit was er twee
   en dat was er één. Vooraan vormen ze één kolom en lees je de verdeling in één
   blik af. */
.puntenverdeling {
  margin: var(--r3) 0 0;
  padding-top: var(--r3);
  border-top: 1px solid var(--rand);
}

.puntenkop {
  margin: 0 0 var(--r2);
  font-size: .875rem;
  font-weight: 600;
  color: var(--tekst);
}

.puntenlijst {
  margin: 0;
  padding: 0;
  list-style: none;
}

.puntenstap {
  display: flex;
  gap: var(--r2);
  align-items: baseline;
  margin: 0 0 var(--r2);
}
.puntenstap:last-child { margin-bottom: 0; }

/* Vaste breedte, zodat de omschrijvingen eronder op één lijn beginnen ook als
   "1 punt" smaller is dan "3 punten". */
.puntenwaarde {
  flex: 0 0 4.5rem;
  font-size: .8125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.puntenomschrijving {
  flex: 1 1 auto;
  min-width: 0;
  font-size: .9375rem;
  line-height: 1.5;
  color: var(--tekst);
}

/* De zin voor een opgave zonder puntenverdeling. Bewust niet in het grijs van
   een terzijde: dit is geen voetnoot maar het antwoord op de vraag "waar zaten
   de punten" — namelijk dat dat hier niet bekend is. */
.puntenstand {
  margin: var(--r3) 0 0;
  padding-top: var(--r3);
  border-top: 1px solid var(--rand);
  font-size: .875rem;
  line-height: 1.5;
  color: var(--tekst);
}

/* Onder de uitleg staat hij in een blok dat zijn eigen streep al heeft. */
#waaromblok > .puntenverdeling,
#waaromblok > .puntenstand { margin-top: var(--r4); }

/* ------------------------------------------------------------------------
   De figuren bij de theorie-uitleg. Zie web/figuren.js voor welke figuur welk
   misverstand adresseert; hieronder staat alleen hoe ze eruitzien.

   Waarom de kleuren hier staan en niet in het javascript: dit is de plek waar
   het lichte thema, het donkere thema en de contrastmodus al bij elkaar
   staan. Een figuur die zijn kleur zelf meebrengt zou in minstens één van de
   drie fout staan, en dat merk je pas als iemand 's avonds zit te leren.

   Er beweegt niets in een figuur, dus er is ook geen regel voor
   prefers-reduced-motion nodig; zie de kop van figuren.js.
   ------------------------------------------------------------------------ */

/* Het vel. width 100% met height auto en een viewBox betekent: hij past altijd
   in de kolom waar hij in staat, ook op 375 punten breed, en de pagina schuift
   niet zijwaarts. De maximale breedte houdt hem op een breed scherm leesbaar:
   een tekenschema van 900 punten breed is geen tekenschema meer maar een
   spandoek. */
.figuur {
  display: block;
  width: 100%;
  height: auto;
  max-width: 26rem;
  margin: var(--r4) 0;
  overflow: visible;
}

/* Assen, getallenlijnen en kaders: aanwezig, maar ze mogen de kromme niet
   beconcurreren. Vandaar de zachte kleur en de dunne lijn. */
.figuur-lijn {
  fill: none;
  stroke: var(--zacht);
  stroke-width: 1.2;
  stroke-linecap: round;
}

.figuur-kader {
  fill: none;
  stroke: var(--veldrand);
  stroke-width: 1;
}

/* De kromme zelf is waar je naar kijkt, dus die krijgt het accent en de
   dikste lijn van de tekening. */
.figuur-kromme {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Stippellijnen leggen een verband (een nul hoort bij dít punt, de wissel zit
   op déze x). Ze zijn geen begrenzing, dus ze zijn dun en zacht. */
.figuur-stippel {
  fill: none;
  stroke: var(--zacht);
  stroke-width: 1.2;
  stroke-dasharray: 4 4;
}

/* De verticale randen van een interval: wel een begrenzing, dus doorgetrokken,
   maar in de zachte kleur omdat ze niet de grafiek zijn. */
.figuur-rand {
  fill: none;
  stroke: var(--zacht);
  stroke-width: 1.4;
}

.figuur-punt {
  fill: var(--tekst);
  stroke: none;
}

/* De nul in een tekenschema: een open rondje, zoals je het op papier zet. Het
   vult met de kaartkleur zodat de lijn eronder niet doorschijnt. */
.figuur-open {
  fill: var(--kaart);
  stroke: var(--tekst);
  stroke-width: 1.4;
}

/* De ∩ en ∪ naast de woorden bol en hol. Een vorm naast het woord, want kleur
   mag nergens de enige drager zijn. */
.figuur-vorm {
  fill: none;
  stroke: var(--tekst);
  stroke-width: 1.6;
  stroke-linecap: round;
}

/* Het ingekleurde vlakdeel. De vulling komt uit een arceringspatroon en niet
   uit een kleur alleen: valt de kleur weg, dan blijven de streepjes over en is
   het nog steeds een vlak. */
.figuur-vlak { stroke: none; }
.figuur-vulling { fill: var(--accentzacht); }
.figuur-arcering {
  fill: none;
  stroke: var(--accent);
  stroke-width: .8;
  opacity: .45;
}

/* Labels. 12 punten is op een telefoon ongeveer wat het op het scherm ook
   wordt, want een figuur van 340 eenheden staat daar bijna op ware grootte.
   Kleiner kan niet: dan is "geen top" naast een stippellijn niet meer te
   lezen op de plek waar het juist uitmaakt. */
.figuur text {
  font-family: inherit;
  fill: var(--tekst);
  font-size: 12px;
}
/* Let op de dubbele klasse: `.figuur text` hierboven weegt zwaarder dan een
   losse klasse, dus zonder de .figuur ervoor zou die regel deze twee
   overstemmen en werd alles alsnog 12 punten in de tekstkleur. */
.figuur .figuur-klein { font-size: 11px; fill: var(--zacht); }
/* De + en de − van het tekenschema. Zwaarder dan de rest, want dit zijn de
   twee tekens waar de hele figuur om draait, en op een klein scherm is een
   dunne min nauwelijks van een streepje te onderscheiden. */
.figuur .figuur-teken { font-size: 15px; font-weight: 600; fill: var(--tekst); }

/* ============================================================ foutpatronen.js
   De voortgangstabel per hernieuwde poging (SPEC-THEORIEMODULE.md sectie 8) en
   de melding die valt als foutpatronen.js een import mist.

   De tabel scrollt zelf zodra hij niet past, in plaats van de pagina breed te
   maken. Op een telefoon zijn dat vijf kolommen naast elkaar, en de kolom die
   je dan als eerste kwijtraakt is "wat er veranderde" — precies de kolom die
   het verschil verklaart. Liever binnen de tabel schuiven dan hem verliezen. */
.pogingtabel {
  width: 100%;
  border-collapse: collapse;
  font-size: .9375rem;
  display: block;
  overflow-x: auto;
}
.pogingtabel caption {
  caption-side: top;
  text-align: left;
  font-weight: 600;
  padding-bottom: .5rem;
}
.pogingtabel th,
.pogingtabel td {
  padding: .375rem .625rem;
  border-bottom: 1px solid var(--randzacht);
  text-align: left;
  white-space: nowrap;
}
.pogingtabel thead th {
  font-size: .8125rem;
  color: var(--zacht);
  font-weight: 600;
}
/* Getallen onder elkaar uitlijnen: 8/19 boven 12/19 hoort op dezelfde plek te
   beginnen, anders moet je twee keer kijken om te zien welk getal groter is. */
.pogingtabel .punten,
.pogingtabel .verschil {
  font-variant-numeric: tabular-nums;
}
.pogingtabel .verschil.omhoog { color: var(--goed); font-weight: 600; }
.pogingtabel .verschil.omlaag { color: var(--fout); font-weight: 600; }
.pogingtabel tbody tr.omhoog { background: var(--goedzacht); }
.pogingtabel tbody tr.omlaag { background: var(--foutzacht); }
.pogingtabel .patronen { white-space: normal; color: var(--zacht); }
.pogingtabel tfoot .pogingtotaal th,
.pogingtabel tfoot .pogingtotaal td {
  font-weight: 600;
  border-top: 2px solid var(--rand);
  border-bottom: none;
}
/* De diagnose staat in de tabel en niet ernaast; zie pogingtabel() voor waarom.
   Hij mag dus wél afbreken over meerdere regels, want het is een zin. */
.pogingtabel .pogingdiagnose td {
  white-space: normal;
  padding-top: .625rem;
  border-bottom: none;
  color: var(--tekst);
}
.pogingtabel .pogingdiagnose.rekendiscipline td { background: var(--waarschuwzacht); }
.pogingtabel .pogingdiagnose.eenreparatie td { background: var(--goedzacht); }
.pogingtabel .pogingdiagnose.terugval td,
.pogingtabel .pogingdiagnose.begrip td { background: var(--foutzacht); }
.pogingtabel .drillsetwijzer,
.pogingtabel .uitlegwijzer { font-weight: 600; }

/* Een module die een import mist laat normaal een wit scherm achter. Deze balk
   staat er dan bovenaan, en hij hoort op te vallen. */
.modulefout {
  margin: 0;
  padding: .75rem 1rem;
  background: var(--fout);
  color: #fff;
  font-weight: 600;
}

/* Op een telefoon mag de bladzijde buiten het blok steken.

   Waarom dat de moeite is. De uitsnede van het correctiemodel is 467 punten
   breed en krijgt op een scherm van 375 punten maar 266 punten: de rest gaat op
   aan de vulling van de kaart en van het uitwerkblok eromheen. Dat is 0,57
   schermpunt per bronpunt, en 11-punts tekst komt dan op ongeveer 6 punten uit.
   Leesbaar, maar net niet.

   Die 109 punten vulling doen hier niets nuttigs. Om tekst heen is witruimte wat
   een alinea leesbaar maakt; om een afbeelding heen is het alleen maar minder
   afbeelding. De plaat loopt daarom op smalle schermen tot aan de rand van het
   blok door, en dat scheelt een factor 1,33: samen met het uitsnijden is de
   tekst 1,7 keer zo groot als op de hele bladzijde van vanmiddag.

   Alleen onder de grens waar het knelt. Op een breed scherm past hij ruim en is
   een plaat die tegen de rand aan ligt juist rommelig. */
@media not all and (min-width: 37.5rem) {
  .uitwerking {
    padding-left: 0;
    padding-right: 0;
  }
  .uitwerkplaat,
  .opgaveplaat {
    /* de vulling van het uitwerkblok terugnemen: --r4 aan weerskanten */
    width: calc(100% + 2 * var(--r4));
    margin-left: calc(-1 * var(--r4));
    max-width: none;
  }
  /* De wenk eronder houdt zijn vulling wel: dat blijft leestekst. */
  .opgaveplek .uitwerkwenk {
    padding-left: var(--r3);
    padding-right: var(--r3);
  }
  /* De tekst eromheen houdt zijn vulling wel: dat blijft leestekst. */
  .uitwerking .uitwerkstap,
  .uitwerking .uitwerkwenk,
  .uitwerking .uitwerkalstekst,
  .uitwerking .puntenverdeling,
  .uitwerking .puntenstand {
    padding-left: var(--r3);
    padding-right: var(--r3);
  }
}

/* ============================================================ driebloksformaat

   Het formaat uit SPEC-THEORIEMODULE.md sectie 3, zoals web/driebloks.js het
   neerzet. Drie blokken in een vaste volgorde, en die volgorde is functioneel:
   Robert legt zijn papier ernaast en schrijft de correctie er met rode pen bij.

   Waarom de blokken genummerd én gekleurd zijn en niet alleen genummerd. Ze
   worden overgeschreven, niet gelezen, en dat gebeurt met het scherm naast het
   papier. Wie zijn blik heen en weer beweegt raakt zijn plek kwijt in een
   kolom van gelijkvormige alinea's; een linkerrand in kleur is de enige
   markering die je vanuit een ooghoek terugvindt. */

#driebloksblok { margin: var(--r5) 0; }

.drieblok {
  border-left: 3px solid var(--rand);
  padding: var(--r2) 0 var(--r2) var(--r4);
  margin: var(--r4) 0;
}
.drieblok h4 { margin: 0 0 var(--r2); font-size: 1rem; }
.drieblok .drieblokregel { margin: 0 0 var(--r2); }
.drieblok .drieblokregel:last-child { margin-bottom: 0; }

/* Blok 1 is het correctiemodel: hier hoort het naartoe. Blok 2 is jouw fout.
   Blok 3 is de theorie, en die is neutraal — hij gaat niet over deze opgave. */
#driebloksblok .drieblok:nth-of-type(1) { border-left-color: var(--goed); }
#driebloksblok .drieblok:nth-of-type(2) { border-left-color: var(--fout); }
#driebloksblok .drieblok:nth-of-type(3) { border-left-color: var(--accent); }

/* Blok 2 zonder invoer. Bij een meerkeuzevraag is er geen uitwerking om een
   regel in aan te wijzen, en dan staat er wat er ontbreekt en waarom. Dat is
   een mededeling en geen fout van jou, dus krijgt het de kleur van een wenk en
   niet die van een fout: rood zou zeggen dat je iets verkeerd deed. */
#driebloksblok .drieblok.zonderinvoer { border-left-color: var(--waarschuw); }
#driebloksblok .drieblok.zonderinvoer .drieblokregel { color: var(--zacht); }

.driebloksfiguur { margin: var(--r3) 0 0; }
.driebloksfiguur svg { max-width: 100%; height: auto; display: block; }

.driebloksepunten {
  margin: var(--r4) 0 0;
  padding: var(--r3);
  background: var(--vlak);
  border-radius: var(--rondklein);
}

.driebloksnaslag { margin: var(--r2) 0 0; padding-left: var(--r5); }
.driebloksnaslag li { margin-bottom: var(--r2); }
.driebloksnaslag .hint { display: block; }

/* Wat er staat als de render faalt.

   De spec zegt het in zijn eerste alinea: als een blok ontbreekt moet de render
   falen in plaats van degraderen. Dit kader is die val, zichtbaar gemaakt. Het
   krijgt de waarschuwkleur en niet de foutkleur, want er is niets mis met het
   werk van de gebruiker — er ontbreekt stof in het traject. */
.drieblokgezakt {
  border: 1px solid var(--waarschuw);
  border-radius: var(--rondklein);
  background: var(--waarschuwzacht);
  padding: var(--r4);
}
.drieblokgezakt h4 { margin: 0 0 var(--r2); font-size: 1rem; }
.drieblokgezaktlijst { margin: var(--r2) 0; padding-left: var(--r5); }
.drieblokgezaktlijst li { margin-bottom: var(--r1); }

/* Het overtypveld, in de vraagkaart. */
#eigenwerkblok { margin-top: var(--r4); }
#eigenwerkblok h3 { margin: 0 0 var(--r2); }
#eigenwerkblok textarea {
  width: 100%;
  padding: var(--r3);
  border: 1px solid var(--veldrand);
  border-radius: var(--rondklein);
  background: var(--achter);
  color: var(--tekst);
  /* Vaste breedte, want er staat wiskunde in die op papier onder elkaar
     uitgelijnd staat. In een proportioneel lettertype schuiven de = en de
     coëfficiënten per regel op, en dan is de kolom die je overtypt niet meer
     de kolom die je ziet. */
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .9375rem;
  line-height: 1.5;
  resize: vertical;
  box-sizing: border-box;
}
#eigenwerkblok textarea:focus {
  outline: 2px solid var(--ring);
  outline-offset: 1px;
  border-color: var(--ring);
  box-shadow: 0 0 0 4px var(--ringzacht);
}
.eigenwerkknoppen {
  display: flex; gap: var(--r2); flex-wrap: wrap; margin-top: var(--r2);
}

/* Op een smal scherm mag niets zijwaarts schuiven.

   Gemeten op 375 bij 812: de blokken bevatten regels uit een correctiemodel die
   uit een pdf komen, en daar zit geen enkele spatie in een breuk of een
   integraalgrens. Zo'n regel is één woord van tachtig tekens breed, en één zo'n
   regel duwt de hele bladzijde opzij. Breken op elk teken is voor gewone tekst
   lelijk; hier is het het enige wat werkt, want er valt niets af te korten
   zonder de stap onleesbaar te maken. */
.drieblok .drieblokregel,
.driebloksnaslag li,
.drieblokgezaktlijst li {
  overflow-wrap: anywhere;
  word-break: break-word;
}

@media not all and (min-width: 37.5rem) {
  .drieblok { padding-left: var(--r3); }
  .driebloksnaslag { padding-left: var(--r4); }
  .eigenwerkknoppen .kleineknop { flex: 1 1 100%; }
}

/* ============================================================= de voordeur

   Het inlogscherm ligt als een laag óver de app heen (web/thuis.js). Dat is
   met opzet geen eigen pagina: de terugkeer van Google komt op dit adres uit,
   en een aparte pagina zou betekenen dat de app twee keer laadt voor één keer
   binnenkomen.

   Zolang de laag er ligt staat de app eronder stil: `voordeur` op de body
   houdt het scrollen tegen, want scrollen achter een deur die dicht is voelt
   als een fout. */

body.voordeur { overflow: hidden; }

.thuis {
  position: fixed;
  inset: 0;
  z-index: var(--laag-deur);
  display: grid;
  place-items: center;
  padding: var(--r4);
  background: var(--achter);
  overflow-y: auto;
}

.thuisblad {
  width: min(26rem, 100%);
  background: var(--kaart);
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  box-shadow: var(--schaduwdik);
  padding: var(--r6, 2rem) var(--r5);
}

.thuisblad h1 { margin: 0 0 var(--r2); font-size: 1.375rem; letter-spacing: -.02em; }
.thuisuitleg { margin: 0 0 var(--r5); color: var(--zacht); font-size: .9375rem; line-height: 1.6; }

/* De Google-knop draagt het merk van Google en niet dat van dit platform: een
   herkenbare knop wordt sneller vertrouwd dan een mooiere. */
.thuisgoogle {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: var(--r2);
  padding: var(--r3);
  border: 1px solid var(--veldrand, var(--rand));
  border-radius: var(--rondklein, var(--rond));
  background: #fff;
  color: #1f1f1f;
  font: inherit;
  font-weight: 500;
  cursor: pointer;
}
.thuisgoogle:hover { background: #f7f8f8; }

/* "of met je e-mailadres", met een streep aan weerszijden. Twee manieren naast
   elkaar horen ook naast elkaar te staan; een lijstje onder elkaar suggereert
   een volgorde die er niet is. */
.thuisof {
  display: flex;
  align-items: center;
  gap: var(--r2);
  margin: var(--r4) 0;
  color: var(--zacht);
  font-size: .8125rem;
}
.thuisof::before, .thuisof::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--randzacht, var(--rand));
}

.thuisformulier { display: grid; gap: var(--r3); }
.thuisformulier label { display: grid; gap: var(--r1); font-size: .8125rem; color: var(--zacht); }
.thuisformulier input {
  padding: var(--r3);
  border: 1px solid var(--veldrand, var(--rand));
  border-radius: var(--rondklein, var(--rond));
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
}

.thuisknop {
  padding: var(--r3);
  border: 0;
  border-radius: var(--rondklein, var(--rond));
  background: var(--accent);
  color: var(--opaccent, #fff);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.thuisknop[disabled] { opacity: .6; cursor: default; }

.thuismelding {
  margin: var(--r3) 0 0;
  padding: var(--r3);
  border-radius: var(--rondklein, var(--rond));
  background: var(--foutzacht);
  color: var(--tekst);
  font-size: .875rem;
  line-height: 1.5;
}

.thuiswissel { display: flex; flex-wrap: wrap; gap: var(--r3); margin-top: var(--r4); }
.thuislink {
  border: 0;
  padding: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  font-size: .875rem;
  cursor: pointer;
  text-decoration: underline;
}

.thuisklein {
  margin: var(--r5) 0 0;
  color: var(--zacht);
  font-size: .8125rem;
  line-height: 1.6;
}

/* "Download voor Mac" onder aan de voordeur (web/macdownload.js, compact). */
.thuismac { margin-top: var(--r5); padding-top: var(--r4); border-top: 1px solid var(--rand); }
.thuismac .thuisklein { margin-top: 0; }
.thuismac .thuisknop { display: block; margin-top: var(--r3); text-align: center; text-decoration: none; }
.thuismac details { margin-top: var(--r3); }
.thuismac summary { cursor: pointer; color: var(--accent); }
.thuismac ol { margin: var(--r2) 0 0; padding-left: 1.25rem; }

/* ================================================================ account

   Eén scherm met blokken (web/account.js). De blokken staan los van elkaar
   zodat je met scrollen vindt wat je zoekt zonder te lezen wat je niet zoekt. */

.accountblok {
  background: var(--kaart);
  border: 1px solid var(--rand);
  border-radius: var(--rond);
  box-shadow: var(--schaduwklein, var(--schaduw));
  padding: var(--r5);
  margin-bottom: var(--r4);
}
.accountblok h2 { margin: 0 0 var(--r3); font-size: 1.0625rem; letter-spacing: -.013em; }

.accountkop { display: flex; align-items: center; gap: var(--r3); margin-bottom: var(--r4); }
.accountnaast { display: grid; gap: 2px; min-width: 0; }
.accountnaast strong { font-size: 1.0625rem; }
.accountmail { color: var(--zacht); font-size: .875rem; overflow-wrap: anywhere; }

.accountportret {
  width: 3rem;
  height: 3rem;
  flex: 0 0 auto;
  border-radius: 50%;
  object-fit: cover;
  background: var(--accentzacht);
}
.accountportret.leeg {
  display: grid;
  place-items: center;
  color: var(--accent);
  font-weight: 600;
  font-size: 1.25rem;
}

.accountformulier { display: grid; gap: var(--r2); justify-items: start; margin-bottom: var(--r3); }
.accountformulier label { display: grid; gap: var(--r1); width: min(22rem, 100%); font-size: .8125rem; color: var(--zacht); }
.accountformulier input {
  padding: var(--r2) var(--r3);
  border: 1px solid var(--veldrand, var(--rand));
  border-radius: var(--rondklein, var(--rond));
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
}
.accountmelding { margin: 0; color: var(--zacht); font-size: .875rem; }
.accountklein { margin: var(--r2) 0 0; color: var(--zacht); font-size: .8125rem; line-height: 1.6; }

/* De lange teksten — privacy, cookies, voorwaarden — staan in uitklappers.
   Wie hier komt om uit te loggen hoeft niet eerst langs drie pagina's tekst. */
.accountuitklap { border-top: 1px solid var(--randzacht, var(--rand)); padding: var(--r3) 0; }
.accountuitklap:first-of-type { border-top: 0; }
.accountuitklap summary { cursor: pointer; font-weight: 500; }
.accountuitklap p { margin: var(--r3) 0 0; color: var(--zacht); font-size: .9375rem; line-height: 1.65; }
.accountlijst { margin: var(--r3) 0 0; padding-left: 1.1rem; color: var(--zacht); font-size: .9375rem; line-height: 1.65; }
.accountlijst li { margin-bottom: var(--r2); }

/* ------------------------------------------------ schermbeelden bij een onderwerp

   Waar staat dit in het programma. Het beeld komt uit de documentatie van de
   maker en is meestal een brede schermafdruk van een portaal; op een telefoon
   van 375 punten is dat onleesbaar klein. Daarom mag het breder zijn dan de
   kolom en zelf horizontaal schuiven, in plaats van tot postzegelformaat te
   krimpen. Wie het van dichtbij wil zien tikt erop en krijgt het op ware
   grootte. Dezelfde afweging als bij de uitwerkplaat; zie
   platform/uitwerkplaat.py voor waarom verkleinen daar niet werkte. */
.beeldkader {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--rand);
  border-radius: var(--r3);
  background: var(--vlak);
}

.beeldkader img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* Op een smal scherm blijft de schermafdruk op ware breedte staan en schuift
   het kader; anders is er niets te lezen en is het beeld er voor niets. */
@media not all and (min-width: 37.5rem) {
  .beeldkader img { max-width: none; min-width: 100%; }
}

/* Het klikpad: waar je moet zijn, in de woorden van het programma zelf. Het
   staat boven het beeld, want je gebruikt het in die volgorde. */
.beeldklikpad {
  margin: 0 0 var(--r3);
  font-size: .9375rem;
  font-weight: 600;
  word-break: break-word;
}

.beeldprogramma { color: var(--zacht); font-weight: 400; }

.beeldbijschrift { margin: var(--r3) 0 0; font-size: .875rem; }

/* De bronregel is een voorwaarde van de licentie en hoort er dus altijd bij,
   maar hij hoeft niet te schreeuwen. Zelfde maat als de vindplaats bij de
   theorie. */
.beeldbron {
  margin-top: var(--r3);
  font-size: .75rem;
  color: var(--zacht);
  word-break: break-word;
}

/* Het keurscherm: één kandidaat tegelijk, met het onderwerp erboven. */
.beeldkaart {
  border: 1px solid var(--rand);
  border-radius: var(--r4);
  padding: var(--r4);
  background: var(--kaart);
}

.beeldonderwerp { margin: 0 0 var(--r2); font-size: 1.0625rem; font-weight: 600; }

/* Een kaart die een link is, stapelt zijn naam en zijn uitleg onder elkaar.
   Zonder dit lopen ze in elkaar over ("Photo CommunityFoto's, albums en...")
   omdat een <a> zijn kinderen naast elkaar zet. */
.kaarten a.kaart { display: grid; gap: var(--r1); color: inherit; text-decoration: none; }
.kaarten a.kaart strong { font-size: 1rem; }
.kaarten a.kaart span { color: var(--zacht); font-size: .875rem; }
.kaarten a.kaart:hover { border-color: var(--accent); }

/* Op het keurscherm is het beeld niet de inhoud maar het bewijsstuk: je kijkt
   ernaar om ja of nee te zeggen. Een schermafdruk van 1400 bij 1100 duwt die
   twee knoppen dan een scherm naar beneden, en dan is elk oordeel twee keer
   scrollen. Vandaar een hoogtegrens en knoppen die blijven staan. */
.beeldkaart .beeldkader img { max-height: 60vh; width: auto; }

#beeldkeurknoppen {
  position: sticky;
  bottom: 0;
  padding: var(--r3) 0;
  background: var(--achter);
}

/* De vriendcode: zes tekens die je overtypt of doorbelt, dus groot genoeg om
   voor te lezen en met ruimte tussen de tekens. Een vaste breedte per teken
   (tabular-nums) voorkomt dat de code danst als er een 1 in zit. */
.vriendcode {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 1.75rem;
  letter-spacing: .22em;
  font-variant-numeric: tabular-nums;
  margin: var(--r2) 0 var(--r3);
  padding: var(--r3) var(--r4);
  background: var(--accentzacht);
  color: var(--accent);
  border-radius: var(--rondklein, var(--rond));
  display: inline-block;
  user-select: all;
}

/* =====================================================================
   HOTSPOT en DRAG DROP: de twee examenvormen waarbij elke regel een punt is

   Ze staan hier bij elkaar, want ze delen hun bouwstenen: een aanraakbaar vlak
   met een rand, dat kleurt zodra het gekozen is. Wat ze niet delen is de
   handeling; zie web/rijenvraag.js en web/sleepvraag.js.

   OVERAL MINSTENS 44 PUNTEN HOOG

   Dat is de ondergrens van Apple en van Material voor iets wat je met een duim
   raakt, en het is hier geen luxe. Bij een hotspot staan Yes en No naast elkaar
   en bij een DRAG DROP staan er soms zes blokken onder elkaar; wordt een van die
   doelen te klein, dan tik je naast het antwoord en telt de vraag als fout
   terwijl je het wist. Dat is precies de fout die deze twee vormen moeten
   voorkomen: punten verliezen aan de vorm in plaats van aan de stof. */

.rijenblok { margin: var(--r3) 0 var(--r2); }
.rijenblok[hidden], .sleepblok[hidden] { display: none; }

/* Eén regel met zijn keuzes. Naast elkaar zolang het past, en onder elkaar
   zodra het niet meer past. Op 375 punten breed is dat altijd: een stelling van
   twee regels tekst met Yes en No ernaast laat voor allebei ongeveer zestig
   punten over, en dan is de knop smaller dan de vinger. */
.rijvraag {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r2) var(--r3);
  align-items: center;
  justify-content: space-between;
  padding: var(--r3) 0;
  border-bottom: 1px solid var(--randzacht);
}
.rijvraag:last-child { border-bottom: 0; }
.rijtekst { flex: 1 1 16rem; line-height: 1.45; }

.rijkeuzes { display: flex; flex-wrap: wrap; gap: var(--r2); }
.rijkeuze {
  min-height: 44px;
  padding: var(--r2) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  cursor: pointer;
}
.rijkeuze:hover { background: var(--accentzacht); }
/* Gekozen draagt drie dingen tegelijk: de vulling, de rand en de tekstkleur.
   Kleur alleen zou te weinig zijn — in de zon en zonder kleurenzicht blijft de
   dikkere rand over, en dat is dezelfde afspraak als bij de antwoordtabel. */
.rijkeuze.gekozen {
  background: var(--accentzacht);
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--accent);
  font-weight: 620;
}
.rijkeuze:focus-visible, .sleepblokje:focus-visible, .sleepplek:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.rijlijst {
  min-height: 44px;
  padding: var(--r2) var(--r3);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  max-width: 100%;
}

/* ------------------------------------------------------------- de sleepvorm */

.sleepblok { margin: var(--r3) 0 var(--r2); }
.sleepwenk { margin: 0 0 var(--r3); color: var(--zacht); font-size: .9375rem; }
.sleepmelding {
  margin: var(--r2) 0;
  min-height: 1.25rem;
  color: var(--accent);
  font-size: .9375rem;
}

.sleepvoorraad {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r2);
  padding: var(--r3);
  background: var(--achter);
  border-radius: var(--rondklein);
}

.sleepblokje {
  min-height: 44px;
  padding: var(--r2) var(--r4);
  border: 1px solid var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  text-align: left;
  cursor: grab;
  /* Zonder dit neemt de browser de vingerbeweging over als scrollen en komt er
     geen enkele pointermove aan. Scrollen kan nog steeds: overal buiten een
     blok, en dat is het grootste deel van het scherm. */
  touch-action: none;
}
.sleepblokje.opgepakt {
  background: var(--accentzacht);
  border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--accent);
  font-weight: 620;
}
/* Een blok dat al ergens ligt bij een volgordevraag. Doorzichtig én
   doorgestreept, want alleen lichter maken leest op een zonnig scherm als
   "gewoon een knop". */
.sleepblokje.op {
  opacity: .45;
  text-decoration: line-through;
  cursor: default;
}

.sleepplekken {
  display: flex;
  flex-direction: column;
  gap: var(--r2);
  margin-top: var(--r3);
}
.sleepplek {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r2) var(--r3);
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 56px;
  padding: var(--r3);
  border: 1px dashed var(--rand);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
/* De plek waar het blok nu boven hangt. Een doorlopende rand in plaats van een
   streepjesrand: dat is hetzelfde verschil als tussen "hier kan iets" en "hier
   komt het als je nu loslaat". */
.sleepplek.raak {
  border-style: solid;
  border-color: var(--accent);
  background: var(--accentzacht);
}
.sleepnaam { flex: 1 1 10rem; line-height: 1.4; }
.sleepvak {
  flex: 1 1 10rem;
  padding: var(--r2) var(--r3);
  border-radius: var(--rondklein);
  background: var(--accentzacht);
  color: var(--accent);
  font-weight: 620;
}
.sleepvak.leeg {
  background: var(--randzacht);
  color: var(--zacht);
  font-weight: 400;
  font-style: italic;
}

/* Het blok dat aan de vinger hangt. position: fixed, want de pagina kan onder
   je hand door scrollen; pointer-events: none, want anders wijst
   elementFromPoint dit blok aan in plaats van de plek eronder en landt er nooit
   iets. */
.sleepzweef {
  position: fixed;
  z-index: var(--laag-deur);
  transform: translate(-50%, -50%);
  pointer-events: none;
  padding: var(--r2) var(--r4);
  border-radius: var(--rondklein);
  background: var(--accent);
  color: var(--opaccent);
  font-weight: 620;
  box-shadow: var(--schaduwdik);
}

/* --------------------------------------------------- de uitslag per regel

   Onder de uitleg, in plaats van de gewone antwoordtabel. Zie naUitleg in
   web/deelantwoorden.js voor waarom die tabel hier niet kan staan: bij drie
   stellingen zou "No" er een vinkje krijgen alsof dat het antwoord was. */

.rijenuitslag { margin: var(--r4) 0 var(--r3); }
.rijenuitslagtabel {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--randzacht);
  border-radius: var(--rondklein);
  overflow: hidden;
}
.rijenuitslagtabel th, .rijenuitslagtabel td {
  padding: var(--r2) var(--r3);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--randzacht);
  line-height: 1.4;
}
.rijenuitslagtabel tr:last-child td { border-bottom: 0; }
.rijenuitslagtabel th {
  font-size: .8125rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--zacht);
  font-weight: 620;
}
.rijenuitslagtekst { width: 55%; }
.rijenuitslagtabel tr.juist td { background: var(--goedzacht); }
.rijenuitslagtabel tr.juist td.rijenuitslagjuist { color: var(--goed); font-weight: 620; }
.rijenuitslagtabel tr.misser td { background: var(--foutzacht); }
.rijenuitslagtabel tr.misser td.rijenuitslagmijn { color: var(--fout); font-weight: 620; }
.rijenuitslagtabel tr.misser td.rijenuitslagjuist { color: var(--goed); font-weight: 620; }

/* Op een telefoon staat de stelling boven zijn twee uitkomsten in plaats van
   ernaast: drie kolommen naast elkaar op 375 punten geeft woorden van één
   lettergreep per regel. */
@media (max-width: 34rem) {
  .rijenuitslagtekst { width: auto; }
  .rijenuitslagtabel, .rijenuitslagtabel tbody, .rijenuitslagtabel tr,
  .rijenuitslagtabel td { display: block; width: 100%; }
  .rijenuitslagtabel tr { border-bottom: 1px solid var(--rand); padding: var(--r2) 0; }
  .rijenuitslagtabel td { border-bottom: 0; padding: var(--r1) var(--r3); }
  .rijenuitslagtabel tr:first-child { display: none; }
  .rijenuitslagmijn::before { content: 'Jij: '; color: var(--zacht); font-weight: 400; }
  .rijenuitslagjuist::before { content: 'Juist: '; color: var(--zacht); font-weight: 400; }
}

/* ============================================================================
   Het leerpad als spelpad, het theorieboekje en de rechterkolom
   (web/spelpad.js, web/theorieboekje.js, web/zijkolom.js) — 11-09-2026.

   Samen zijn dit de drie stukken die van scherm-pad een Duolingo-achtig
   lessenpad maken: een gekleurde balk met de naam van het domein en de knop
   naar de theorie, het slingerende pad met knooppunten eronder, en een
   rechterkolom ernaast met vandaag, de eerstvolgende toets en waar je staat.
   ========================================================================= */

/* -------------------------------------------------------- padindeling (breed) */

.padindeling {
  display: flex;
  flex-direction: column;
  gap: var(--r5);
}

@media (min-width: 52.5rem) {
  .padindeling { flex-direction: row; align-items: flex-start; gap: var(--r6); }
  .padhoofd { flex: 1 1 auto; min-width: 0; }
  .padzijkolom {
    flex: 0 0 18rem;
    display: flex;
    flex-direction: column;
    gap: var(--r4);
    /* blijft in beeld terwijl het pad eronder scrolt, net als Duolingo's
       rechterkolom naast het lessenpad */
    position: sticky;
    top: calc(4.5rem + env(safe-area-inset-top));
  }
}
@media not all and (min-width: 52.5rem) {
  .padzijkolom { display: flex; flex-direction: column; gap: var(--r4); }
}

/* ------------------------------------------------------------------ spelbalk */

.spelwrapper { display: flex; flex-direction: column; gap: 0; margin-bottom: var(--r5); }

.spelbalk {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r3);
  padding: var(--r4) var(--r5);
  border-radius: var(--rond);
  color: #fff;
  box-shadow: var(--schaduw);
}
/* Zes bandkleuren, dezelfde als het dashboard voor trajecten gebruikt (zie
   --band1 tot en met --band6 hierboven); hier onderscheiden ze domeinen. */
.spelbalk { background: var(--bandkleur, var(--traject1)); color: var(--optraject); }

.spelbalktekst { display: flex; flex-direction: column; gap: .125rem; min-width: 0; }
.spelbalklabel {
  font-size: .6875rem;
  font-weight: 640;
  text-transform: uppercase;
  letter-spacing: .05em;
  opacity: .85;
}
.spelbalktekst b {
  font-size: 1.125rem;
  font-weight: 720;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.spelboekknop {
  flex-shrink: 0;
  border: 2px solid rgba(255, 255, 255, .6);
  background: rgba(255, 255, 255, .16);
  color: #fff;
  font: inherit;
  font-size: .8125rem;
  font-weight: 680;
  text-transform: uppercase;
  letter-spacing: .02em;
  padding: var(--r2) var(--r4);
  border-radius: var(--rondklein);
  cursor: pointer;
  transform: scale(1);
  transition: background-color 140ms ease-out, transform 110ms ease-out;
}
.spelboekknop:hover { background: rgba(255, 255, 255, .26); }
.spelboekknop:active { transform: scale(.96); }

/* --------------------------------------------------------------- spelknopen */

.spelpad {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  padding: var(--r5) var(--r3);
}

.spelknoopwrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .375rem;
  width: 6.5rem;
}
/* Het lichte slingeren: een herhalend patroon van zes, zodat het pad niet in
   een kaarsrechte kolom naar beneden loopt maar ook niet willekeurig springt. */
.spelknoopwrap:nth-child(6n+2) { align-self: flex-start; margin-left: 6%; }
.spelknoopwrap:nth-child(6n+3) { align-self: flex-start; margin-left: 15%; }
.spelknoopwrap:nth-child(6n+4) { align-self: flex-end; margin-right: 15%; }
.spelknoopwrap:nth-child(6n+5) { align-self: flex-end; margin-right: 6%; }

.spelknoop {
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  border: 3px solid var(--randzacht);
  background: var(--kaart);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font: inherit;
  color: var(--zacht);
  box-shadow: 0 .18rem 0 0 var(--randzacht), var(--schaduwklein);
  transform: translateY(0);
  transition: transform 110ms ease-out, box-shadow 110ms ease-out;
}
.spelknoop:hover { filter: brightness(.97); }
.spelknoop:active {
  transform: translateY(.15rem);
  box-shadow: 0 .03rem 0 0 var(--randzacht), var(--schaduwklein);
}

.spelcode {
  font-size: .9375rem;
  font-weight: 720;
  letter-spacing: -.01em;
}

.spelvink { width: 1.75rem; height: 1.75rem; stroke-width: 2.6; color: #fff; }

/* Beheerst: vol in de trajectkleur, met een vinkje. */
.spelknoop.st-beheerst {
  background: var(--goedvol);
  border-color: var(--goedvol);
  box-shadow: 0 .18rem 0 0 var(--goeddonker), var(--schaduwklein);
}
.spelknoop.st-beheerst:active {
  box-shadow: 0 .03rem 0 0 var(--goeddonker), var(--schaduwklein);
}

/* Op weg: half gevuld — de bovenste helft in het accent, de onderste leeg. */
.spelknoop.st-opweg {
  background: linear-gradient(180deg, var(--accentvol) 0 50%, var(--kaart) 50% 100%);
  border-color: var(--accentvol);
  color: var(--tekst);
}

/* Zwak: vol in de aandachtskleur — dit is precies wat er om aandacht vraagt. */
.spelknoop.st-zwak {
  background: var(--foutvol);
  border-color: var(--foutvol);
  color: #fff;
  box-shadow: 0 .18rem 0 0 var(--foutdonker), var(--schaduwklein);
}
.spelknoop.st-zwak:active {
  box-shadow: 0 .03rem 0 0 var(--foutdonker), var(--schaduwklein);
}

/* Niet behandeld: grijs en gedempt. */
.spelknoop.st-nieuw {
  background: var(--onbehandeldzacht);
  border-color: var(--onbehandeld);
  color: var(--onbehandeld);
  opacity: .68;
}

.spelnaam {
  font-size: .75rem;
  line-height: 1.2;
  text-align: center;
  color: var(--zacht);
  max-width: 6.5rem;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* Het knooppunt dat net op beheerst komt veert op: het enige "spel"-moment
   van dit pad, en met opzet kort. app.js/kearegie.js vieren de mijlpaal er al
   apart bij (de melding onderaan); dit is de tekening zelf die meedoet. */
@media (prefers-reduced-motion: no-preference) {
  .spelknoop.netbeheerst { animation: spelveer 280ms ease-out; }
}
@keyframes spelveer {
  0% { transform: scale(1); }
  45% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

@media (max-width: 26rem) {
  .spelknoopwrap { width: 5rem; }
  .spelknoop { width: 3.25rem; height: 3.25rem; }
  .spelnaam { max-width: 5rem; }
}

/* --------------------------------------------------------- theorieboekje */

.boekachtergrond {
  position: fixed;
  inset: 0;
  z-index: var(--laag-deur);
  background: rgba(16, 24, 30, .45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .boekachtergrond { animation: boekfade 180ms ease-out; }
}
@keyframes boekfade { from { opacity: 0; } to { opacity: 1; } }

.boekpaneel {
  background: var(--kaart);
  width: 100%;
  max-width: 40rem;
  max-height: min(85dvh, 48rem);
  border-radius: var(--rond) var(--rond) 0 0;
  display: flex;
  flex-direction: column;
  box-shadow: var(--schaduwdik);
  overflow: hidden;
}
@media (min-width: 37.5rem) {
  .boekachtergrond { align-items: center; padding: var(--r5); }
  .boekpaneel { border-radius: var(--rond); max-height: min(85dvh, 44rem); }
}
@media (prefers-reduced-motion: no-preference) {
  .boekpaneel { animation: boekop 220ms ease-out; }
}
@keyframes boekop {
  from { transform: translateY(1rem); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.boekpaneelkop {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--r3);
  padding: var(--r4) var(--r5) var(--r3);
  border-bottom: 1px solid var(--randzacht);
}
.boeklabel {
  display: block;
  font-size: .75rem;
  font-weight: 640;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--zacht);
}
.boekpaneelkop h2 { margin: .125rem 0 0; font-size: 1.25rem; }

.boeksluit {
  flex-shrink: 0;
  border: 0;
  background: var(--randzacht);
  color: var(--tekst);
  font: inherit;
  font-weight: 620;
  font-size: .8125rem;
  padding: var(--r2) var(--r3);
  border-radius: var(--rondklein);
  cursor: pointer;
}
.boeksluit:hover { background: var(--rand); }

.boekkaarten {
  overflow-y: auto;
  padding: var(--r4) var(--r5) var(--r6);
  display: flex;
  flex-direction: column;
  gap: var(--r3);
}

.boekkaart {
  border: 1px solid var(--randzacht);
  border-radius: var(--rond2);
  padding: var(--r3) var(--r4);
  background: var(--vlak);
}
.boekkop { display: flex; align-items: baseline; gap: var(--r2); margin-bottom: .375rem; }
.boekcode {
  font-size: .75rem;
  font-weight: 680;
  color: var(--accent);
  background: var(--accentzacht);
  padding: .0625rem .5rem;
  border-radius: 999px;
}
.boekkop b { font-size: .9375rem; }
.boekkern { margin: 0 0 .5rem; line-height: 1.5; }
.boekbron { margin: 0; font-size: .8125rem; color: var(--zacht); }
.boekleeg { margin: 0; font-size: .875rem; color: var(--zacht); font-style: italic; }

/* -------------------------------------------------------------- zijkolom */

.zijkaart {
  border: 1px solid var(--randzacht);
  border-radius: var(--rond2);
  padding: var(--r4);
  background: var(--kaart);
  box-shadow: var(--schaduwklein);
}
.zijkaart h3 {
  margin: 0 0 var(--r3);
  font-size: .8125rem;
  font-weight: 680;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--zacht);
}
.zijleeg { margin: 0; font-size: .875rem; color: var(--zacht); }

.zijringrij { display: flex; align-items: center; gap: var(--r3); }
.zijring { width: 3.5rem; height: 3.5rem; flex-shrink: 0; transform: rotate(-90deg); }
.zijring circle { fill: none; stroke-width: 3.5; }
.zijring .baan { stroke: var(--randzacht); }
.zijring .vulling {
  stroke: var(--accent);
  stroke-linecap: round;
  transition: stroke-dashoffset .3s ease-out, stroke .3s ease-out;
}
.zijkaartvandaag.gehaald .zijring .vulling { stroke: var(--goed); }
.zijringtekst { display: flex; flex-direction: column; gap: .125rem; }
.zijringtekst b { font-size: 1.0625rem; }
.zijringtekst span { font-size: .8125rem; color: var(--zacht); }
.zijkaartvandaag.gehaald .zijringtekst span { color: var(--goed); font-weight: 620; }

.zijkaarttoets b { display: block; font-size: 1rem; margin-bottom: .125rem; }
.zijkaarttoets p { margin: 0; font-size: .875rem; color: var(--zacht); }

.zijstandregel + .zijstandregel { margin-top: var(--r3); }
.zijstandkop {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: .8125rem;
  margin-bottom: .25rem;
}
.zijstandkop b { color: var(--goed); font-weight: 680; }
.zijstandbaan {
  height: .375rem;
  border-radius: 999px;
  background: var(--randzacht);
  overflow: hidden;
}
.zijstandbaan i {
  display: block;
  height: 100%;
  background: var(--goed);
  border-radius: inherit;
  transition: width .3s ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .zijring .vulling, .zijstandbaan i { transition: none; }
}

/* ---------------------------------------------------------------- buddy */

/* Alleen als het scherm aan staat: een id-selector wint anders van .scherm { display: none }
   en dan blijft de buddy onder elk ander scherm staan. */
#scherm-buddy.aan { display: flex; flex-direction: column; height: 100%; }

.buddygesprek {
  display: flex;
  flex-direction: column;
  gap: var(--r4);
  padding: var(--r3) 0 var(--r5);
  min-height: 12rem;
}

.buddyopening {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--r3);
  text-align: center;
  padding: var(--r6) var(--r4);
  color: var(--zacht);
}
.buddyopening p { margin: 0; max-width: 28rem; }

.buddyregel { display: flex; gap: var(--r3); max-width: 40rem; }
.buddyjij { justify-content: flex-end; margin-left: auto; }
.buddyjij p {
  margin: 0;
  background: var(--accent);
  color: var(--opaccent);
  padding: var(--r3) var(--r4);
  border-radius: var(--rond2) var(--rond2) var(--r1) var(--rond2);
}
.buddybuddy .kea { flex-shrink: 0; margin-top: .125rem; }
.buddyinhoud {
  background: var(--kaart);
  border: 1px solid var(--randzacht);
  border-radius: var(--r1) var(--rond2) var(--rond2) var(--rond2);
  padding: var(--r3) var(--r4);
  display: flex;
  flex-direction: column;
  gap: .5rem;
}
.buddyinhoud p { margin: 0; line-height: 1.5; }
.buddymodel { font-size: .75rem; color: var(--zacht); font-style: italic; }
.buddybron {
  display: block;
  font-size: .75rem;
  color: var(--zacht);
  border-top: 1px solid var(--randzacht);
  padding-top: .375rem;
}
.buddybron + .buddybron { border-top: 0; padding-top: 0; }

.buddyvak {
  display: flex;
  gap: var(--r3);
  align-items: flex-end;
  position: sticky;
  bottom: var(--r4);
  background: var(--achter);
  padding-top: var(--r3);
}
.buddyveld {
  flex: 1 1 auto;
  resize: none;
  font: inherit;
  font-size: 1rem;
  padding: var(--r3);
  border: 1px solid var(--veldrand);
  background: var(--veldvlak);
  border-radius: var(--rond2);
  color: var(--tekst);
}
.buddyveld:focus { outline: 2px solid var(--ring); outline-offset: 1px; }
.buddyvraagknop { width: auto; min-width: 9rem; flex-shrink: 0; }

@media (max-width: 30rem) {
  .buddyregel { max-width: 100%; }
  .buddyvak { flex-direction: column; align-items: stretch; }
  .buddyvraagknop { width: 100%; }
}

/* --------------------------------------------------- de rondleiding
   Eén keer bij de eerste start, en daarna alleen nog via Instellingen. Hij
   leunt op dezelfde vormen als het theorieboekje (boekachtergrond/boekpaneel):
   een donkere laag met een kaart erop. Apart gehouden omdat de rondleiding
   smaller is en een rij bolletjes onderaan heeft die het boekje niet kent. */
.rondleidingachtergrond {
  position: fixed;
  inset: 0;
  z-index: var(--laag-deur);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--r4);
  background: rgb(0 0 0 / 0.45);
}

.rondleidingpaneel {
  width: min(30rem, 100%);
  max-height: 90vh;
  overflow-y: auto;
  padding: var(--r5);
  border-radius: var(--rond);
  background: var(--kaart);
  box-shadow: 0 1.5rem 3rem rgb(0 0 0 / 0.25);
}

.rondleidinglabel {
  display: block;
  margin-bottom: 0.25rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--zacht);
}

.rondleidingkop h2 { margin: 0 0 var(--r4); }

.rondleidingtekst {
  margin: 0 0 var(--r5);
  line-height: 1.55;
}

.rondleidingbolletjes {
  display: flex;
  gap: 0.4rem;
  margin-bottom: var(--r4);
}

.rondleidingbolletjes .bolletje {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--rand);
}

.rondleidingbolletjes .bolletje.nu { background: var(--accent); }

.rondleidingknoppen {
  display: flex;
  align-items: center;
  gap: var(--r3);
}

/* Overslaan staat links en duwt de rest naar rechts: weggaan mag, maar het is
   niet waar je oog als eerste landt. */
.rondleidingsluit {
  margin-right: auto;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--zacht);
  text-decoration: underline;
  cursor: pointer;
}

/* De knop waar de rondleiding het over heeft, in de zijbalk of de tabbalk. */
.rondleidingwijst {
  position: relative;
  outline: 0.15rem solid var(--accent);
  outline-offset: 0.15rem;
  border-radius: var(--rondklein);
}

@media (prefers-reduced-motion: no-preference) {
  .rondleidingpaneel { animation: rondleidingop 0.2s ease-out; }
  @keyframes rondleidingop {
    from { opacity: 0; transform: translateY(0.5rem); }
    to { opacity: 1; transform: none; }
  }
}

/* De invoerbalk van de buddy: boek erin slepen of kiezen. */
.buddyinvoer {
  display: flex;
  align-items: center;
  gap: var(--r3);
  margin-top: var(--r3);
  padding: var(--r3);
  border: 1px dashed var(--rand);
  border-radius: var(--rondklein);
  color: var(--zacht);
  font-size: .9rem;
}

.buddyinvoer.erboven {
  border-color: var(--accent);
  background: var(--accentzacht);
}

.buddykiezer { display: none; }

/* De kea boven het pad, met de dagzin in een ballon. */
.keaballonrij {
  display: flex;
  align-items: flex-start;
  gap: var(--r3);
  margin: var(--r4) 0;
}

.keaballon {
  position: relative;
  flex: 1;
  padding: var(--r3) var(--r4);
  border: 2px solid var(--rand);
  border-radius: var(--rond);
  background: var(--kaart);
}

.keaballon p { margin: 0; font-weight: 600; }

/* Het puntje naar de kea toe: twee driehoeken over elkaar, zodat de rand
   doorloopt in plaats van dat er een gat in valt. */
.keaballon::before,
.keaballon::after {
  content: '';
  position: absolute;
  top: 1.1rem;
  border: .5rem solid transparent;
}
.keaballon::before { left: -1rem; border-right-color: var(--rand); }
.keaballon::after { left: -.85rem; border-right-color: var(--kaart); }

/* De startknop onder het pad. */
.spelstartrij {
  display: flex;
  justify-content: center;
  margin-top: var(--r5);
}

.spelstart { min-width: 14rem; }

/* ------------------------------------------ de vraagvormen van VR-01 … VR-03
   Getallenlijn, vergelijkingsbouwer, woordbank en paren. Tokens en paren
   dragen het 2px-lippatroon van de kaarten (UI-01); een token dat op is blijft
   als grijze plek in de bank staan, zodat de bank niet verspringt. */
.getallenlijn { margin: var(--r4) 0 var(--r2); padding: 0 var(--r4); }
.lijnbaan {
  position: relative;
  height: 44px;
  cursor: pointer;
  touch-action: none;
}
.lijnbaan::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 4px;
  margin-top: -2px;
  background: var(--kaartrand);
  border-radius: 2px;
}
.lijnstreep {
  position: absolute;
  top: 50%;
  width: 2px; height: 14px;
  margin: -7px 0 0 -1px;
  background: var(--rand);
}
.lijnduim {
  position: absolute;
  top: 50%;
  width: 32px; height: 32px;
  margin: -16px 0 0 -16px;
  padding: 0;
  border: 2px solid var(--accent);
  border-bottom-width: var(--lip);
  border-radius: 50%;
  background: var(--kaart);
  touch-action: none;
  cursor: grab;
}
.lijnduim:not(.gezet) { opacity: .55; }
.lijnduim:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.lijnranden { display: flex; justify-content: space-between; color: var(--zacht); font-size: .9375rem; }
.lijnlezing { margin: var(--r2) 0 0; font-weight: var(--gewicht-vet); }

.tokenregel, .vergelijkingsregel {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--r2);
  min-height: 52px;
  margin: var(--r3) 0;
  padding-bottom: var(--r2);
  border-bottom: 2px solid var(--kaartrand);
}
.tokenbank { display: flex; flex-wrap: wrap; gap: var(--r2); margin: var(--r3) 0; }
.token, .tokenplek, .paar {
  min-height: 44px;
  padding: var(--r2) var(--r4);
  border: 2px solid var(--kaartrand);
  border-bottom-width: var(--lip);
  border-radius: var(--rondklein);
  background: var(--kaart);
  color: var(--tekst);
  font: inherit;
  cursor: pointer;
  touch-action: none;
}
.tokenplek { min-width: 3.5rem; border-style: dashed; border-bottom-width: 2px; background: transparent; }
.tokenplek.gevuld { border-style: solid; border-bottom-width: var(--lip); background: var(--kaart); }
.token.op {
  background: var(--uitgeschakeld);
  border-color: var(--uitgeschakeld);
  color: transparent;
  cursor: default;
}
.token.gekozen, .paar.gekozen { border-color: var(--accent); background: var(--accentzacht); }
.token:focus-visible, .tokenplek:focus-visible, .paar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vergelijkingsvast { font-weight: var(--gewicht-vet); }
.sleepschaduw { position: fixed; z-index: 50; pointer-events: none; }

.paren {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--r2);
  margin: var(--r3) 0;
}
.parenkolom { display: flex; flex-direction: column; gap: var(--r2); min-width: 0; }
.paar {
  display: flex;
  align-items: center;
  gap: var(--r2);
  padding: var(--r2) var(--r3);
  text-align: left;
  overflow-wrap: anywhere;
}
.paarnummer { min-width: 1ch; color: var(--zacht); font-weight: var(--gewicht-vet); }
.paar.gekoppeld { border-color: var(--rand); }
.paar.goed { background: var(--goedzacht); border-color: var(--goed); cursor: default; }
.paar.fout { background: var(--foutzacht); border-color: var(--fout); }

/* ------------------------------------------- fase 3: dagdoel, knooppunt, lege staat */

.dagdoelkaarten { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--r2); margin: var(--r2) 0 var(--r4); }
.dagdoelkaart, .dagenknop {
  font: inherit; font-weight: var(--gewicht-vet); color: var(--tekst);
  background: var(--kaart); border: 2px solid var(--kaartrand); border-bottom-width: var(--lipklein);
  border-radius: var(--rond); padding: var(--r3) var(--r2); cursor: pointer;
}
.dagdoelkaart[aria-pressed="true"], .dagenknop[aria-pressed="true"] { border-color: var(--accent); background: var(--accentzacht); }
.dagenperweek { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--r1); margin: var(--r2) 0; }
.dagenknop { padding: var(--r2) 0; min-height: 2.75rem; }
.dagdoelvraag { margin: 0; font-weight: var(--gewicht-vet); }

.knooppopover {
  position: relative; z-index: 5; width: min(18rem, 100%); margin: var(--r2) auto 0;
  background: var(--kaart); border: 2px solid var(--kaartrand); border-bottom-width: var(--lip);
  border-radius: var(--rond); padding: var(--r4); text-align: center; transform-origin: top center;
}
.knooppopover h3 { margin: 0 0 var(--r1); font-size: var(--tekst-basis); }
.knooppopover p { margin: 0 0 var(--r3); color: var(--zacht); }
.knooppopover .hoofdknop { width: 100%; }

.legestaat { display: flex; flex-direction: column; align-items: center; gap: var(--r3); text-align: center; margin: var(--r5) auto; max-width: 22rem; }
.legestaat p { margin: 0; color: var(--zacht); }
.zijkaart .legestaat { margin: var(--r2) auto; }

/* ------------------------------------------------- praatbalk met Kea (schil)

   Onderin elk scherm, weg te klikken, nooit weg (web/praatbalkplek.js).
   De hoogte is 56 px zolang de balk open is en 0 als hij dicht is of nog niet
   bestaat; de inhoud rekent ermee, zodat niets achter de balk valt (WCAG 2.4.11).
   Vast onderin de inhoudskolom: naast de zijbalk, boven de tabbalk. */
:root { --praatbalk-hoogte: 0px; }
:root[data-praatbalk="open"] { --praatbalk-hoogte: 56px; }

.praatbalkplek {
  position: fixed;
  left: 0;
  right: 0;
  bottom: env(safe-area-inset-bottom);
  z-index: var(--laag-vast);
}
body.metzijbalk .praatbalkplek { left: var(--zijbalkbreedte); }
body.mettabbalk .praatbalkplek { bottom: calc(var(--tabbalk-hoog) + env(safe-area-inset-bottom)); }
:root:not([data-praatbalk="open"]) .praatbalkplek { display: none; }

.praatbalkopen {
  position: fixed;
  right: var(--r4);
  bottom: calc(var(--r4) + env(safe-area-inset-bottom));
  z-index: var(--laag-vast);
  inline-size: 3.25rem;
  block-size: 3.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 2px solid var(--rand);
  background: var(--kaart);
  box-shadow: 0 2px 8px rgb(0 0 0 / .15);
  cursor: pointer;
}
body.mettabbalk .praatbalkopen { bottom: calc(var(--r3) + var(--tabbalk-hoog) + env(safe-area-inset-bottom)); }

main { padding-bottom: calc(var(--r7) + var(--praatbalk-hoogte) + var(--toetsenbord, 0px)); }
html { scroll-padding-block-end: calc(var(--r4) + var(--praatbalk-hoogte)); }
@media not all and (min-width: 37.5rem) {
  body.mettabbalk main {
    padding-bottom: calc(var(--r6) + var(--tabbalk-hoog) + var(--praatbalk-hoogte) + env(safe-area-inset-bottom) + var(--toetsenbord, 0px));
  }
  html:has(body.mettabbalk) {
    scroll-padding-block-end: calc(var(--tabbalk-hoog) + var(--praatbalk-hoogte) + env(safe-area-inset-bottom) + var(--r4));
  }
  body.mettabbalk .kortemelding {
    bottom: calc(var(--r3) + var(--tabbalk-hoog) + var(--praatbalk-hoogte) + env(safe-area-inset-bottom) + var(--toetsenbord, 0px));
  }
}
