/* SDS AdministratieApp — basisstijl
   Sober, functioneel, geïnspireerd op de "s e n d r a design studio" huisstijl-typografie.
   Layout: vaste zijbalk (in-/uitklapbaar) + topbalk, licht/donker thema via [data-thema]. */

:root {
    /* -- Licht thema (standaard) ------------------------------------- */
    --inkt: #1a1a1a;
    --gedimd: #6b6b6b;
    --lijn: #e2e0dc;
    --papier: #ffffff;
    --achtergrond: #f5f4f1;
    --accent: #0f4c81;
    --accent-donker: #0b3a63;
    --accent-zacht: #eaf1f8;
    --ok: #1c6b3c;
    --ok-achtergrond: #e5f3ea;
    --fout: #9b1c1c;
    --fout-achtergrond: #fbe9e9;
    /* Toegankelijkheid: zie docs/toegankelijkheid.md. --veldrand haalt 3:1
       tegen zowel --papier als --achtergrond (WCAG 1.4.11; --lijn haalt 1,3:1
       en is alleen voor decoratieve randen). --knop-tekst staat op vlakken met
       --accent/--fout/--gedimd als achtergrond. */
    --veldrand: #767676;
    --knop-tekst: #ffffff;
    --fout-hover: #7a1414;

    --zijbalk-bg: #edece7;
    --zijbalk-lijn: #ddd9d1;
    --zijbalk-tekst: #4c4a45;
    --zijbalk-tekst-actief: #1a1a1a;
    --zijbalk-actief-bg: #ffffff;

    --schaduw-sm: 0 1px 2px rgba(30, 26, 14, 0.05), 0 1px 6px rgba(30, 26, 14, 0.04);
    --schaduw-md: 0 4px 14px rgba(30, 26, 14, 0.07);

    /* -- Maten, herbruikbaar ------------------------------------------ */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --zijbalk-breedte: 15.5rem;
    --zijbalk-breedte-dicht: 4.5rem;

    /* Focusstijl (toetsenbord), bewust in beide thema's hetzelfde — zie het
       blok "Toetsenbordfocus" verderop. Zwart op #ffdd00 = 15,6:1. */
    --focus-bg: #ffdd00;
    --focus-lijn: #000000;
}

/* Systeemvoorkeur als standaardsignaal (werkt ook zonder JS); de expliciete
   data-thema-toggle hieronder wint in beide richtingen zodra JS aanwezig is. */
@media (prefers-color-scheme: dark) {
    :root:not([data-thema="licht"]) {
        --inkt: #ececea;
        --gedimd: #9c9a9f;
        --lijn: #333238;
        --papier: #201f25;
        --achtergrond: #17161b;
        --accent: #6fa8dc;
        --accent-donker: #8fbce3;
        --accent-zacht: rgba(111, 168, 220, 0.14);
        --ok: #5cc290;
        --ok-achtergrond: rgba(92, 194, 144, 0.14);
        --fout: #e5827a;
        --fout-achtergrond: rgba(229, 130, 122, 0.14);
        --veldrand: #8a8890;
        --knop-tekst: #17161b;
        --fout-hover: #f0a29b;

        --zijbalk-bg: #131217;
        --zijbalk-lijn: #2a2930;
        --zijbalk-tekst: #b7b5bd;
        --zijbalk-tekst-actief: #ffffff;
        --zijbalk-actief-bg: #201f25;

        --schaduw-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
        --schaduw-md: 0 6px 18px rgba(0, 0, 0, 0.35);
        color-scheme: dark;
    }
}
:root[data-thema="donker"] {
    --inkt: #ececea;
    --gedimd: #9c9a9f;
    --lijn: #333238;
    --papier: #201f25;
    --achtergrond: #17161b;
    --accent: #6fa8dc;
    --accent-donker: #8fbce3;
    --accent-zacht: rgba(111, 168, 220, 0.14);
    --ok: #5cc290;
    --ok-achtergrond: rgba(92, 194, 144, 0.14);
    --fout: #e5827a;
    --fout-achtergrond: rgba(229, 130, 122, 0.14);
    --veldrand: #8a8890;
    --knop-tekst: #17161b;
    --fout-hover: #f0a29b;

    --zijbalk-bg: #131217;
    --zijbalk-lijn: #2a2930;
    --zijbalk-tekst: #b7b5bd;
    --zijbalk-tekst-actief: #ffffff;
    --zijbalk-actief-bg: #201f25;

    --schaduw-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --schaduw-md: 0 6px 18px rgba(0, 0, 0, 0.35);
    color-scheme: dark;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
    font-size: 15px;
    line-height: 1.55;
    color: var(--inkt);
    background: var(--achtergrond);
}

h1 { font-size: 1.5rem; font-weight: 600; letter-spacing: 0.01em; }
h2 { font-size: 1.1rem; font-weight: 600; }

a { color: var(--accent); }
a:hover { color: var(--accent-donker); }

code.secret {
    display: inline-block;
    padding: 0.4rem 0.6rem;
    background: var(--achtergrond);
    border: 1px solid var(--lijn);
    border-radius: 4px;
    font-size: 0.95rem;
    word-break: break-all;
}

.icoon { width: 1.15em; height: 1.15em; flex-shrink: 0; }

/* ---- App-schil: zijbalk + topbalk + inhoud ----------------------------- */

.app-schil {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
}

.zijbalk {
    width: var(--zijbalk-breedte);
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--zijbalk-bg);
    border-right: 1px solid var(--zijbalk-lijn);
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    transition: width 0.18s ease;
}
:root[data-zijbalk="dicht"] .zijbalk { width: var(--zijbalk-breedte-dicht); }

.zijbalk-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 1.1rem 1rem;
}
/* De wordmark mag nooit de wissel-knop uit de zijbalk duwen: krimpt en
   trunceert liever dan dat de knop buiten de (afgeknotte) zijbalk valt. */
.zijbalk-kop .logo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.zijbalk-kop .zijbalk-icoonknop { flex-shrink: 0; }
:root[data-zijbalk="dicht"] .zijbalk-kop { justify-content: center; }
:root[data-zijbalk="dicht"] .zijbalk-kop .logo { display: none; }

/* .zijbalk (0,1,0) + .zijbalk-icoonknop (0,1,0) = (0,2,0), bewust hoger dan
   de generieke button[type="submit"]-knopstijl (0,1,1) verderop — anders
   wint die en oogt de uitlogknop als een blauwe primaire actie-knop. */
.zijbalk .zijbalk-icoonknop {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.1rem;
    height: 2.1rem;
    padding: 0;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    color: var(--zijbalk-tekst);
    /* De uitlogknop is een <button type="submit"> (voor het formulier) en
       erft anders font-weight: 600 van de generieke .knop/button[type=submit]
       -regel verderop — die regel verliest hier wel van background/padding/
       etc. (hogere specificiteit, zie de knopstijl-comment daar), maar
       font-weight staat daar niet in overschreven, dus sijpelt door. Alleen
       zichtbaar sinds het uitklapmenu (@media 680px) er een tekstlabel naast
       zet; als icoon-only knop viel het nooit op. */
    font-weight: 400;
    cursor: pointer;
}
.zijbalk .zijbalk-icoonknop:hover { background: var(--zijbalk-actief-bg); border-color: var(--zijbalk-lijn); color: var(--zijbalk-tekst-actief); }

.zijbalk-nav { flex: 1; padding: 0.25rem 0.75rem; }
.zijbalk-nav ul { list-style: none; margin: 0 0 0.3rem; padding: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.zijbalk-nav a {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    padding: 0.4rem 0.7rem;
    border-radius: var(--radius-sm);
    color: var(--zijbalk-tekst);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
}
.zijbalk-nav a:hover { background: var(--zijbalk-actief-bg); color: var(--zijbalk-tekst-actief); }
.zijbalk-nav a.actief {
    background: var(--zijbalk-actief-bg);
    color: var(--zijbalk-tekst-actief);
    font-weight: 600;
    box-shadow: var(--schaduw-sm);
}
.zijbalk-nav a span { overflow: hidden; text-overflow: ellipsis; }
:root[data-zijbalk="dicht"] .zijbalk-nav a { justify-content: center; padding: 0.4rem; }
:root[data-zijbalk="dicht"] .zijbalk-nav a span { display: none; }

.zijbalk-groep {
    margin: 0.6rem 0 0.2rem;
    padding: 0 0.7rem;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--gedimd);
    font-weight: 600;
}
:root[data-zijbalk="dicht"] .zijbalk-groep { padding: 0; text-align: center; }
:root[data-zijbalk="dicht"] .zijbalk-groep span { display: none; }

.zijbalk-onder {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.85rem 1rem;
    border-top: 1px solid var(--zijbalk-lijn);
}
:root[data-zijbalk="dicht"] .zijbalk-onder { flex-direction: column; }
.zijbalk-uitloggen { margin: 0; margin-left: auto; }
:root[data-zijbalk="dicht"] .zijbalk-uitloggen { margin-left: 0; }

/* Tekstlabel naast thema/uitloggen-icoon — buiten het mobiele uitklapmenu
   (zie @media 680px) zijn dit overal icon-only knoppen, dus standaard uit. */
.zijbalk-actie-tekst { display: none; }

/* .zijbalk-uitklapbaar wrapt nav + onder samen (nodig om ze in één keer te
   kunnen in-/uitklappen op mobiel, zie hieronder) — op alle bredere schermen
   puur transparante doorgeefluiken, zodat .zijbalk-nav's flex: 1 nog steeds
   de ruimte tussen kop en onder opvult zoals vóór deze wrapper. */
.zijbalk-uitklapbaar,
.zijbalk-uitklapbaar-binnen {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

/* Hamburgerknop: alleen zichtbaar in de mobiele kop (zie @media 680px). */
.hamburger { display: none; }

/* .icoon.icoon-… (niet los .icoon-…): #thema-schakelaar bevat ook de
   .zijbalk-actie-tekst-labels hieronder, die dezelfde icoon-licht/icoon-donker
   -klasse hergebruiken om mee te wisselen — zonder de .icoon-eis zou deze
   ID-selector (hogere specificiteit dan .zijbalk-actie-tekst { display: none })
   die labels ook buiten het mobiele uitklapmenu tonen. */
#thema-schakelaar .icoon.icoon-donker { display: none; }
:root[data-thema="donker"] #thema-schakelaar .icoon.icoon-zon,
:root[data-thema="donker"] #thema-schakelaar .icoon.icoon-licht { display: none; }
:root[data-thema="donker"] #thema-schakelaar .icoon.icoon-donker { display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-thema="licht"]) #thema-schakelaar .icoon.icoon-licht { display: none; }
    :root:not([data-thema="licht"]) #thema-schakelaar .icoon.icoon-donker { display: block; }
}

.logo {
    font-weight: 600;
    text-decoration: none;
    color: var(--inkt);
    white-space: nowrap;
    font-size: 0.92rem;
}

.app-inhoud {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.topbalk {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 1.75rem;
    background: var(--papier);
    border-bottom: 1px solid var(--lijn);
    position: sticky;
    top: 0;
    z-index: 5;
}
.topbalk-rechts { margin-left: auto; display: flex; align-items: center; gap: 1.1rem; }
.gebruiker { color: var(--gedimd); text-decoration: none; }
.gebruiker:hover { color: var(--inkt); text-decoration: underline; }

.meldingen-menu { position: relative; }
.meldingen-icoon {
    position: relative;
    display: inline-flex;
    align-items: center;
    color: var(--inkt);
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.2rem;
}
.meldingen-icoon .icoon { width: 1.3rem; height: 1.3rem; }
.meldingen-icoon .badge {
    position: absolute;
    top: -0.3rem;
    right: -0.4rem;
    min-width: 1.1rem;
    height: 1.1rem;
    padding: 0 0.3rem;
    border-radius: 999px;
    background: var(--fout);
    color: var(--knop-tekst);
    font-size: 0.68rem;
    font-weight: 600;
    line-height: 1.1rem;
    text-align: center;
}

/* Dropdown onder het 🔔-icoon: laatste 3 meldingen + knop naar /meldingen.
   Zelfde open/dicht-patroon (klasse i.p.v. [hidden]) als .zijbalk-uitklapbaar
   hierboven — zie de klik-erbuiten/Escape-afhandeling in app.js. */
.meldingen-paneel {
    display: none;
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    width: 22rem;
    max-width: calc(100vw - 2rem);
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-md);
    z-index: 20;
    overflow: hidden;
}
.meldingen-paneel.open { display: block; }
.meldingen-paneel ul { list-style: none; margin: 0; padding: 0; }
.meldingen-paneel li + li { border-top: 1px solid var(--lijn); }
.meldingen-paneel li a {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.65rem 0.9rem;
    color: inherit;
    text-decoration: none;
}
.meldingen-paneel li a:hover { background: var(--achtergrond); }
.meldingen-paneel li strong { font-size: 0.88rem; }
.meldingen-paneel li span { font-size: 0.82rem; color: var(--gedimd); }
.meldingen-paneel li time { font-size: 0.74rem; color: var(--gedimd); }
.meldingen-item-ongelezen strong::before {
    content: "";
    display: inline-block;
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 999px;
    background: var(--accent);
    margin-right: 0.4rem;
}
.meldingen-leeg { padding: 0.9rem; color: var(--gedimd); font-size: 0.85rem; }
.meldingen-alles {
    display: block;
    text-align: center;
    padding: 0.6rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
    border-top: 1px solid var(--lijn);
}
.meldingen-alles:hover { background: var(--achtergrond); }

/* ---- Gastpagina's (uitgelogd: 403/404 e.d.) ---------------------------- */

.gast-header {
    background: var(--papier);
    border-bottom: 1px solid var(--lijn);
    padding: 0.9rem 1.5rem;
}
.gast-main { max-width: 700px; margin: 3rem auto; padding: 0 1.5rem; }

/* ---- Hoofdinhoud ------------------------------------------------------- */

main {
    /* flex: 1 laat main de resterende hoogte van .app-inhoud opvullen
       (die op zijn beurt door .app-schil's min-height: 100vh minstens een
       volledig scherm hoog is) — daardoor plakt .site-footer eronder aan de
       onderkant van het scherm bij korte pagina's, en schuift 'm gewoon mee
       naar beneden (dus uit beeld) zodra de inhoud zelf langer is dan het
       scherm. Geen position: sticky/fixed op de footer zelf nodig. */
    flex: 1;
    max-width: 1200px;
    width: 100%;
    margin: 1.75rem auto 3rem;
    padding: 0 1.75rem;
}
/* Vaste, voorspelbare ruimte tussen op-zichzelf-staande blokken direct in
   main — voorkomt dat een tabel/paneel/melding tegen het vorige element aan
   plakt, zonder dat iedere view zelf marges hoeft te regelen. */
main > * + * { margin-top: 1.5rem; }

.site-footer {
    border-top: 1px solid var(--lijn);
    color: var(--gedimd);
    font-size: 0.85rem;
    text-align: center;
    padding: 1.25rem;
}

.pagina-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}

/* Balk bovenaan op de QA-omgeving: dit is een testkopie, niet de echte administratie. */
.omgeving-banner {
    background: var(--fout);
    color: var(--knop-tekst);
    text-align: center;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0.35rem 1rem;
}

/* Een actie in de balk (support verlaten, support-instellingen): tekst in de balkkleur, onderstreept. */
.omgeving-banner form { display: inline; margin-left: 0.75rem; }
.omgeving-banner a,
.omgeving-banner .knop-link { color: inherit; text-decoration: underline; font-weight: 700; margin-left: 0.5rem; }

/* Groepje verwante pagina's onder de paginatitel (bijv. Rekeningschema, Eigen rekening toevoegen, Grootboek):
   een <nav> met een lijst links. Eén rand om het geheel, de huidige pagina gemarkeerd via aria-current. */
.pagina-menu { margin: 0.75rem 0 1.25rem; }
.pagina-menu ul {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.2rem;
    list-style: none;
    margin: 0;
    padding: 0.25rem;
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-sm);
}
.pagina-menu a {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.45rem 0.85rem;
    border-radius: var(--radius-sm);
    color: var(--inkt);
    text-decoration: none;
    font-size: 0.92rem;
}
.pagina-menu a:hover { background: var(--accent-zacht); color: var(--accent-donker); }
.pagina-menu a[aria-current="page"] { background: var(--accent-zacht); color: var(--accent-donker); font-weight: 600; }

.paneel {
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-sm);
    padding: 1.75rem;
}
.paneel.smal { max-width: 560px; }

/* CSS-only tabbladen (geen JS) voor /instellingen: verborgen radio's + een
   verticaal menu i.p.v. een horizontale tab-balk — schaalt beter naarmate er
   meer instellingen-categorieën bijkomen (een tab-balk loopt op den duur vol/
   gaat wrappen, een verticale lijst niet). De radio's moeten rechtstreekse
   kinderen van .instellingen-vorm blijven (niet genest in .instellingen-menu)
   — de ~-combinator hieronder werkt alleen tussen elementen die dezelfde
   ouder delen, en .instellingen-menu/.instellingen-inhoud zijn juist wél
   elkaars buren. Nieuw tabblad toevoegen: een radio + een label (in
   .instellingen-menu) + een paneel (in .instellingen-inhoud), en één regel
   in elk van de twee selectorlijsten hieronder. */
.instellingen-vorm {
    display: grid;
    grid-template-columns: 13rem 1fr;
    column-gap: 2rem;
    align-items: start;
}
.instellingen-vorm > input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.instellingen-menu {
    grid-column: 1;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding-right: 1.25rem;
    border-right: 1px solid var(--lijn);
}
.instellingen-menu label {
    padding: 0.55rem 0.8rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    color: var(--gedimd);
    font-size: 0.95rem;
}
.instellingen-menu label:hover { background: var(--achtergrond); color: var(--inkt); }
.instellingen-inhoud { grid-column: 2; min-width: 0; }
.instellingen-vorm > .acties { grid-column: 1 / -1; }

.tab-paneel { display: none; }

#tab-algemeen:checked ~ .instellingen-menu label[for="tab-algemeen"],
#tab-bedrijf:checked ~ .instellingen-menu label[for="tab-bedrijf"],
#tab-herkenning:checked ~ .instellingen-menu label[for="tab-herkenning"],
#tab-meldingen:checked ~ .instellingen-menu label[for="tab-meldingen"],
#tab-vergoedingen:checked ~ .instellingen-menu label[for="tab-vergoedingen"],
#tab-ib:checked ~ .instellingen-menu label[for="tab-ib"],
#tab-sjabloon:checked ~ .instellingen-menu label[for="tab-sjabloon"],
#tab-offertes:checked ~ .instellingen-menu label[for="tab-offertes"] {
    background: var(--accent-zacht);
    color: var(--accent-donker);
    font-weight: 600;
}
#tab-algemeen:checked ~ .instellingen-inhoud #paneel-algemeen,
#tab-bedrijf:checked ~ .instellingen-inhoud #paneel-bedrijf,
#tab-herkenning:checked ~ .instellingen-inhoud #paneel-herkenning,
#tab-meldingen:checked ~ .instellingen-inhoud #paneel-meldingen,
#tab-vergoedingen:checked ~ .instellingen-inhoud #paneel-vergoedingen,
#tab-ib:checked ~ .instellingen-inhoud #paneel-ib,
#tab-sjabloon:checked ~ .instellingen-inhoud #paneel-sjabloon,
#tab-offertes:checked ~ .instellingen-inhoud #paneel-offertes {
    display: block;
}

@media (max-width: 640px) {
    .instellingen-vorm { grid-template-columns: 1fr; }
    .instellingen-menu {
        grid-column: 1;
        flex-direction: row;
        flex-wrap: wrap;
        border-right: none;
        border-bottom: 1px solid var(--lijn);
        padding-right: 0;
        padding-bottom: 0.75rem;
        margin-bottom: 0.75rem;
    }
    .instellingen-inhoud { grid-column: 1; }
}

.veldgroep { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.25rem; }
.veldgroep p { min-width: 0; }

.toelichting { color: var(--gedimd); font-size: 0.9rem; }
.gedimd { color: var(--gedimd); }
.negatief { color: var(--fout); }
/* white-space: nowrap zodat "€ 1.234,56" nooit tussen het teken en het getal
   afbreekt in een smalle kolom — .rechts markeert vrijwel altijd een
   bedragkolom (zie Tabel.tsx's rechtsKolommen). */
.rechts { text-align: right; white-space: nowrap; }

.visueel-verborgen {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ---- Flash-berichten --------------------------------------------------- */

.flash {
    padding: 0.7rem 1rem;
    border-radius: var(--radius-sm);
    border: 1px solid;
}
.flash-ok { background: var(--ok-achtergrond); border-color: var(--ok); color: var(--ok); }
.flash-fout { background: var(--fout-achtergrond); border-color: var(--fout); color: var(--fout); }
/* Waarschuwing: iets om te weten na een gelukte actie (bijv. een nieuw IBAN bij een leverancier).
   Geen fout: er is niets mislukt, dus ook geen foutsamenvatting, geen focus-verplaatsing en geen
   regel in het logboek als geweigerde actie. */
.flash-waarschuwing { background: var(--accent-zacht); border-color: var(--accent); color: var(--inkt); }

/* ---- Tabellen ---------------------------------------------------------- */

table {
    width: 100%;
    border-collapse: collapse;
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-sm);
}

th, td {
    text-align: left;
    padding: 0.6rem 0.85rem;
    border-bottom: 1px solid var(--lijn);
    vertical-align: top;
}

thead th {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gedimd);
    background: var(--achtergrond);
}

tbody tr:hover { background: var(--achtergrond); }
@supports (background: color-mix(in srgb, red 4%, white)) {
    tbody tr:hover { background: color-mix(in srgb, var(--accent) 4%, var(--papier)); }
}
tfoot th, tfoot td { font-weight: 600; border-top: 2px solid var(--inkt); }

table.smal-links { max-width: 560px; }

/* Sorteerpijltjes: de <th> zelf is niet meer klikbaar maar bevat een
   .tabel-sorteer-knop (zie het toegankelijkheidsblok onderaan). De pijl volgt
   aria-sort en heeft een leeg alternatief ("/ ''"), zodat een schermlezer hem
   niet nóg eens voorleest bovenop de aria-sort-melding. */
.tabel-sorteer::after { content: ""; display: inline-block; width: 0.9em; opacity: 0.5; }
th[aria-sort="ascending"] .tabel-sorteer::after { content: "▲"; content: "▲" / ""; opacity: 1; }
th[aria-sort="descending"] .tabel-sorteer::after { content: "▼"; content: "▼" / ""; opacity: 1; }

/* ---- Kerncijfers (dashboard) ------------------------------------------ */

.kerncijfers {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1.1rem;
    margin: 0;
}

.kerncijfer {
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-sm);
    padding: 1rem 1.2rem;
}
.kerncijfer h2 {
    margin: 0;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gedimd);
    font-weight: 600;
}
.kerncijfer .bedrag { margin: 0.4rem 0 0; font-size: 1.2rem; font-weight: 600; }
.kerncijfer .vergelijking { display: block; margin: 0.3rem 0 0; font-size: 0.78rem; color: var(--gedimd); }

/* Twee kolommen breed (valt terug op 1 als het grid daar niet genoeg
   ruimte voor heeft, bijv. op smalle schermen): een "naam .... € bedrag"-
   rij heeft meer breedte nodig dan een los getal. */
.kerncijfer-lijst { grid-column: span 2; }
.kerncijfer-ranglijst { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.kerncijfer-ranglijst li { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; font-size: 0.88rem; }
.kerncijfer-ranglijst li a { color: inherit; text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kerncijfer-ranglijst li a:hover { text-decoration: underline; }
.kerncijfer-ranglijst li span { font-weight: 600; white-space: nowrap; }

.sectie-titel { margin: 1.75rem 0 1.1rem; font-size: 1rem; color: var(--gedimd); }

/* Meerjarenoverzicht: bredere/hogere tegels dan de gewone kerncijfers, elk
   met een staafdiagram — minder tegels per rij past bij de grotere inhoud. */
.kerncijfers-groot { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.kerncijfers-groot .kerncijfer { padding-bottom: 0.6rem; }

.mini-grafiek { display: block; width: 100%; height: auto; margin-top: 0.5rem; }
.mini-grafiek-nullijn { stroke: var(--lijn); stroke-width: 1; }
.mini-grafiek-staaf { fill: var(--accent); }
.mini-grafiek-staaf.negatief { fill: var(--fout); }
.mini-grafiek-label { font-size: 8px; fill: var(--gedimd); text-anchor: middle; }

/* ---- Formulieren ------------------------------------------------------- */

label { display: block; font-size: 0.85rem; color: var(--gedimd); margin-bottom: 0.25rem; }

input[type="text"], input[type="email"], input[type="password"], input[type="search"],
input[type="date"], input[type="number"], select {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--veldrand);
    border-radius: var(--radius-sm);
    font: inherit;
    background: var(--papier);
    color: var(--inkt);
}

.knop, button[type="submit"] {
    display: inline-block;
    padding: 0.55rem 1.15rem;
    background: var(--accent);
    color: var(--knop-tekst);
    border: none;
    border-radius: var(--radius-sm);
    font: inherit;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}
.knop:hover, button[type="submit"]:hover { background: var(--accent-donker); color: var(--knop-tekst); }

.vervaldatum-snel { display: inline-flex; gap: 0.5rem; margin-left: 0.5rem; }
.vervaldatum-snel .knop-link { font-size: 0.85rem; }

.knop-secundair { background: var(--gedimd); }
.knop-gevaar { background: var(--fout); }
.knop-gevaar:hover { background: var(--fout-hover); }

.knop-link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--accent);
    text-decoration: underline;
    cursor: pointer;
}
.knop-link:hover { color: var(--accent-donker); background: none; }
.knop-link-gevaar { color: var(--fout); }
.knop-link-gevaar:hover { color: var(--fout-hover); }

.inline-form { display: flex; align-items: end; gap: 0.75rem; max-width: 560px; }
.inline-form label { margin: 0; }
.inline-form input { width: 8rem; }

.kopieer-regels select { width: auto; min-width: 24rem; max-width: 100%; }

.regel-acties { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.regel-acties select { width: auto; min-width: 16rem; max-width: 100%; }
.regel-acties .scheiding { color: var(--gedimd); }

.acties { display: flex; gap: 0.7rem; align-items: center; }

/* ---- Boekingsformulier ------------------------------------------------- */

.boeking-form { background: var(--papier); border: 1px solid var(--lijn); border-radius: var(--radius-md); box-shadow: var(--schaduw-sm); padding: 1.4rem; }

.boeking-kop {
    display: flex;
    gap: 1.1rem;
    flex-wrap: wrap;
    border: none;
    padding: 0;
    margin: 0 0 1.1rem;
}
.boeking-kop p { margin: 0; min-width: 10rem; }
.boeking-kop .groei { flex: 1; }

.regels-tabel select { min-width: 12rem; }
.bedrag-invoer { width: 7rem; text-align: right; }

.regels-tabel select.regel-soort { min-width: 0; width: 5rem; }
.volgorde-cel { white-space: nowrap; }
.volgorde-cel .knop-link { text-decoration: none; font-size: 0.8rem; padding: 0 0.15rem; }

#saldo-indicator.in-evenwicht { color: var(--ok); font-weight: 600; }
#saldo-indicator.uit-evenwicht { color: var(--fout); font-weight: 600; }

.ai-test { display: flex; align-items: center; gap: 0.75rem; }
#ai-test-resultaat.bezig { color: var(--gedimd); }
#ai-test-resultaat.geslaagd { color: var(--ok); font-weight: 600; }
#ai-test-resultaat.mislukt { color: var(--fout); font-weight: 600; }

/* ---- Relaties en facturen ---------------------------------------------- */

textarea {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--veldrand);
    border-radius: var(--radius-sm);
    font: inherit;
    background: var(--papier);
    color: var(--inkt);
    resize: vertical;
}

.formulier-kolommen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1.1rem 2rem;
}
.formulier-kolommen fieldset { border: none; padding: 0; margin: 0; min-width: 0; }
.formulier-kolommen legend {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gedimd);
    font-weight: 600;
    padding: 0;
    margin-bottom: 0.5rem;
}
.formulier-kolommen p { margin: 0 0 0.9rem; }
.formulier-kolommen .acties { grid-column: 1 / -1; }

tr.inactief td { color: var(--gedimd); }
tr.melding-ongelezen td:first-child { border-left: 3px solid var(--fout); font-weight: 600; }
.iban-cel { font-size: 0.85rem; color: var(--gedimd); }

.status {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: 99px;
    font-size: 0.78rem;
    border: 1px solid var(--lijn);
    background: var(--achtergrond);
    /* Meerdere labels naast elkaar (bijv. status + "te laat") staan zonder dit
       zonder ruimte tegen elkaar aan — ook verticaal, als ze naar een tweede
       regel wrappen. */
    margin: 0.15rem 0.35rem 0.15rem 0;
}
.status-verzonden { border-color: var(--accent); color: var(--accent); background: var(--accent-zacht); }
.status-oninbaar, .status-te-laat { border-color: var(--fout); color: var(--fout); background: var(--fout-achtergrond); }

.betalingen { margin-top: 0; }
.betalingen h2 { margin-top: 0; }
.betalingen .inline-form { flex-wrap: wrap; max-width: none; align-items: end; }
.betalingen .inline-form p { margin: 0; }
.betalingen .inline-form select { width: auto; min-width: 10rem; }

.regel-ex { white-space: nowrap; }

/* ---- Bank- en creditcardmutaties --------------------------------------- */

.aansluiting {
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-left: 4px solid var(--gedimd);
    border-radius: var(--radius-sm);
    box-shadow: var(--schaduw-sm);
    padding: 0.7rem 1rem;
}
.aansluiting.sluit-aan { border-left-color: var(--ok); }
.aansluiting.sluit-niet-aan { border-left-color: var(--fout); }

.mutatie {
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-sm);
    padding: 1rem 1.2rem;
    margin-bottom: 0.9rem;
}

.mutatie-kop {
    display: flex;
    align-items: center;
    gap: 1.1rem;
    flex-wrap: wrap;
}
.mutatie-datum { color: var(--gedimd); white-space: nowrap; }
.mutatie-bedrag { font-weight: 600; white-space: nowrap; min-width: 7rem; text-align: right; }
.mutatie-tegenpartij { font-weight: 600; }
.mutatie-knoppen { margin-left: auto; display: flex; gap: 0.5rem; }
.mutatie-knoppen button { padding: 0.35rem 0.9rem; }

.mutatie-tekst {
    margin: 0.4rem 0 0;
    color: var(--gedimd);
    font-size: 0.85rem;
    word-break: break-word;
}
.mutatie .toelichting { margin: 0.4rem 0 0; }

.mutatie details { margin-top: 0.7rem; }
.mutatie summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; }
.mutatie details[open] summary { margin-bottom: 0.7rem; }

.verdeeltabel select { min-width: 11rem; width: 100%; }
.verdeeltabel td, .verdeeltabel th { padding: 0.4rem 0.5rem; }
.verdeeltabel .bedrag-invoer { width: 6.5rem; }
.rest-indicator.uit-evenwicht { color: var(--fout); font-weight: 600; }
.rest-indicator.in-evenwicht { color: var(--ok); font-weight: 600; }

.onthouden label { display: inline; }
.onthouden input[type="text"] { margin-top: 0.3rem; }

/* ---- Btw-aangifte ------------------------------------------------------ */

.status-ingediend { border-color: var(--ok); color: var(--ok); background: var(--ok-achtergrond); }

.aangifte-tabel { margin-bottom: 0; }
.aangifte-tabel th[scope="row"] { width: 3rem; color: var(--gedimd); font-weight: 600; }
.aangifte-tabel tr.rubriek-leeg td, .aangifte-tabel tr.rubriek-leeg th { color: var(--gedimd); }
.aangifte-tabel tfoot td, .aangifte-tabel tfoot th { border-top: none; }
.aangifte-tabel tfoot tr:first-child td, .aangifte-tabel tfoot tr:first-child th { border-top: 2px solid var(--inkt); }
.aangifte-tabel tr.aangifte-saldo td, .aangifte-tabel tr.aangifte-saldo th {
    border-top: 1px solid var(--inkt);
    font-size: 1.05rem;
}

.specificatie { margin-top: 2rem; }
.specificatie summary { cursor: pointer; color: var(--accent); }
.specificatie h3 { font-size: 0.95rem; margin: 1.4rem 0 0.5rem; }

/* ---- Filterbalk -------------------------------------------------------- */

.filterbalk {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin: 0;
}
.filterbalk a {
    /* Bewust compact/klein gehouden — de pillen zijn secundaire navigatie,
       geen invoervelden, en hoeven dus niet dezelfde hoogte als het zoekveld
       ernaast te hebben. flex-shrink: 0 voorkomt dat een pil in een krappe
       (bijv. mobiele) rij ineendrukt tot de tekst binnenin gaat afbreken —
       dan liever laten wrappen naar een nieuwe regel (of scrollen, zie
       .mutaties-filterbalken) dan een ingedrukte pil met knipperende tekst. */
    flex-shrink: 0;
    padding: 0.3rem 0.7rem;
    border: 1px solid var(--lijn);
    border-radius: 99px;
    text-decoration: none;
    color: var(--inkt);
    background: var(--papier);
    font-size: 0.8rem;
}
.filterbalk a[aria-current="page"] {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--knop-tekst);
}

/* ---- Paginakop + werkbalk (React-eilanden) ----------------------------- */
/* Titel + "Nieuwe …"-knop, en de hoofdfilter/zoekveld op één samengevoegde
   rij eronder — i.p.v. titel, filterbalk en zoekveld als drie losse,
   los-vast-aanvoelende blokken. Zie frontend/src/lib/PaginaHeader.tsx. */

.tabel-koptekst {
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    box-shadow: var(--schaduw-sm);
    padding: 1.1rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.tabel-koptekst .pagina-kop { gap: 1rem; }
.tabel-koptekst h1 { margin: 0; }
/* Titelregel-acties naast elkaar, bijv. Mutaties' "Codeerregels"-link vóór
   de "Importeren"-knop (PaginaHeader's extraKnop-prop). */
.pagina-kop-acties { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }

.tabel-werkbalk {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
}
.tabel-werkbalk .filterbalk { flex: 1; min-width: 0; }

.tabel-zoekveld-wrap { display: block; }
.tabel-zoekveld { width: 22rem; max-width: 100%; }

/* Mutaties heeft twee filterdimensies (dagboek + status) i.p.v. één, dus
   samen in één werkbalk-kind zodat ze als groep tegenover het zoekveld staan
   — zie frontend/src/pages/mutaties/FilterBalk.tsx. Elke groep (.filterbalk)
   wrapt intern gewoon mee zoals overal, dat is prima; wat niet moet, is
   pillen laten samendrukken (zie .filterbalk a's flex-shrink: 0 hierboven). */
.tabel-werkbalk .mutaties-filterbalken {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
}
/* .tabel-werkbalk .filterbalk (hierboven) is bedoeld voor de andere pagina's,
   met precies één filterbalk die de rúimte naast het zoekveld deelt. Diezelfde
   descendant-selector raakt via .mutaties-filterbalken ook deze twee geneste
   filterbalken — flex: 1 duwt ze dan allebei naar exact 50% breedte, ongeacht
   hoeveel pillen erin zitten. Zodra dat te smal wordt voor de langste pil (die
   dankzij flex-shrink: 0 niet kleiner mag), loopt hij over zijn eigen kolom
   heen, over de buurgroep. flex: initial laat elke groep gewoon zijn eigen
   inhoud volgen en op de rij wrappen zoals de rest van de pagina. */
.mutaties-filterbalken .filterbalk { flex: initial; min-width: auto; }
.mutaties-zoekform { display: flex; align-items: center; gap: 0.5rem; }
/* Smaller dan de 22rem van andere pagina's: hier staat ook nog een eigen
   "Zoeken"-knop naast het veld (serverside zoeken i.p.v. live filter), dus
   evenveel breedte gunnen als bijv. Debiteuren laat de dagboek-/statuspillen
   ernaast te weinig ruimte over en duwt ze voortijdig naar een nieuwe regel. */
.mutaties-zoekform .tabel-zoekveld { width: 14rem; }

/* ---- Jaarrekening & jaarafsluiting -------------------------------------- */

/* Balans en V&W lezen als twee kolommen naast elkaar (activa | passiva,
   omzet | kosten); onder de 900px-breekpunt hieronder stapelen ze. */
.jaarrekening-balans {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.25rem;
    align-items: start;
}
.jaarrekening-balans table { margin: 0; }

.jr-groepkop th { padding-top: 0.9rem; color: var(--gedimd); font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.04em; }
.jr-subtotaal th, .jr-subtotaal td { border-top: 1px solid var(--lijn); font-weight: 600; }
.jr-resultaat th, .jr-resultaat td { font-weight: 600; }

/* Eén smalle kolommenset: dit is een rekensom, geen brede gegevenstabel. */
.ib-berekening { max-width: 34rem; }
.ib-berekening .jr-resultaat th,
.ib-berekening .jr-resultaat td { border-top: 2px solid var(--lijn); }

@media (max-width: 900px) {
    .jaarrekening-balans { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
    /* Zonder dit staat "Codeerregels" verticaal gecentreerd tegenover de hele
       (op smalle schermen best hoge) pillenkolom hiernaast — bovenaan
       uitlijnen oogt veel natuurlijker naast een blok dat inmiddels hoger is
       dan breed. */
    .tabel-werkbalk { align-items: flex-start; }
    .mutaties-zoekform { width: 100%; }
    .mutaties-zoekform .tabel-zoekveld { flex: 1; width: auto; }
}

/* Binnen een React-eiland (één mount-div, dus geen "main > * + *"-buren)
   krijgen alle rechtstreekse blokken toch de vaste tussenruimte. */
.pagina-inhoud > * + * { margin-top: 1.5rem; }

/* ---- Inlogpagina's ----------------------------------------------------- */

.auth-pagina {
    display: grid;
    place-items: center;
    min-height: 100vh;
    background: var(--achtergrond);
}

.auth-kaart {
    width: min(92vw, 380px);
    background: var(--papier);
    border: 1px solid var(--lijn);
    border-radius: var(--radius-lg);
    box-shadow: var(--schaduw-md);
    padding: 2.25rem;
}
.auth-kaart h1 {
    font-size: 1.1rem;
    letter-spacing: 0.25em;
    text-align: center;
    margin-top: 0;
}
.auth-kaart h1 span { color: var(--gedimd); font-weight: 400; }
.auth-kaart button { width: 100%; }

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

@media (max-width: 900px) {
    :root { --zijbalk-breedte: var(--zijbalk-breedte-dicht); }
    .zijbalk-kop { justify-content: center; }
    .zijbalk-kop .logo { display: none; }
    .zijbalk-nav a { justify-content: center; padding: 0.55rem; }
    .zijbalk-nav a span, .zijbalk-groep { display: none; }
    .zijbalk-onder { flex-direction: column; }
    main { padding: 0 1.1rem; }
    .topbalk { padding: 0.75rem 1.1rem; }
}

/* Op telefoonbreedte is een smalle, altijd-zichtbare linkerkolom (zelfs
   icoon-only, hierboven) nog steeds kostbare breedte die de inhoud niet
   heeft, en een horizontale iconenrij is geen echt menu — je ziet nergens een
   label. Daarom hier een compacte kopbalk (logo + hamburger) met daaronder
   een verticaal uitklapmenu: dezelfde nav-markup uit layout.php, nu gewoon
   weer een lijst met icoon + label, plus thema-wissel en uitloggen als
   volwaardige menuregels onderaan (zie .zijbalk-onder hieronder). */
@media (max-width: 680px) {
    .app-schil { flex-direction: column; min-height: auto; }
    .zijbalk {
        /* position: sticky (elke waarde ≠ static doet dat) maakt dit meteen
           het ankerpunt voor .zijbalk-uitklapbaar hieronder, dat als los
           paneel over de pagina heen valt (position: absolute) i.p.v. de
           documentstroom te duwen — anders blijft een sticky element dat zelf
           een volle beeldschermhoogte in beslag neemt de hele tijd dat het
           openstaat de rest van de pagina onbereikbaar blokkeren. */
        position: sticky;
        top: 0;
        z-index: 20;
        width: 100%;
        height: auto;
        flex-direction: column;
        border-right: none;
        border-bottom: 1px solid var(--zijbalk-lijn);
        /* De basisregel hierboven zet overflow-y: auto voor de volle-hoogte
           desktoprail — op mobiel is .zijbalk zelf nog maar de compacte
           kopbalk, en die overflow zou het uitklappaneel hieronder (position:
           absolute, buiten de documentstroom) afknippen zodra het onder de
           rand van die korte kopbalk uitsteekt. */
        overflow: visible;
    }
    .zijbalk-kop { padding: 0.65rem 0.9rem; }
    .zijbalk-kop .logo { display: block; }
    /* De desktop in-/uitklapknop (icoon-only rail ↔ volle breedte) heeft op
       een telefoon niets om in te klappen — die rol neemt de hamburger over. */
    #zijbalk-schakelaar { display: none; }
    .hamburger {
        display: inline-flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 5px;
        width: 2.3rem;
        height: 2.3rem;
        flex-shrink: 0;
        padding: 0;
        background: none;
        border: 1px solid transparent;
        border-radius: var(--radius-sm);
        cursor: pointer;
    }
    .hamburger:hover { background: var(--zijbalk-actief-bg); border-color: var(--zijbalk-lijn); }
    .hamburger-lijn {
        display: block;
        width: 1.3rem;
        height: 2px;
        border-radius: 2px;
        background: var(--zijbalk-tekst);
        transition: transform 0.22s ease, opacity 0.15s ease;
    }
    /* Hamburger → kruisje, aangestuurd door aria-expanded — geen aparte
       open/dicht-CSS-klasse nodig voor de knop zelf. */
    .hamburger[aria-expanded="true"] .hamburger-lijn:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    .hamburger[aria-expanded="true"] .hamburger-lijn:nth-child(2) { opacity: 0; }
    .hamburger[aria-expanded="true"] .hamburger-lijn:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

    /* Het uitklapbare paneel valt als los blok óver de pagina heen (position:
       absolute, geen normale-documentstroom-ruimte), vlak onder de kopbalk —
       .zijbalk erboven is het ankerpunt (position: sticky telt daarvoor ook
       mee). Dicht: onzichtbaar én niet-klikbaar (visibility, niet alleen
       opacity, anders blijven de links eronder "aanwezig" voor toetsenbord/
       muis terwijl je ze niet ziet). */
    .zijbalk-uitklapbaar {
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        max-height: calc(100vh - 3.6rem);
        overflow-y: auto;
        background: var(--zijbalk-bg);
        border-bottom: 1px solid var(--zijbalk-lijn);
        box-shadow: var(--schaduw-md);
        visibility: hidden;
        opacity: 0;
        transform: translateY(-6px);
        transition: opacity 0.18s ease, transform 0.18s ease, visibility 0s linear 0.18s;
    }
    .zijbalk-uitklapbaar.open {
        visibility: visible;
        opacity: 1;
        transform: translateY(0);
        transition: opacity 0.18s ease, transform 0.18s ease;
    }

    .zijbalk-nav { padding: 0.3rem 0.75rem 0.5rem; }
    .zijbalk-nav ul { flex-direction: column; }
    /* De @media 900px hierboven (tablet: icoon-only rail) zet justify-
       content: center — geldt hier ook mee (beide media queries matchen
       tegelijk op telefoonbreedte), dus expliciet terugzetten naar links. */
    .zijbalk-nav a { justify-content: flex-start; padding: 0.75rem 0.8rem; }
    .zijbalk-nav a span { display: inline; }

    .zijbalk-onder {
        flex-direction: column;
        align-items: stretch;
        gap: 0.15rem;
        padding: 0.5rem 0.75rem 0.85rem;
    }
    .zijbalk-uitloggen { margin: 0; }
    /* Thema/uitloggen waren vaste vierkante icoonknoppen (2.1×2.1rem) — in
       het uitklapmenu worden het volle-breedte menuregels met zichtbaar
       label (.zijbalk-actie-tekst, zie hierboven), net als de nav erboven. */
    .zijbalk-onder .zijbalk-icoonknop {
        width: 100%;
        height: auto;
        justify-content: flex-start;
        gap: 0.8rem;
        padding: 0.75rem 0.8rem;
    }
    .zijbalk-actie-tekst { display: inline; }
    /* Van de twee thema-labels hoort er hier maar één zichtbaar te zijn:
       "Donker thema" in het lichte thema (klikken schakelt naar donker),
       "Licht thema" in het donkere thema — zelfde wissel-logica als de
       zon-/maan-iconen hierboven, alleen dan voor de tekst. */
    .zijbalk-actie-tekst.icoon-donker { display: none; }
    :root[data-thema="donker"] .zijbalk-actie-tekst.icoon-licht { display: none; }
    :root[data-thema="donker"] .zijbalk-actie-tekst.icoon-donker { display: inline; }

    /* De boekjaarwissel/meldingen/naam-balk mag met de inhoud meescrollen —
       alleen de navigatie zelf hoeft op een telefoon permanent bereikbaar. */
    .topbalk { position: static; }
    main { padding: 0 1rem; }
}

/* ---- Onboarding-wizard (nieuwe administratie) -------------------------- */

.paneel.wizard { max-width: 760px; }

.wizard-stappen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.2rem;
    list-style: none;
    margin: 0 0 1.4rem;
    padding: 0;
    font-size: 0.85rem;
    color: var(--gedimd);
}
.wizard-stappen li a, .wizard-stappen li > span { display: inline-flex; align-items: center; gap: 0.4rem; color: inherit; text-decoration: none; }
.wizard-stappen a:hover { color: var(--accent); }
.wizard-stappen .nr {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    border: 1px solid var(--lijn);
    font-size: 0.75rem;
}
.wizard-stappen .klaar .nr { background: var(--ok-achtergrond); border-color: var(--ok); color: var(--ok); }
.wizard-stappen .huidig { color: var(--inkt); font-weight: 600; }
.wizard-stappen .huidig .nr { background: var(--accent); border-color: var(--accent); color: var(--knop-tekst); }

.wizard-velden {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.2rem 1.4rem;
}
.wizard-velden p { margin: 0 0 0.9rem; }
.wizard-velden .volle-breedte { grid-column: 1 / -1; }
.wizard-velden p.toelichting { margin-top: -0.5rem; }
@media (max-width: 560px) { .wizard-velden { grid-template-columns: 1fr; } }

.wizard-keuzes { display: grid; gap: 0.7rem; margin-bottom: 1rem; }
label.kaart, label.keuze {
    display: flex;
    gap: 0.75rem;
    align-items: flex-start;
    color: var(--inkt);
    font-size: 0.95rem;
    cursor: pointer;
}
label.kaart {
    padding: 0.85rem 1rem;
    border: 1px solid var(--lijn);
    border-radius: var(--radius-md);
    background: var(--papier);
}
label.kaart:hover { border-color: var(--accent); }
label.kaart:has(input:checked) { border-color: var(--accent); background: var(--accent-zacht); }
label.kaart input, label.keuze input { margin-top: 0.25rem; flex: none; }
.kaart-tekst { display: flex; flex-direction: column; gap: 0.15rem; }
.kaart-tekst span { font-size: 0.85rem; color: var(--gedimd); }

.wizard-tabel { width: 100%; margin-bottom: 0.5rem; }
.wizard-tabel td, .wizard-tabel th { padding: 0.3rem 0.4rem; vertical-align: middle; }
.wizard-tabel .bedrag-invoer { width: 7.5rem; }
.wizard-tabel select { min-width: 8.5rem; }

.wizard-samenvatting {
    display: grid;
    grid-template-columns: minmax(9rem, 14rem) 1fr;
    gap: 0.6rem 1.2rem;
    margin: 0 0 1.2rem;
}
.wizard-samenvatting dt { color: var(--gedimd); font-size: 0.85rem; }
.wizard-samenvatting dd { margin: 0; }
.wizard-lijst { list-style: none; margin: 0; padding: 0; }
.wizard-database { border: 1px solid var(--lijn); border-radius: var(--radius-md); padding: 1rem 1.2rem; margin: 0 0 1.2rem; }
.wizard-acties { margin-top: 1.4rem; justify-content: space-between; }

/* ---- Actielogboek (superadmin) ----------------------------------------- */

.logboek-tabs { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
.logboek-tabs a {
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--lijn);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--gedimd);
    font-size: 0.9rem;
    background: var(--papier);
}
.logboek-tabs a.actief { border-color: var(--accent); background: var(--accent-zacht); color: var(--inkt); font-weight: 600; }

.logboek-filters {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0.2rem 1.2rem;
    margin-bottom: 1.2rem;
}
.logboek-filters p { margin: 0 0 0.9rem; }
.logboek-filters .acties { grid-column: 1 / -1; }

.logboek-vlag {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.4rem;
    border-radius: var(--radius-sm);
    background: var(--accent-zacht);
    color: var(--accent);
    font-size: 0.72rem;
}
.logboek-tabelnaam { font-size: 0.85rem; color: var(--gedimd); margin: 1.2rem 0 0.4rem; font-weight: 600; }
.logboek-diff { margin-bottom: 0.8rem; }
.logboek-diff caption { text-align: left; font-size: 0.8rem; padding-bottom: 0.3rem; }
.logboek-diff .logboek-voor { color: var(--fout); }
.logboek-diff .logboek-na { color: var(--ok); }
.logboek-paginering { justify-content: space-between; max-width: 28rem; }

/* ---- Vertalingen (superadmin) ------------------------------------------ */

.vertalingen-tabel { table-layout: fixed; width: 100%; }
.vertalingen-tabel td { vertical-align: top; }
.vertalingen-tabel textarea {
    width: 100%;
    min-height: 2.2rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--veldrand);
    border-radius: var(--radius-sm);
    font: inherit;
    background: var(--papier);
    color: var(--inkt);
    resize: vertical;
}
.vertalingen-sleutel { width: 22%; }
.vertalingen-sleutel code { font-size: 0.8rem; word-break: break-all; }
.vertalingen-bron { width: 26%; font-size: 0.85rem; }
.vertalingen-actie { width: 9rem; font-size: 0.82rem; text-align: right; }
.vertalingen-drift { margin: 0.35rem 0 0; font-size: 0.8rem; }
.vlag-let-op { background: var(--fout-achtergrond); color: var(--fout); }
.vlag-gedimd { background: var(--achtergrond); color: var(--gedimd); }
.verborgen { display: none; }

@media (max-width: 860px) {
    .vertalingen-tabel, .vertalingen-tabel tbody, .vertalingen-tabel tr, .vertalingen-tabel td { display: block; width: auto; }
    .vertalingen-tabel thead { display: none; }
    .vertalingen-tabel tr { border-bottom: 1px solid var(--lijn); padding: 0.6rem 0; }
    .vertalingen-actie { text-align: left; }
}

/* ---- Toegankelijkheid (WCAG 2.2 AA) ------------------------------------ */
/* Achtergrond en plan: docs/toegankelijkheid.md. */

/* Geplakte topbalk (± 3,5rem) mag een gefocust element of een sprongdoel
   nooit bedekken (2.4.11). scroll-padding geldt ook voor focus-scrollen. */
html { scroll-padding-top: 5rem; }

/* -- Toetsenbordfocus ------------------------------------------------------
   Naar het voorbeeld van GOV.UK, in beide thema's identiek:
   · links        gele achtergrond, zwarte tekst, 3px zwarte onderstreping
   · knoppen      gele achtergrond, zwarte tekst, 2px zwarte rand
   · invoervelden veld blijft wit: gele ring van 3px + 2px zwarte binnenrand
   Alleen :focus-visible, dus een muisklik kleurt niets geel (tekstvelden: zie de muis-uitzondering hieronder).
   !important op links en knoppen: veel bestaande regels (actief-menu-item,
   hover, .knop-secundair…) zetten zelf achtergrond/kleur met een hogere
   specificiteit, en de focusstijl mag door niets overruled worden.
   outline: 3px solid transparent blijft in Windows-hoog-contrastmodus
   zichtbaar, waar box-shadow en achtergrond wegvallen. */

/* Links en link-achtige besturing (knop-in-tekst, sorteerkop, samenvatting). */
a:not(.knop):focus-visible,
.knop-link:focus-visible,
.tabel-sorteer:focus-visible,
summary:focus-visible {
    outline: 3px solid transparent !important;
    color: var(--focus-lijn) !important;
    background-color: var(--focus-bg) !important;
    box-shadow: 0 -2px var(--focus-bg), 0 3px var(--focus-lijn) !important;
    text-decoration: none !important;
}
/* Kinderen met een eigen (grijze/blauwe) kleur, bijv. de subregels in het
   meldingenpaneel, mogen op geel niet onleesbaar worden. */
a:not(.knop):focus-visible *,
.knop-link:focus-visible *,
.tabel-sorteer:focus-visible * { color: var(--focus-lijn) !important; }

/* Knoppen — ook de icoonknoppen (zijbalk, meldingen, hamburger) en <a class="knop">. */
.knop:focus-visible,
button:not(.knop-link):not(.tabel-sorteer):focus-visible,
input[type="submit"]:focus-visible,
input[type="button"]:focus-visible {
    outline: 3px solid var(--focus-bg) !important;
    outline-offset: 0 !important;
    color: var(--focus-lijn) !important;
    background-color: var(--focus-bg) !important;
    box-shadow: inset 0 0 0 2px var(--focus-lijn) !important;
    text-decoration: none !important;
}
.hamburger:focus-visible .hamburger-lijn { background: var(--focus-lijn); }

/* Tekstvelden, keuzelijsten, tekstvlakken. */
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 3px solid var(--focus-bg);
    outline-offset: 0;
    border-color: var(--focus-lijn);
    box-shadow: inset 0 0 0 2px var(--focus-lijn);
}

/* Met de muis in een veld geklikt (app.js zet html[data-invoer="muis"]): geen gele ring. Een tekstveld matcht :focus-visible
   ook bij een klik, dus zonder deze regel verscheen de toetsenbordfocus ook voor muisgebruikers. Het veld blijft herkenbaar aan
   een gekleurde rand en de tekstcursor. Alleen tekstvelden, keuzelijsten en tekstvlakken: links en knoppen krijgen bij een klik
   sowieso geen :focus-visible. Met Tab (data-invoer="toetsenbord") of zonder JS geldt de gele ring hierboven. */
html[data-invoer="muis"] input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):focus-visible,
html[data-invoer="muis"] select:focus-visible,
html[data-invoer="muis"] textarea:focus-visible {
    outline: none !important;
    box-shadow: none !important;
    border-color: var(--accent);
}

/* Aanvinkvakjes en keuzerondjes: de ring staat buiten het (kleine) vakje. */
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible {
    outline: 3px solid var(--focus-bg);
    outline-offset: 2px;
    box-shadow: 0 0 0 2px var(--focus-lijn);
}
/* De keuzekaarten van de wizard: de hele kaart licht op, niet alleen het rondje. */
label.kaart:has(input:focus-visible) {
    outline: 3px solid var(--focus-bg);
    outline-offset: 0;
    box-shadow: inset 0 0 0 2px var(--focus-lijn);
}
/* De tabbladen van /instellingen zijn radio's met opacity 0: de focus moet
   op het bijbehorende label zichtbaar zijn. Nieuw tabblad = één regel erbij. */
#tab-algemeen:focus-visible ~ .instellingen-menu label[for="tab-algemeen"],
#tab-bedrijf:focus-visible ~ .instellingen-menu label[for="tab-bedrijf"],
#tab-herkenning:focus-visible ~ .instellingen-menu label[for="tab-herkenning"],
#tab-meldingen:focus-visible ~ .instellingen-menu label[for="tab-meldingen"],
#tab-vergoedingen:focus-visible ~ .instellingen-menu label[for="tab-vergoedingen"],
#tab-ib:focus-visible ~ .instellingen-menu label[for="tab-ib"],
#tab-sjabloon:focus-visible ~ .instellingen-menu label[for="tab-sjabloon"],
#tab-offertes:focus-visible ~ .instellingen-menu label[for="tab-offertes"] {
    outline: 3px solid transparent;
    color: var(--focus-lijn);
    background-color: var(--focus-bg);
    box-shadow: 0 -2px var(--focus-bg), 0 3px var(--focus-lijn);
}
.instellingen-vorm > input[type="radio"]:focus-visible { box-shadow: none; outline: none; }

/* Sprongdoelen (tabindex="-1", bereikt via een skiplink of na een foutmelding)
   zijn geen tabstop, dus 2.4.7 geldt er niet voor — maar een rustige rand laat
   wel zien waar je bent geland. */
[tabindex="-1"]:focus { outline: none; }
[tabindex="-1"]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

/* -- Skiplinks -------------------------------------------------------------
   .skiplinks: de balk boven aan elke pagina; visueel verborgen tot een van de
   links focus krijgt (:focus-within), níet display: none — dan zijn ze niet
   focusbaar. .toon-bij-focus: dezelfde techniek voor één losse link (tabel
   overslaan, terug naar het menu) die in de gewone stroom komt te staan. */
.skiplinks {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.75rem;
    padding: 0.85rem 1.75rem;
    background: var(--papier);
    border-bottom: 3px solid var(--focus-bg);
    font-weight: 600;
}
.skiplinks:not(:focus-within) {
    right: auto;
    width: 1px; height: 1px;
    padding: 0; border: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.toon-bij-focus:not(:focus):not(:active) {
    position: absolute;
    width: 1px; height: 1px;
    margin: 0; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.toon-bij-focus { display: inline-block; margin: 0.4rem 0; }
.tabel-einde { height: 0; }

/* -- Sorteerbare tabelkoppen: een echte knop i.p.v. een klikbare <th> ------- */
.tabel-sorteer {
    display: block;
    width: 100%;
    margin: 0;
    padding: 0.6rem 0.85rem;
    border: 0;
    background: none;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    text-align: inherit;
    color: inherit;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.tabel-sorteer:hover { color: var(--inkt); }
th:has(> .tabel-sorteer) { padding: 0; }

/* -- Brede tabellen scrollen in hun eigen vak i.p.v. de pagina (1.4.10) ---- */
.tabel-scroll { overflow-x: auto; max-width: 100%; }

/* -- Doelgrootte (2.5.8: minstens 24×24 px) ------------------------------- */
td .knop-link, .regel-acties .knop-link, .acties .knop-link {
    display: inline-flex;
    align-items: center;
    min-height: 1.5rem;
}
.volgorde-cel .knop-link {
    justify-content: center;
    min-width: 1.5rem;
    min-height: 1.5rem;
}

/* -- Formulierfouten (3.3.1) -------------------------------------------- */
[aria-invalid="true"] { border-color: var(--fout); box-shadow: inset 0 0 0 1px var(--fout); }
.veld-fout { display: block; margin-top: 0.25rem; color: var(--fout); font-weight: 600; font-size: 0.9rem; }

/* -- Minder beweging (2.3.3, wel gewenst) --------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        /* 0s en niet 0.01ms: een transitie van een fractie is nog steeds één
           frame lang, en juist op visibility (het mobiele menu) is dat het
           verschil tussen "focusbaar" en "nog niet focusbaar". */
        transition-duration: 0s !important;
        transition-delay: 0s !important;
        scroll-behavior: auto !important;
    }
}

/* Compacte verzendknop naast de boekjaar-/administratiekeuze in de topbalk. */
.knop-compact { padding: 0.35rem 0.8rem; font-size: 0.85rem; }

/* Boekjaar-/administratiewissel in de topbalk: keuzelijst + knop op één rij. */
.boekjaar-form { display: flex; align-items: center; gap: 0.4rem; margin: 0; }
.boekjaar-form select { width: auto; }

/* Op een telefoon past maar één kerncijfer-kolom; "span 2" zou een tweede
   (impliciete) kolom aanmaken en de pagina horizontaal laten scrollen (1.4.10). */
@media (max-width: 380px) {
    .kerncijfer-lijst { grid-column: 1 / -1; }
}

/* Het zoekveld naast de "Zoeken"-knop mag krimpen (een <input> heeft anders een
   vaste minimumbreedte en duwt de knop buiten een smal scherm, 1.4.10). */
.mutaties-zoekform .tabel-zoekveld { min-width: 0; }

/* Foutsamenvatting: de ene, gedeelde weergave van foutmeldingen (helpers.php
   render_fouten(), frontend/src/lib/Meldingen.tsx en app.js). */
.foutsamenvatting { border-left-width: 6px; }
.foutsamenvatting h2 { margin: 0; font-size: 1.05rem; }
.foutsamenvatting ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.foutsamenvatting a { color: inherit; }
/* Altijd aanwezige, meestal lege live region van de React-eilanden: geen
   ruimte innemen zolang er niets in staat, maar wél in de toegankelijkheidsboom
   blijven (display: none zou de live region weghalen, en een melding die dan
   pas verschijnt wordt door schermlezers vaak niet voorgelezen). */
.melding-regio:empty { margin: 0; height: 0; overflow: hidden; }

/* Links in lopende tekst moeten méér dan alleen een kleurverschil hebben
   (1.4.1): de Tailwind-preflight in de React-eilanden haalt de standaard-
   onderstreping weg. :where() houdt de specificiteit op nul, dus elke
   bewuste text-decoration: none (menu, knoppen, ranglijsten) blijft winnen. */
:where(main p, main li, main dd) a:where(:not(.knop)) { text-decoration: underline; }

/* Snelkeuze +7/+14/+30 dagen naast de vervaldatum (2.5.8). */
.vervaldatum-snel .knop-link { display: inline-flex; align-items: center; justify-content: center; min-width: 1.5rem; min-height: 1.5rem; }

/* In een smalle tabelcel (regeltabellen) krijgt de melding meer ruimte door compacter te zijn. */
td .veld-fout { font-size: 0.8rem; line-height: 1.3; }
