/* ============================================================
   ExamenFlix — huisstijl

   GEGENEREERD BESTAND — NIET MET DE HAND AANPASSEN.

   Samengesteld uit de tokenbestanden van het designsysteem, dat in de
   ExamenFlix-repo staat onder .claude/skills/examenflix-design/. Wil je een
   kleur, een maat of een font wijzigen, dan doe je dat daar.

   Op het platform zelf:
       node scripts/bouw-huisstijl.js

   Voor een losstaande trainer, via de skill examenflix-huisstijl:
       node ~/.claude/skills/examenflix-huisstijl/scripts/ververs-uit-designsysteem.js
       node ~/.claude/skills/examenflix-huisstijl/scripts/sync-huisstijl.js <trainer>

   Beide wegen leveren dit bestand byte-identiek op. Dat is de hele reden dat
   het gegenereerd wordt: een handmatige kopie loopt binnen een maand uiteen,
   en dan heeft de ene trainer een kleur die de andere niet heeft.

   Vakspecifieke kleuren (domeinaccenten) horen NIET hier maar in het
   per-project bestand styles/brand-vak.css.

   Bevat uitsluitend variabelen en basistypografie. Alle componenten in
   main.css, nav.css, motion.css en admin.css lezen deze namen; nergens in
   die bestanden hoort een letterlijke kleurwaarde te staan.
   controleer-huisstijl.js dwingt dat af.

   Afkomstig van outsmart-huisstijl (productlijn OutSmart your Exam, huisstijl
   Extern.pro): zelfde systeem, andere merknaam en een andere heldenkleur.
   Structuur en namen zijn bewust gelijk gehouden — alleen het rood is nieuw.
   ============================================================ */

/* ==== tokens/kleuren.css ==== */
/* ---------- ExamenFlix-palet ----------
   Eén heldenkleur (ExamenFlix Rood), veel wit, sterk typografisch contrast
   tussen een zware kop en een rustige body. Terughoudendheid is de stijl:
   geen regenboog. */
:root {
  --examenflix-rood: #F02226;  /* heldenkleur: uit het logo, focus en actie */
  --diep-rood: #C4141A;        /* hover en actieve staten */
  --bos-rood: #7A1015;         /* diepte, donkerste accent */

  /* De heldenkleur haalt tegen wit 4,2:1. Genoeg voor grote tekst en voor
     vlakken, niet ruim boven de 4,5:1 die kleine tekst nodig heeft — en de
     merkstijl eist AA expliciet. Daarom één regel: vlakken, randen en koppen
     krijgen de heldenkleur, kleine tekst en witte knoplabels de diepere tint
     (6,1:1). Het merkbeeld blijft rood; alleen tekst die je moet kunnen lezen
     wordt een stap donkerder. */
  --rood-tekst: var(--diep-rood);

  --blos: #FCEAEA;             /* zachte sectieachtergrond */
  --mint: var(--blos);         /* compat-naam uit de vorige (groene) huisstijl */

  /* ---------- Neutralen ---------- */
  --inktzwart: #1A1A1A;      /* koppen en bodytekst */
  --steengrijs: #6E6E6E;     /* secundaire tekst */
  --mistgrijs: #F4F4F4;      /* pagina-achtergrond */
  --border-gray: #E4E4E4;
  --white: #FFFFFF;

  /* Paneelkleur als eigen naam naast --white. Componenten die een kaart of
     paneel vullen horen --paneel te gebruiken: dat is de enige haak waarmee
     een donkere modus ooit kan werken. --white blijft bestaan voor wat écht
     wit moet zijn (tekst op een rode knop, de knop van een schakelaar). */
  --paneel: var(--white);

  /* De grond onder het balklogo. Het logo is transparant (het woordmerk is
     wit), dus in het lichte register tekent de balk er zelf zijn donkerblauwe
     plaat onder — de grondkleur van het aangeleverde logo. In donker is hij
     transparant en valt het logo weg in de balk (besluit 422). */
  --logo-grond: #040F1C;

  /* Neutrale vlakken binnen kaarten (invoerblokken, uitwerkingen). */
  --vlak: #F7F7F7;
  --vlak-rand: #E4E4E4;

  /* Vulling van een neutraal chipje of badge — een tint donkerder dan --vlak,
     zodat hij op een wit paneel nog te zien is. Ook de vulling van een melding
     van een student, want dat is hetzelfde vlak met een andere betekenis. */
  --paneel-grijs: #EDEDED;

  /* De heldenkleur als gloed onder een knop die om aandacht vraagt. Een
     schaduw is geen merkkleur maar een hoeveelheid licht — behalve deze,
     want hij is zichtbaar rood en hoort dus mee te wisselen met het merk. */
  --rood-gloed: rgba(240, 34, 38, 0.35);
  --rood-gloed-sterk: rgba(240, 34, 38, 0.45);

  /* ---------- Domeinaccenten ----------
     Een generieke schaal van licht naar donker, niet zes willekeurige tinten.
     Een schaal op hélderheid is voor kleurenblinde gebruikers béter te
     onderscheiden dan losse tinten, en kleur is hier hoe dan ook de tweede
     aanwijzing: elk domein heeft ook een icoon en een naam.

     Alleen gebruiken waar géén tekst op staat (accentbalken, stippen,
     voortgangsbalken). Witte tekst op de heldenkleur haalt AA niet.

     De koppeling van vakcodes aan deze schaal staat per project in
     styles/brand-vak.css:  --domein-OKI: var(--domein-3);
     Meer domeinen dan zes? Laat de schaal rondlopen. */
  --domein-1: #E8969A;
  --domein-2: var(--examenflix-rood);
  --domein-3: var(--diep-rood);
  --domein-4: var(--bos-rood);
  --domein-5: #4A0C10;
  --domein-6: #2E0709;
}

/* ==== tokens/status.css ==== */
/* ---------- Semantische statussen ----------
   Deze stonden ooit als losse hex-waarden in de componenten. Dat werkt tot
   de dag dat de huisstijl wisselt: dan volgt alles behalve die waarden, en
   zie je twee statussen die op elkaar gaan lijken.

   Elke status heeft een tekstvariant, want de vlakkleur is te licht om
   tekst op te zetten en de volle kleur te licht om tekst ván te maken.

   --goed is groen en niet de heldenkleur (herzien 24-08). Het stond eerst op
   --examenflix-rood, met --fout als een dóffer rood ernaast; in de praktijk
   zijn dat twee roden die niemand uit elkaar houdt. Een goed beantwoorde
   vraag kwam daardoor in een rode balk te staan — precies het signaal dat
   "fout" betekent. Groen is hier geen decoratie maar betekenis, en dat weegt
   zwaarder dan één kleur in de hele huisstijl. */
:root {
  --groen: #1B8A4B;        /* randen, iconen, vlakken */
  --groen-diep: #12693A;   /* letters: 6,0:1 op wit */
  --groen-bg: #EAF7EF;
  --goed: var(--groen);
  --goed-bg: var(--groen-bg);
  --goed-tekst: var(--groen-diep);

  --waarschuwing: #E6A100;
  --waarschuwing-bg: #FDF4DE;
  --waarschuwing-tekst: #7A5200;

  --fout: #C0392B;
  --fout-bg: #FBEAE7;
  --fout-tekst: #8E2B20;

  --info: #2C7BE5;
  --info-bg: #EAF2FD;
  --info-tekst: #1A4E96;

  /* Rood dat leesbaar is op een donker vlak. Nodig voor de enkele
     componenten die altijd donker zijn (de XP-toast), los van de donkere
     modus. Op inktzwart haalt dit 6,9:1; --examenflix-rood haalt daar 3,3:1. */
  --rood-op-donker: #FF7A70;

  /* Markering in het examen: moet zichtbaar ánders zijn dan "beantwoord",
     anders lijken twee toestanden op elkaar. Daarom amber en niet nóg een
     rood. */
  --markering: var(--waarschuwing);
  --markering-bg: var(--waarschuwing-bg);
  --markering-tekst: var(--waarschuwing-tekst);

  /* Melding van een student: het enige signaal in de reviewlijst dat van een
     mens komt, dus inktzwart — maximaal contrast, zonder een zesde kleur. */
  --melding: var(--inktzwart);
  --melding-bg: var(--paneel-grijs);

  /* ---------- Feedback ----------
     VEROUDERD in nieuwe CSS — gebruik --goed / --goed-bg en --fout / --fout-bg.
     Deze namen blijven staan omdat de losstaande trainers (verkeer, rekenen,
     scooter) ze in hun eigen main.css en admin.css gebruiken.

     --feedback-good stond op de heldenkleur terwijl --goed groen is. Dat is
     dezelfde fout die op 24-08 in --goed is hersteld, hier één laag dieper
     blijven staan: een goed antwoord kreeg een rode balk. Hij wijst nu naar
     --goed, zodat "goed is groen" ook in die trainers klopt zodra ze
     synchroniseren. */
  --feedback-good: var(--goed);
  --feedback-good-bg: var(--goed-bg);
  --feedback-bad: var(--fout);
  --feedback-bad-bg: var(--fout-bg);

  /* Engelse aliassen — verkeer's main.css gebruikt deze namen. */
  --warning: var(--waarschuwing);
  --warning-bg: var(--waarschuwing-bg);
  --error: var(--fout);
  --error-bg: var(--fout-bg);
}

/* ==== tokens/spel.css ==== */
/* ---------- Spelpalet ----------
   UITSLUITEND voor de motiverende laag: streaks, badges, niveaus, de sprint
   en de ranglijst. Examen, oefenen en de uitslagpagina blijven rood/grijs.
   Die twee registers uit elkaar houden is de hele bedoeling — gebruik deze
   kleuren dus nooit in een vraagscherm.

   Het spelpalet staat NAAST de hoofdtokens, het vervangt ze nooit.
   Schermen die het mogen gebruiken krijgen class="register-spel" op body. */
:root {
  --vlam: #FF6B2C;
  --vlam-diep: #E04E12;
  --vlam-bg: #FFF1E8;
  --goud: #F5B301;
  --goud-diep: #C98F00;
  --goud-bg: #FFF8E1;
  --level-paars: #6C4BD6;
  --level-diep: #4E33A8;
  --level-bg: #F0ECFC;
  --verloop-vlam: linear-gradient(135deg, #FF8A3D, #E04E12);
  --verloop-goud: linear-gradient(135deg, #FFD34D, #C98F00);
  --verloop-level: linear-gradient(135deg, #8A6BE8, #4E33A8);

  /* De gloed onder de pulserende streakvlam. Zie --rood-gloed: zichtbaar
     gekleurd, dus een token en geen losse rgba in motion.css. */
  --vlam-gloed: rgba(255, 107, 44, 0.65);
}

/* ==== tokens/typografie.css ==== */
/* ---------- Typografie ----------
   Het contrast tussen een zware kop en een rustige body is het onderdeel
   dat moet blijven staan: Montserrat ExtraBold/Black tegen Open Sans.

   De maten hieronder staan als token zodat een specimen en een component
   hetzelfde getal lezen. basis/basis.css zet ze op de elementen zelf. */
:root {
  --font-header: 'Montserrat', 'Helvetica Neue', sans-serif;
  --font-body: 'Open Sans', sans-serif;
  --kop-gewicht: 800;

  --tekst-basis: 15px;
  --regelhoogte-basis: 1.6;
  --h1: 44px;
  --h2: 34px;
  --h3: 26px;
  --h4: 20px;
  /* Paginakop binnen de app (.kop h1) is bewust kleiner dan de marketing-h1 */
  --kop-h1: 30px;
  --label-klein: 13px;
  /* Antwoordopties staan vast op 16px: daaronder zoomt iOS Safari in bij het
     aantikken van een veld. Zie ook --tekst-invoer in tokens/aanraken.css. */
  --optie-tekst: 16px;
}

/* ==== tokens/vorm.css ==== */
/* ---------- Vorm ----------
   Kaart: wit vlak, 1px lijnrand, radius 10px, lage schaduw. Knoppen en velden
   radius 6px, pillen 999px. Geen gradiënten buiten het spelpalet. */
:root {
  --card-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
  --card-shadow-hover: 0 6px 22px rgba(0, 0, 0, 0.10);
  --radius: 10px;
  --radius-sm: 6px;
  --pil: 999px;
  --nav-hoogte: 80px;
  --max-breedte: 1100px;
}

/* ==== tokens/aanraken.css ==== */
/* ---------- Aanraken en invoer ----------
   Twee getallen die op een telefoon het verschil maken tussen bruikbaar en
   bijna bruikbaar. Ze staan hier en niet per component, omdat een ondergrens
   die je per component opnieuw kiest geen ondergrens is.

   --raakvlak is de maat voor alles wat je aan kunt raken. Onder de 44px
   mist een duim structureel; dat is geen smaakkwestie maar het getal dat
   Apple en Google allebei voorschrijven. Een knop mag kleiner ogen dan zijn
   raakvlak — geef hem dan padding of een onzichtbare marge, geen kleinere
   hoogte.

   --tekst-invoer is de ondergrens voor een invoerveld. Safari op iOS zoomt
   de héle pagina in zodra je een veld met kleinere tekst aanraakt, en zoomt
   daarna niet terug. Eén pixel te weinig kost de gebruiker dus zijn layout
   voor de rest van het bezoek. */
:root {
  --raakvlak: 44px;
  --tekst-invoer: 16px;

  /* De veilige onderrand van een telefoon met een home-indicator. Alles wat
     vast onderaan het scherm staat telt hem op bij zijn eigen padding; de
     pagina telt hem op bij de ruimte die ze voor die balk vrijhoudt. Zonder
     dit valt de laatste knop van een pagina onder de indicator. */
  --veilig-onder: env(safe-area-inset-bottom, 0px);
}

/* ==== tokens/aliassen.css ==== */
/* ---------- Sjabloonnamen en compat-aliassen ----------
   Twee woordenlijsten bestaan naast elkaar.

   De rolnamen komen uit het sjabloon van examentrainer-frontend, dat een
   eigen, kortere woordenlijst gebruikt. Die staat hier vertaald, zodat de
   huisstijl een drop-in is voor een verse trainer uit het sjabloon: main.css
   blijft werken zonder één regel te veranderen.

   Daaronder staat een reeks verouderde namen uit eerdere huisstijlen. Ze
   blijven staan zodat bestaande componentregels werken. Nieuwe CSS gebruikt
   de rolnamen uit tokens/kleuren.css en tokens/status.css.

   Verwijderen zodra dit in alle trainers nul oplevert:
     grep -c 'sky-pulse\|tangerine\|royal-indigo\|emerald-drive' styles/*.css */
:root {
  --hoofdkleur: var(--examenflix-rood);
  --hoofdkleur-diep: var(--diep-rood);
  --hoofdkleur-licht: var(--blos);
  --inkt: var(--inktzwart);
  --grijs: var(--steengrijs);
  --lijn: var(--border-gray);
  --achtergrond: var(--mistgrijs);
  --font-kop: var(--font-header);
  --font-tekst: var(--font-body);
  --radius-s: var(--radius-sm);
  --schaduw: var(--card-shadow);

  /* VEROUDERD — niet gebruiken in nieuwe CSS. */
  --sky-pulse: var(--rood-tekst);           /* links en kleine accenttekst */
  --tangerine-heat: var(--rood-tekst);      /* primaire knoppen (witte tekst erop) */
  --tangerine-dark: var(--bos-rood);        /* knop-hover */
  --emerald-drive: var(--examenflix-rood);  /* geslaagd, goed */
  --royal-indigo: var(--bos-rood);          /* open vragen, XP */
  --solar-gold: var(--waarschuwing);        /* waarschuwing — spaarzaam */
  --crimson-flame: var(--fout);             /* fout — bewust ánders rood dan de heldenkleur */
  --pure-noir: var(--inktzwart);
  --ash-stone: var(--steengrijs);
  --light-gray: var(--mistgrijs);
}

/* ==== tokens/donker.css ==== */
/* ---------- Donkere modus ----------
   Bewust OPT-IN, niet op prefers-color-scheme alleen. Aanzetten per project
   met <html data-thema="auto"> (volgt het systeem), forceren met
   <html data-thema="donker">, en met class="thema-donker" op een willekeurig
   element om licht en donker naast elkaar te zetten (zie
   guidelines/donkere-modus.html).

   Donker werkt alleen als componenten hun panelen met --paneel vullen en niet
   met --white. In kern/styles is dat sinds 31-08 zo; controleer-huisstijl.js
   sectie D bewaakt het.

   De waarden staan hieronder twee keer. Dat is niet mooi maar wel nodig: één
   set moet ongeconditioneerd gelden (geforceerd donker en de scope-class), de
   andere alleen binnen de media query (auto). CSS kent geen mixin, en een
   tussenlaag van variabelen maakt elke waarde twee keer indirect.

   De aliassen uit tokens/aliassen.css moeten in béide blokken opnieuw: een
   custom property wordt berekend op het element waar hij is gedeclareerd.
   --lijn staat op :root en heeft daar de lichte --border-gray al ingebakken;
   een scope die alleen --border-gray overschrijft verandert --lijn niet mee.
   Zonder die regels blijven paneelranden, balken en uitwerkingen licht.

   Het spelpalet moet mee: --vlam-bg, --goud-bg en --level-bg zijn bijna wit
   en gloeien op een donker paneel als je ze laat staan. */

:root[data-thema="donker"],
:root[data-thema="auto"] { color-scheme: dark; }
.thema-donker { color-scheme: dark; }

:root[data-thema="donker"],
.thema-donker {
  /* Een scope moet ook de tekstkleur zetten: kinderen erven anders de donkere
     inkt van body, en die verdwijnt op een donker vlak. */
  color: var(--inktzwart);

  --inktzwart: #F2F4F5;
  --steengrijs: #A8B3B5;
  --mistgrijs: #14191A;
  --border-gray: #2C3436;
  --paneel: #1D2426;
  --logo-grond: transparent;  /* het logo valt weg in de balk */
  --vlak: #232B2D;
  --vlak-rand: #2C3436;

  --blos: #331515;
  --groen: #35B36B;        /* op een donker vlak is #1B8A4B te dof voor een rand */
  --goed-bg: #12291C;
  --goed-tekst: #7BD9A0;
  --fout-bg: #3A1D19;
  --fout-tekst: #F0A79C;
  --waarschuwing-bg: #332A14;
  --waarschuwing-tekst: #E8C173;
  --info-bg: #14243A;
  --info-tekst: #8FBDF0;
  --paneel-grijs: #262B2C;  /* --melding-bg volgt hem */

  --feedback-good-bg: var(--goed-bg);
  --feedback-bad-bg: var(--fout-bg);

  --vlam-bg: #34211A;
  --goud-bg: #332C14;
  --level-bg: #241E3A;

  /* Op donker mag de heldenkleur zelf tekst zijn: contrast keert om. */
  --rood-tekst: #FF7A70;

  --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  --card-shadow-hover: 0 6px 22px rgba(0, 0, 0, 0.5);

  /* Aliassen opnieuw — zie de toelichting bovenaan. */
  --hoofdkleur-licht: var(--blos);
  --inkt: var(--inktzwart);
  --grijs: var(--steengrijs);
  --lijn: var(--border-gray);
  --achtergrond: var(--mistgrijs);
  --schaduw: var(--card-shadow);
}

@media (prefers-color-scheme: dark) {
  :root[data-thema="auto"] {
    --inktzwart: #F2F4F5;
    --steengrijs: #A8B3B5;
    --mistgrijs: #14191A;
    --border-gray: #2C3436;
    --paneel: #1D2426;
    --logo-grond: transparent;  /* het logo valt weg in de balk */
    --vlak: #232B2D;
    --vlak-rand: #2C3436;

    --blos: #331515;
    --groen: #35B36B;
    --goed-bg: #12291C;
    --goed-tekst: #7BD9A0;
    --fout-bg: #3A1D19;
    --fout-tekst: #F0A79C;
    --waarschuwing-bg: #332A14;
    --waarschuwing-tekst: #E8C173;
    --info-bg: #14243A;
    --info-tekst: #8FBDF0;
    --paneel-grijs: #262B2C;  /* --melding-bg volgt hem */

    --feedback-good-bg: var(--goed-bg);
    --feedback-bad-bg: var(--fout-bg);

    --vlam-bg: #34211A;
    --goud-bg: #332C14;
    --level-bg: #241E3A;

    --rood-tekst: #FF7A70;

    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
    --card-shadow-hover: 0 6px 22px rgba(0, 0, 0, 0.5);

    /* Aliassen opnieuw — zie de toelichting bovenaan. */
    --hoofdkleur-licht: var(--blos);
    --inkt: var(--inktzwart);
    --grijs: var(--steengrijs);
    --lijn: var(--border-gray);
    --achtergrond: var(--mistgrijs);
    --schaduw: var(--card-shadow);
  }
}

/* ==== basis/basis.css ==== */
/* ---------- Basis ---------- */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-body);
  font-size: var(--tekst-basis);
  line-height: var(--regelhoogte-basis);
  color: var(--inktzwart);
  background: var(--mistgrijs);
  -webkit-font-smoothing: antialiased;
}

/* Koppen zwaar en met krappe tracking: dat is het handschrift van dit merk. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-header);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--inktzwart);
}

h1 { font-size: var(--h1); font-weight: 900; line-height: 1.05; }
h2 { font-size: var(--h2); }
h3 { font-size: var(--h3); }
h4 { font-size: var(--h4); }

/* Kleine labels in klein kapitaal, zoals de merkstijl voorschrijft. */
.label-klein {
  font-size: var(--label-klein);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--steengrijs);
  font-weight: 600;
}

a {
  color: var(--rood-tekst);
  text-decoration: none;
}

/* Hover alleen waar er een aanwijzer is. Op een touchscreen blijft een
   hover-staat na een tik hángen tot je ergens anders tikt — een kaart die
   omhoog blijft staan leest als "geselecteerd" terwijl er niets geselecteerd
   is. Elke :hover in deze huisstijl hoort in zo'n blok. */
@media (hover: hover) {
  a:hover { color: var(--bos-rood); }
}

/* Eén woord in de kop rood: de techniek uit de merkstijl, afgeleid van het
   woordmerk (Examen wit + Flix rood). */
.rood-accent { color: var(--examenflix-rood); }

/* ---------- Invoer ----------
   Formuliervelden erven de typografie van de pagina niet; zonder deze regel
   staat elk veld in de systeemfont van de browser. De grootte is de bodem uit
   --tekst-invoer: een component mag een veld gróter zetten, nooit kleiner.
   controleer-huisstijl.js meldt het wanneer dat toch gebeurt. */
input, select, textarea, button {
  font-family: var(--font-body);
}
input, select, textarea {
  font-size: var(--tekst-invoer);
}

/* ---------- Focus ----------
   Zichtbare focus is geen extra. Wie met een toetsenbord of een schakelaar
   bedient heeft hem nodig, en :focus-visible toont hem alleen dán — een
   muisklik of een tik op het scherm laat hem met rust. Eén regel hier scheelt
   hem in elk component apart te moeten zetten. */
:focus-visible {
  outline: 2px solid var(--examenflix-rood);
  outline-offset: 2px;
}

/* Op een smal scherm schuift de hele schaal een stap terug. Dat gebeurt door
   de tokens te herdefiniëren en niet door de elementen opnieuw te zetten: dan
   klopt een component die --h2 leest ook op een telefoon, en staat elk getal
   nog steeds maar op één plek. */
@media (max-width: 768px) {
  :root {
    --tekst-basis: 14px;
    --h1: 32px;
    --h2: 26px;
    --h3: 21px;
  }
}
