/* ==========================================================================
   Geist, huisletter van CleverLab (zelf-gehost, variabele font 400–700).
   Subsets latin + latin-ext dekken nl-BE. Bron: Google Fonts (SIL OFL).
   ========================================================================== */

@font-face {
    font-family: 'Geist';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/geist-latin.woff2') format('woff2');
    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: 'Geist';
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url('fonts/geist-latin-ext.woff2') format('woff2');
    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;
}

/* ==========================================================================
   Design-tokens, afgestemd op cleverlabstudiebegeleiding.be (zie docs/ui-plan.md §3)

   Twee selectoren op één blok, precies zoals Bootstrap 5.3 het zelf doet: `:root` is de
   standaard, `[data-bs-theme="light"]` laat een deelboom terugvallen op licht terwijl de rest
   van de bladzijde donker staat. Dat tweede is niet theoretisch -- de opnamestudio gebruikt het
   (zie Studio.razor).

   Waarom `[data-bs-theme]` en niet gewoon `@media (prefers-color-scheme: dark)`: de donkere
   variant van Bootstrap zit niet alleen in variabelen op `:root`, maar ook in regels per
   onderdeel ([data-bs-theme=dark] .btn-close, .accordion-button::after, de tabelvariabelen).
   Een mediaquery bereikt die regels niet. Het attribuut zetten we in App.razor uit
   matchMedia('(prefers-color-scheme: dark)'), dus de voorkeur van het toestel blijft de bron.
   ========================================================================== */

:root,
[data-bs-theme="light"] {
    /* Merkpalet (1-op-1 van de website) */
    --clp-primary: #a0d591;         /* zacht groen, primaire actie */
    --clp-primary-hover: #87cc6a;
    --clp-primary-ink: #163a0c;     /* donkergroene tekst op groen */
    --clp-secondary: #5f92eb;       /* blauw, links en accenten */
    --clp-secondary-hover: #2761c4;
    --clp-secondary-ink: #ffffff;   /* tekst óp het blauw */

    --clp-foreground: #0f172a;      /* leikleur, hoofdtekst */
    --clp-muted: #5b6573;           /* gedempte tekst */
    --clp-border: #e6eaf1;          /* fijne rand */
    --clp-surface-muted: #f4f7fb;   /* lichte vlakvulling */
    --clp-background: #ffffff;      /* de bladzijde zelf */
    --clp-surface: #ffffff;         /* een kaart, een venster, een grafiekvlak */
    --clp-track: #eceef1;           /* de lege helft van een voortgangsbalk */

    /* Zacht merkvlak: een actieve chip, een geselecteerde kaart, het actieve item in de zijnav.
       De inkt hoort erbij -- in donkere modus wordt het vlak niet lichter maar donkerder, en dan
       is de donkergroene merkinkt onleesbaar. */
    --clp-accent-zacht: rgba(160, 213, 145, 0.24);
    --clp-accent-zachter: rgba(160, 213, 145, 0.16);
    --clp-accent-ink: var(--clp-primary-ink);

    /* Vakkleuren (data-accenten; blijven onderscheidend naast het merk) */
    --clp-vak-wiskunde: #7c3aed;
    --clp-vak-fysica: #2563eb;
    --clp-vak-chemie: #0f9d63;
    --clp-vak-biologie: #d97706;
    --clp-vak-generiekecompetenties: #db2777;
    --clp-vak-ink: #ffffff;         /* tekst óp een vakkleur */

    /* Semantiek: antwoorduitkomsten en misvatting-uitleg */
    --clp-correct: #198754;
    --clp-wrong: #dc3545;
    --clp-blank: #6c757d;
    --clp-misconception: #b45309;

    /* Formuliervalidatie */
    --clp-valid: #26b050;
    --clp-invalid: #e50000;

    /* Waarschuwingsbalk onderaan (#blazor-error-ui in MainLayout.razor.css) */
    --clp-waarschuwing-bg: lightyellow;
    --clp-waarschuwing-ink: #0f172a;

    /* Systeembalk bovenaan (de offline-melding). Eigen tokens en niet --clp-foreground omgekeerd:
       in donkere modus is de voorgrondkleur licht, en een lichte balk over een donkere bladzijde
       is precies het felle vlak dat we hier niet willen. */
    --clp-banner-bg: #0f172a;
    --clp-banner-ink: #ffffff;

    /* Hervat-aanbod (Oefenen.razor.css): de middenstand van de mastery-schaal, sterk verdund. */
    --clp-hervat-bg: #fdf4e1;       /* #f0a202 op 12% over wit */
    --clp-hervat-rand: #f8d58d;     /* dezelfde tint op 45% */

    /* Mastery-schaal: één continue schaal, overal dezelfde */
    --clp-mastery-low: #dc3545;
    --clp-mastery-mid: #f0a202;
    --clp-mastery-high: #2fb673;
    --clp-mastery-none: #adb5bd;

    /* Chrome */
    --clp-nav-bg: #ffffff;
    --clp-nav-ink: #0f172a;
    --clp-shadow-card: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 3px rgba(15, 23, 42, 0.06);

    /* Maatvoering */
    --clp-radius: 0.625rem;         /* 10px, knoppen */
    --clp-radius-card: 1rem;        /* 16px, kaarten */
    --clp-content-max: 62rem;
    --clp-touch-target: 44px;
    --clp-tabbar-height: 3.75rem;
    --clp-sidenav-width: 14rem;

    /* Breedte van de y-as-kolom van de voortgangsgrafiek. Twee regels moeten hetzelfde getal
       gebruiken -- de kolom zelf en de inspringing van de datumlabels eronder -- anders staan de
       datums naast hun punt. */
    --clp-voortgang-yas: 2.2rem;

    /* Hoe lang een verbroken verbinding stil mag blijven vóór de app erover begint (blok 3.2).
       Verreweg de meeste onderbrekingen op een telefoon duren één of twee seconden — live
       nagemeten met een geforceerde breuk: verbroken op 6 ms, weer verbonden op 1211 ms. Zonder
       deze pauze ziet iemand die door een tunnel rijdt om de haverklap een modale dialoog voor
       iets wat hij zelf nooit gemerkt zou hebben.

       Staat hier en niet in ReconnectModal.razor.css omdat twee kanten hem lezen: die CSS als
       animation-delay, en OfflineBanner.razor.js om te weten wanneer de dialoog écht zichtbaar
       wordt (en de offline-balk dus moet wijken). Eén getal, twee lezers. */
    --clp-verbinding-vertraging: 2000ms;
}

/* Donkere variant. Enkel kleuren: maatvoering, tijden en de twee getallen die door JS gelezen
   worden staan hierboven en gelden voor beide.

   Twee keuzes die niet vanzelf spreken:

   1. Het merkgroen blijft exact hetzelfde. Een merk dat van kleur verschiet is geen merk meer, en
      #a0d591 is licht genoeg om ook op een donkere bladzijde een vlak te zijn met donkere tekst
      erop. Het blauw en de vakkleuren kunnen dat niet -- dat zijn tekstkleuren op wit, en tekst
      van #2563eb op #0f172a haalt geen 3:1. Die worden dus lichter, en de tekst er bovenop
      (--clp-vak-ink) wordt donker in plaats van wit.
   2. Vlakken worden hier lichter dan de bladzijde en niet donkerder. Op een donkere achtergrond
      leest een lichter vlak als "dichterbij", precies zoals een schaduw dat op wit doet -- en een
      schaduw zelf doet op donker vrijwel niets meer. */
[data-bs-theme="dark"] {
    --clp-primary: #a0d591;
    --clp-primary-hover: #b4e0a7;   /* op donker gaat hover omhóóg in helderheid */
    --clp-primary-ink: #163a0c;
    --clp-secondary: #8fb4f5;
    --clp-secondary-hover: #b3ccf9;
    --clp-secondary-ink: #0f172a;

    --clp-foreground: #e8edf5;
    --clp-muted: #9aa7b8;
    --clp-border: #2c3849;
    --clp-surface-muted: #1b2434;
    --clp-background: #0f172a;
    --clp-surface: #182233;
    --clp-track: #2c3849;

    --clp-accent-zacht: rgba(160, 213, 145, 0.20);
    --clp-accent-zachter: rgba(160, 213, 145, 0.12);
    --clp-accent-ink: #cdeac0;

    --clp-vak-wiskunde: #a78bfa;
    --clp-vak-fysica: #60a5fa;
    --clp-vak-chemie: #34d399;
    --clp-vak-biologie: #fbbf24;
    --clp-vak-generiekecompetenties: #f472b6;
    --clp-vak-ink: #0f172a;

    --clp-correct: #4ade80;
    --clp-wrong: #ff6b6b;
    --clp-blank: #9aa7b8;
    --clp-misconception: #fbbf24;

    --clp-valid: #4ade80;
    --clp-invalid: #ff8080;

    --clp-waarschuwing-bg: #3a3413;
    --clp-waarschuwing-ink: #f3e6a3;

    --clp-banner-bg: #243044;
    --clp-banner-ink: #e8edf5;

    --clp-hervat-bg: #3a2e12;
    --clp-hervat-rand: #6b551f;

    --clp-mastery-low: #ff6b6b;
    --clp-mastery-mid: #fbbf24;
    --clp-mastery-high: #4ade80;
    --clp-mastery-none: #55627a;

    --clp-nav-bg: #131c2e;
    --clp-nav-ink: #e8edf5;
    --clp-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.50);
}

html, body {
    font-family: 'Geist', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    color: var(--clp-foreground);
    background-color: var(--clp-background);
}

/* ==========================================================================
   Geïnstalleerde app op een telefoon (blok 2.1 van docs/mobiel/plan-mobiele-app.md)
   ========================================================================== */

/* Geen pull-to-refresh en geen doorschietende scroll. Iemand die tijdens een vraag naar boven
   veegt om terug te lezen, herlaadt anders de pagina — en een herlaad tijdens een examensimulatie
   voelt als "mijn antwoorden zijn weg", ook al zijn ze dat niet.

   Dit is de wisselwerking uit blok 1.2, punt 3: mét deze regel is er in een geïnstalleerde app
   (standalone, dus ook geen adresbalk) geen enkele gebaarmatige manier meer om te herladen. De
   herlaadknoppen die versie.js bedient zijn daarmee niet langer een extraatje maar de énige weg
   terug. Zet deze regel dus nooit aan zonder dat die knoppen werken. */
html {
    overscroll-behavior-y: contain;
}

/* iOS zoomt automatisch in zodra je een invoerveld met een letter kleiner dan 16px aanraakt, en
   zoomt daarna niet vanzelf terug: de leerling blijft achter met een scheefgetrokken pagina.
   Vandaar 16px op alles waar je in typt of kiest, maar alleen op aanraakschermen — op een laptop
   mag een compact veld gewoon compact blijven. Selectievakjes en radioknoppen staan er bewust
   buiten: die ontlenen hun afmeting in Bootstrap aan de letterhoogte (1em), dus een opgelegde
   16px zou ze groter maken dan bedoeld. */
@media (pointer: coarse) {
    input:not([type="checkbox"]):not([type="radio"]),
    select,
    textarea,
    .form-control,
    .form-control-sm,
    .form-select,
    .form-select-sm {
        font-size: 16px;
    }
}

h1, h2, h3, h4, h5, h6 {
    color: var(--clp-foreground);
    font-weight: 700;
    letter-spacing: -0.01em;
}

a {
    color: var(--clp-secondary);
    text-decoration: none;
}

a:hover {
    color: var(--clp-secondary-hover);
    text-decoration: underline;
}

.text-muted {
    color: var(--clp-muted) !important;
}

/* ==========================================================================
   Knoppen
   ========================================================================== */

.btn {
    --bs-btn-border-radius: var(--clp-radius);
    font-weight: 600;
}

.btn-primary {
    --bs-btn-color: var(--clp-primary-ink);
    --bs-btn-bg: var(--clp-primary);
    --bs-btn-border-color: var(--clp-primary);
    --bs-btn-hover-color: var(--clp-primary-ink);
    --bs-btn-hover-bg: var(--clp-primary-hover);
    --bs-btn-hover-border-color: var(--clp-primary-hover);
    --bs-btn-active-color: var(--clp-primary-ink);
    --bs-btn-active-bg: var(--clp-primary-hover);
    --bs-btn-active-border-color: var(--clp-primary-hover);
    --bs-btn-disabled-color: var(--clp-primary-ink);
    --bs-btn-disabled-bg: var(--clp-primary);
    --bs-btn-disabled-border-color: var(--clp-primary);
}

.btn-outline-primary {
    --bs-btn-color: var(--clp-foreground);
    --bs-btn-border-color: var(--clp-border);
    --bs-btn-hover-color: var(--clp-foreground);
    --bs-btn-hover-bg: var(--clp-surface-muted);
    --bs-btn-hover-border-color: var(--clp-border);
    --bs-btn-active-color: var(--clp-foreground);
    --bs-btn-active-bg: var(--clp-surface-muted);
    --bs-btn-active-border-color: var(--clp-border);
    background-color: var(--clp-surface);
}

/* Het eerste, dunne ringetje heeft de kleur van de bladzijde en niet van de knop: het houdt de
   blauwe focusring los van de rand eronder, zodat die ring ook op een knop mét rand zichtbaar
   blijft. Daarom --clp-background en niet --clp-surface. */
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus, .form-select:focus {
    box-shadow: 0 0 0 0.1rem var(--clp-background), 0 0 0 0.25rem rgba(95, 146, 235, 0.55);
    border-color: var(--clp-secondary);
}

.form-check-input:checked {
    background-color: var(--clp-secondary);
    border-color: var(--clp-secondary);
}

h1:focus {
    outline: none;
}

/* ==========================================================================
   Kaarten en oppervlakken
   ========================================================================== */

.card {
    --bs-card-border-color: var(--clp-border);
    --bs-card-border-radius: var(--clp-radius-card);
    box-shadow: var(--clp-shadow-card);
}

.card.bg-light {
    --bs-card-bg: var(--clp-surface-muted);
    box-shadow: none;
}

.form-select, .form-control {
    border-color: var(--clp-border);
    border-radius: var(--clp-radius);
}

/* Groene marker-accent achter een woord (merkmotief van de website). */
.marker {
    background: linear-gradient(180deg, transparent 55%, var(--clp-primary) 55%);
    padding: 0 0.1em;
}

/* ==========================================================================
   Tabellen
   ========================================================================== */

/* Een tabel is het enige element in de app dat níét smaller wil worden dan haar inhoud: op een
   telefoon duwt ze anders de hele bladzijde breder en gaat álles zijwaarts schuiven. In een
   .table-responsive schuift alleen de tabel zelf.

   overscroll-behavior-x om dezelfde reden als bij de figuren in blok 8.3: wie in een tabel naar
   links veegt en het einde raakt, geeft die veeg anders door aan de browser — en dat is op Android
   en iOS het terugveeg-gebaar. Je wilde een kolom zien en je staat op de vorige pagina. */
.table-responsive {
    overscroll-behavior-x: contain;
}

/* ==========================================================================
   Presets en chips (sessieconfiguratie)
   ========================================================================== */

.preset-grid {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

.chip-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.chip {
    align-items: center;
    background: var(--clp-surface);
    border: 1px solid var(--clp-border);
    border-radius: 999px;
    color: var(--clp-foreground);
    cursor: pointer;
    display: inline-flex;
    font-size: 0.9rem;
    font-weight: 600;
    gap: 0.35rem;
    min-height: 2.25rem;
    padding: 0.35rem 0.85rem;
}

.chip:hover {
    background: var(--clp-surface-muted);
}

.chip.chip-active {
    background: var(--clp-accent-zacht);
    border-color: var(--clp-primary);
    color: var(--clp-accent-ink);
}

.chip.chip-sm {
    font-size: 0.8rem;
    min-height: 2rem;
    padding: 0.25rem 0.7rem;
}

/* De chips zijn de primaire selectie-UI van élke sessiestart: vak, onderdeel, moeilijkheid, en de
   dagen van het studieplan. Met een muis is 36px (en 32px voor de kleine variant) ruim genoeg, met
   een duim niet — 44px is de maat waarop je raak tikt zonder te kijken. Vandaar alleen op een
   aanraakscherm: een rij pillen van 44px zou op een laptop de hele kaart overheersen voor een
   probleem dat daar niet bestaat.

   min-width staat er even hard bij als min-height. De dagenkiezer van het studieplan zet er "Ma",
   "Di", "Wo" in: met de gewone padding is dat een pil van nog geen 30px breed, en dan is een hoogte
   van 44px een liggend streepje waar je nog steeds naast tikt. */
@media (pointer: coarse) {
    .chip,
    .chip.chip-sm {
        justify-content: center;
        min-height: var(--clp-touch-target);
        min-width: var(--clp-touch-target);
    }
}

/* ==========================================================================
   Mastery-schaal op Bootstrap-progressbalken
   ========================================================================== */

.progress {
    background-color: var(--clp-surface-muted);
}

.progress-bar.mastery-low { background-color: var(--clp-mastery-low); }
.progress-bar.mastery-mid { background-color: var(--clp-mastery-mid); }
.progress-bar.mastery-high { background-color: var(--clp-mastery-high); }
.progress-bar.mastery-none { background-color: var(--clp-mastery-none); color: var(--clp-foreground); }

/* Vak-indicator (gekleurd bolletje naast de vaknaam) */
.vak-dot {
    border-radius: 50%;
    display: inline-block;
    height: 0.75rem;
    margin-right: 0.4rem;
    width: 0.75rem;
    vertical-align: baseline;
}

.vak-dot.vak-wiskunde { background-color: var(--clp-vak-wiskunde); }
.vak-dot.vak-fysica { background-color: var(--clp-vak-fysica); }
.vak-dot.vak-chemie { background-color: var(--clp-vak-chemie); }
.vak-dot.vak-biologie { background-color: var(--clp-vak-biologie); }
.vak-dot.vak-generiekecompetenties { background-color: var(--clp-vak-generiekecompetenties); }

/* Voortgangsgrafiek (% juist per dag), y-as + gridlijnen */
.voortgang-wrap {
    display: flex;
    align-items: stretch;
    gap: 0.4rem;
}

/* Geen vaste hoogte: de y-as rekt mee met de grafiek ernaast, want die is nu breedte-gedreven.
   Met een hoogte van 90px stond "0%" op een breed scherm ergens halverwege de kaart. */
.voortgang-yas {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    text-align: right;
    line-height: 1;
    flex: 0 0 auto;
    min-width: var(--clp-voortgang-yas);
}

/* De verhouding staat hier en niet als hoogte-attribuut op de svg: zo houdt het vak dezelfde
   10:3 als de viewBox en schaalt de curve gelijkmatig in plaats van uitgerekt. flex-start houdt
   de stretch van de flexrij eraf, die zou de verhouding weer overrulen. */
.voortgang-grafiek {
    align-self: flex-start;
    width: 100%;
    height: auto;
    aspect-ratio: 10 / 3;
}

.voortgang-grid {
    stroke: var(--clp-muted);
    stroke-width: 1;
    opacity: 0.25;
    vector-effect: non-scaling-stroke;
}

/* Verticale markering per dag: subtieler dan de horizontale gridlijnen. */
.voortgang-dagtick {
    stroke: var(--clp-muted);
    stroke-width: 1;
    opacity: 0.15;
    vector-effect: non-scaling-stroke;
}

/* De x-as-labels uitlijnen onder de grafiek (voorbij de y-as-kolom) */
.voortgang-xas {
    padding-left: calc(var(--clp-voortgang-yas) + 0.4rem);
}

/* Datumlabels absoluut positioneren onder hun datapunt, één per dag.
   overflow: hidden, want een label dat toch buiten de kaart zou vallen mag de pagina niet
   breder maken -- op een telefoon levert dat horizontaal geschuif op het hele scherm op. */
.voortgang-dagen {
    position: relative;
    height: 1rem;
    margin-top: 0.15rem;
    overflow: hidden;
}

.voortgang-dag {
    position: absolute;
    top: 0;
    white-space: nowrap;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

/* Twaalf datums van "dd/MM" naast elkaar vragen zo'n 480px; een telefoon heeft er 300.
   De server weet de schermbreedte niet, dus draagt elk label zijn dichtheidsrang mee en valt
   hier per breekpunt de helft weg. De eerste en de laatste dag blijven altijd staan. */
@media (max-width: 767.98px) {
    .voortgang-dag[data-dicht="2"] {
        display: none;
    }
}

@media (max-width: 479.98px) {
    .voortgang-dag[data-dicht="1"] {
        display: none;
    }
}

/* Badges wat zachter */
.badge.bg-light {
    background-color: var(--clp-surface-muted) !important;
    color: var(--clp-muted) !important;
    font-weight: 600;
}

/* ==========================================================================
   Formulieren en foutafhandeling (Blazor-standaard)
   ========================================================================== */

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--clp-valid);
}

.invalid {
    outline: 1px solid var(--clp-invalid);
}

.validation-message {
    color: var(--clp-invalid);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

/* ==========================================================================
   Studieplan, weekweergave, op-schema-widget en wizard
   ========================================================================== */

.plan-week {
    border: 1px solid var(--clp-border);
    border-radius: var(--clp-radius-card);
    box-shadow: var(--clp-shadow-card);
}

.plan-week-eindfase {
    background-color: var(--clp-surface-muted);
}

.plan-badge-eindfase {
    background-color: var(--clp-secondary);
    color: var(--clp-secondary-ink);
    font-weight: 600;
}

.plan-badge-luwte {
    background-color: var(--clp-surface-muted);
    color: var(--clp-muted);
    border: 1px solid var(--clp-border);
    font-weight: 600;
}

.plan-week-onderdelen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

/* Onderdeel-box: nieuwe leerstof in vak-kleur, herhaling grijs. */
.plan-box {
    border-radius: 6px;
    color: var(--clp-vak-ink);
    font-size: 0.82rem;
    font-weight: 600;
    padding: 0.2rem 0.6rem;
    white-space: nowrap;
}

.plan-box.vak-wiskunde { background-color: var(--clp-vak-wiskunde); }
.plan-box.vak-fysica { background-color: var(--clp-vak-fysica); }
.plan-box.vak-chemie { background-color: var(--clp-vak-chemie); }
.plan-box.vak-biologie { background-color: var(--clp-vak-biologie); }
.plan-box.vak-generiekecompetenties { background-color: var(--clp-vak-generiekecompetenties); }

.plan-box-herhaling {
    background-color: var(--clp-surface-muted);
    color: var(--clp-muted);
    border: 1px solid var(--clp-border);
}

/* Weekbord: het studieplan op week-niveau, per week boxjes met de leerstof (feedback). */
.plan-board-maand {
    color: var(--clp-muted);
    margin: 1rem 0 0.4rem;
    text-transform: capitalize;
}

.plan-board-weken {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.6rem;
}

.plan-board-week {
    border: 1px solid var(--clp-border);
    border-radius: var(--clp-radius-card);
    box-shadow: var(--clp-shadow-card);
    padding: 0.6rem 0.75rem;
}

.plan-board-week-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.45rem;
}

/* Categoriekop op de Oefenen-pagina (Studieplan / Vrij oefenen / Gericht oefenen). */
.oefen-categorie {
    color: var(--clp-muted);
    margin: 1.25rem 0 0.5rem;
}
.oefen-categorie:first-of-type {
    margin-top: 0.5rem;
}

.op-schema {
    align-items: center;
    border: 1px solid var(--clp-border);
    border-radius: var(--clp-radius-card);
    display: inline-flex;
    gap: 0.6rem;
    padding: 0.6rem 1rem;
}

.op-schema-dot {
    border-radius: 50%;
    flex: none;
    height: 0.7rem;
    width: 0.7rem;
}

.op-schema-goed .op-schema-dot { background-color: var(--clp-mastery-high); }
.op-schema-achter .op-schema-dot { background-color: var(--clp-mastery-mid); }

.wizard {
    max-width: 34rem;
}

.streak-teller {
    color: var(--clp-muted);
    font-weight: 600;
}

/* ==========================================================================
   G-TIMER: sessie-brede afteltijdbalk (examensimulatie/proefexamen)
   ========================================================================== */

/* Blauwe balk boven de vraag die client-side afloopt via de klp-timer-af-animatie.
   De resterende breedte komt uit de inline-stijl (width + negatieve animation-delay),
   zodat de balk over vragen heen blijft doorlopen zonder server-round-trips. */
.exam-timer {
    max-width: 44rem;
    height: 8px;
    margin: 0 auto 0.75rem;
    background: var(--clp-surface-muted);
    border: 1px solid var(--clp-border);
    border-radius: 999px;
    overflow: hidden;
}

.exam-timer-bar {
    height: 100%;
    background: var(--clp-secondary);
    border-radius: 999px;
}

@keyframes klp-timer-af {
    from { width: 100%; }
    to { width: 0%; }
}

/* Reduced motion: geen animatie; de statische breedte uit de inline-stijl toont de resterende tijd. */
@media (prefers-reduced-motion: reduce) {
    .exam-timer-bar { animation: none !important; }
}

/* Blok 8.7 (C18, WCAG 2.2.1): de balk met de afleesbare stand ernaast. Een balk die leegloopt is
   voor wie hem niet ziet geen informatie, en ook wie hem wél ziet leest er geen minuten uit af. */
.exam-timer-blok {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    max-width: 44rem;
    margin: 0 auto 0.75rem;
}

/* De balk zelf verliest binnen het blok haar eigen breedte en marge; buiten het blok (DevPreview)
   houdt ze die. */
.exam-timer-blok .exam-timer {
    flex: 1 1 auto;
    max-width: none;
    margin: 0;
}

/* Tabulaire cijfers: zonder dit springt "1:09" bij elke tik een paar pixels op en neer. */
.exam-timer-tijd {
    flex: 0 0 auto;
    min-width: 3.5ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--clp-muted);
}

/* Krap en kritiek. De kleur zegt hier niets wat het getal ernaast niet al zegt — kleur draagt dus
   nooit alleen de boodschap (WCAG 1.4.1). */
.exam-timer-blok-krap .exam-timer-tijd {
    color: var(--clp-waarschuwing-ink);
}

.exam-timer-blok-krap .exam-timer-bar {
    background: var(--clp-waarschuwing-ink);
}

.exam-timer-blok-kritiek .exam-timer-tijd {
    color: var(--clp-wrong);
}

.exam-timer-blok-kritiek .exam-timer-bar {
    background: var(--clp-wrong);
}

/* ==========================================================================
   Installeren: wat alleen in een browsertab zin heeft
   ========================================================================== */

/* Een uitnodiging om te installeren hoort niet in de geïnstalleerde app. Dit staat bewust in CSS en
   niet in een @if op de server: standalone is een eigenschap van het vénster, niet van het account.
   Dezelfde ingelogde student kan tegelijk in de app en in een browsertab zitten, en de server ziet
   dat verschil niet -- het venster wel, meteen bij de eerste verf, zonder interop af te wachten.
   Drie display-modes om dezelfde reden als in installeren.js: fullscreen en minimal-ui zijn ook
   "vanaf het beginscherm gestart". navigator.standalone van oudere iOS-versies vangt dit niet; die
   krijgen de regel te zien, en dat is de goede kant om op te falen (zichtbaar boven verborgen). */
@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
    .clp-alleen-browser {
        display: none !important;
    }
}
