/* =====================================================================
   Cursistenportal — design system
   Strak, modern, rustig. Systeem-fonts, veel witruimte, zachte schaduwen.
   ===================================================================== */

:root {
    --bg:            #f4f5f7;
    --surface:       #ffffff;
    --surface-2:     #fafbfc;
    --border:        #e6e8ec;
    --border-strong: #d3d7de;

    --text:          #1a1d23;
    --text-soft:     #5b616e;
    --text-faint:    #8b93a1;

    --brand:         #4f46e5;   /* indigo */
    --brand-600:     #4338ca;
    --brand-50:      #eef0fe;
    --brand-ink:     #ffffff;

    --success-bg:    #e7f7ee;  --success-tx: #0f7a43;  --success-bd: #b6e6cb;
    --error-bg:      #fdecec;  --error-tx:   #b3261e;  --error-bd:   #f5c6c3;
    --info-bg:       #eef2ff;  --info-tx:    #3949ab;  --info-bd:    #cdd6ff;
    --warn-bg:       #fff4e0;  --warn-tx:    #8a5200;  --warn-bd:    #f0d5a4;

    --radius:        14px;
    --radius-sm:     10px;
    --shadow-sm:     0 1px 2px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.10);
    --shadow-md:     0 4px 12px rgba(16,24,40,.08), 0 12px 32px rgba(16,24,40,.08);
    --shadow-lg:     0 18px 50px rgba(16,24,40,.16);

    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue",
            Arial, "Noto Sans", sans-serif;
    --sidebar-w: 264px;
    --sidebar-w-smal: 76px;
    --impbar-h:  34px;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg:            #0f1115;
        --surface:       #171a21;
        --surface-2:     #1d212a;
        --border:        #262b36;
        --border-strong: #333a48;
        --text:          #eef0f4;
        --text-soft:     #a7aebc;
        --text-faint:    #737b8a;
        --brand:         #7c73ff;
        --brand-600:     #6a60f5;
        --brand-50:      #20233a;
        --success-bg:#12291d; --success-tx:#7ee2ac; --success-bd:#1f4a33;
        --error-bg:  #2c1615; --error-tx:  #f5a29c; --error-bd:  #4d2723;
        --info-bg:   #191d33; --info-tx:   #a9b6ff; --info-bd:   #2c3560;
        --warn-bg:   #2c2113; --warn-tx:   #f0c98a; --warn-bd:   #4e3a1d;
        --shadow-lg: 0 18px 50px rgba(0,0,0,.55);
    }
}

* { box-sizing: border-box; }

/* De browser verbergt [hidden] met display:none, maar dat is een regel op een
   attribuut: elke klasse hieronder die zelf een display meegeeft (flex, grid)
   wint daarvan en zet het element weer aan. Vandaar hier één regel die vóór
   gaat — anders staat een blok dat als hidden begint meteen in beeld. */
[hidden] { display: none !important; }

html, body { height: 100%; }

body {
    margin: 0;
    font-family: var(--font);
    color: var(--text);
    background: var(--bg);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3 { margin: 0; line-height: 1.2; letter-spacing: -.01em; }
a { color: inherit; }

/* ---------------------------------------------------------------- Brand */
.brand-mark {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 11px;
    background: linear-gradient(135deg, var(--brand), var(--brand-600));
    color: var(--brand-ink); font-weight: 700; font-size: .82rem;
    letter-spacing: .02em; box-shadow: var(--shadow-sm);
}
.brand-mark--lg { width: 52px; height: 52px; border-radius: 14px; font-size: 1rem; }

/* ============================================================= AUTH view */
.is-auth {
    display: grid; place-items: center; min-height: 100vh; padding: 24px;
    background:
        radial-gradient(1100px 520px at 15% -10%, var(--brand-50), transparent 60%),
        radial-gradient(900px 500px at 100% 110%, var(--brand-50), transparent 55%),
        var(--bg);
}
.auth-wrap { width: 100%; max-width: 420px; }
.auth-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
    padding: 38px 34px 34px;
}
.auth-card__head {
    display: flex; flex-direction: column; align-items: center; gap: 14px;
    margin-bottom: 22px; text-align: center;
}
.auth-card__head h1 { font-size: 1.18rem; font-weight: 650; }
.auth-title { font-size: 1.5rem; font-weight: 680; margin-bottom: 4px; }
.auth-sub { color: var(--text-soft); font-size: .93rem; margin: 0 0 22px; }
.auth-alt { text-align: center; margin: 20px 0 0; font-size: .9rem; }
.auth-foot { text-align: center; color: var(--text-faint); font-size: .8rem; margin: 20px 0 0; }

/* ================================================================= Forms */
.form { display: flex; flex-direction: column; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field__label { font-size: .82rem; font-weight: 600; color: var(--text-soft); }
.field__hint { font-size: .78rem; color: var(--text-faint); line-height: 1.4; }

input[type=email], input[type=password], input[type=text], input[type=tel] {
    width: 100%; padding: 12px 14px;
    font: inherit; color: var(--text);
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    transition: border-color .15s, box-shadow .15s, background .15s;
}
input::placeholder { color: var(--text-faint); }
input:focus {
    outline: none; background: var(--surface);
    border-color: var(--brand);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}

.form__row {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap; font-size: .88rem;
}
.checkbox { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; color: var(--text-soft); }
.checkbox input { width: 16px; height: 16px; accent-color: var(--brand); }

.link { color: var(--brand); text-decoration: none; font-weight: 550; }
.link:hover { text-decoration: underline; }

/* ============================================================== Buttons */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    padding: 12px 18px; font: inherit; font-weight: 600; cursor: pointer;
    /* Een <a> die als knop is opgemaakt hoort geen onderstreping te hebben. */
    text-decoration: none;
    border: 1px solid transparent; border-radius: var(--radius-sm);
    transition: transform .05s, background .15s, box-shadow .15s, border-color .15s;
}
.btn:active { transform: translateY(1px); }
/* Icoontje in een knop: schaalt mee met de tekst en volgt de tekstkleur. */
.btn__ico { flex: none; width: 1.05em; height: 1.05em; }
.btn--block { width: 100%; }
.btn--primary {
    background: var(--brand); color: var(--brand-ink); box-shadow: var(--shadow-sm);
}
.btn--primary:hover { background: var(--brand-600); }
.btn--ghost {
    background: transparent; color: var(--text-soft); border-color: var(--border-strong);
}
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }

/* ================================================================ Alerts */
.alert {
    padding: 12px 15px; border-radius: var(--radius-sm); font-size: .9rem;
    border: 1px solid transparent; margin-bottom: 16px;
}
.alert--success { background: var(--success-bg); color: var(--success-tx); border-color: var(--success-bd); }
.alert--error   { background: var(--error-bg);   color: var(--error-tx);   border-color: var(--error-bd); }
.alert--info    { background: var(--info-bg);    color: var(--info-tx);    border-color: var(--info-bd); }

/* ============================================================== APP shell */
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }

.sidebar {
    position: sticky; top: 0; align-self: start; height: 100vh;
    display: flex; flex-direction: column;
    background: var(--surface); border-right: 1px solid var(--border);
    padding: 22px 18px;
}
.sidebar__brand { display: flex; align-items: center; gap: 12px; padding: 4px 6px 22px; }
.brand-name { font-weight: 680; font-size: 1.02rem; letter-spacing: -.01em; }

/* Logo en naam zijn samen de weg terug naar het dashboard — zoals een logo
   linksboven op vrijwel elke site. Het is een link, geen knop: er staat een
   echte URL achter, dus middelklikken en "in nieuw tabblad openen" werken. */
.brand-link {
    display: flex; align-items: center; gap: 12px; min-width: 0;
    color: inherit; text-decoration: none; border-radius: var(--radius-sm);
}
.brand-link:hover .brand-name { color: var(--brand); }
.brand-link:focus-visible {
    outline: 2px solid var(--brand); outline-offset: 3px;
}

.sidebar__nav { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.sidebar__nav a {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 13px; border-radius: var(--radius-sm);
    color: var(--text-soft); text-decoration: none; font-weight: 550; font-size: .94rem;
    transition: background .15s, color .15s;
}
.sidebar__nav a:hover { background: var(--surface-2); color: var(--text); }
.sidebar__nav a.active { background: var(--brand-50); color: var(--brand); }
.nav-ico { width: 20px; text-align: center; opacity: .9; }

.sidebar__foot { border-top: 1px solid var(--border); padding-top: 16px; }
.user-chip { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; padding: 0 4px; }
.user-chip__avatar {
    width: 38px; height: 38px; flex: none; border-radius: 50%;
    display: grid; place-items: center; font-weight: 700;
    background: var(--brand-50); color: var(--brand);
}
.user-chip__meta { display: flex; flex-direction: column; overflow: hidden; }
.user-chip__meta strong { font-size: .9rem; }
.user-chip__meta small { color: var(--text-faint); font-size: .78rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ================================================================ Content */
/* min-width: 0 is hier geen detail: als grid-item krijgt .content standaard
   min-width: auto, en dan kan de kolom niet smaller worden dan de breedste
   tabel erin. Een breed cursusoverzicht duwde de hele pagina zo buiten het
   scherm. Met 0 krimpt de kolom netjes mee en scrolt de tabel binnen haar
   eigen .table-wrap. */
.content { padding: 40px clamp(20px, 5vw, 56px); max-width: 1080px; min-width: 0; }
/* Pagina's met een brede tabel laten de leesbreedte los en vullen het scherm.
   Een lopende tekst blijft op 1080px, want regels van een halve meter lezen
   niet; een tabel met negen kolommen wél. */
.content--breed { max-width: none; }

.page-head { margin-bottom: 30px; }
.eyebrow { text-transform: uppercase; letter-spacing: .09em; font-size: .72rem;
    font-weight: 700; color: var(--brand); margin: 0 0 6px; }
.page-head h1 { font-size: 1.8rem; font-weight: 700; }
.page-head__sub { color: var(--text-soft); margin: 6px 0 0; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
    gap: 18px; margin-bottom: 30px; }
.card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow-sm);
    transition: transform .12s, box-shadow .12s;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.card__ico {
    width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center;
    background: var(--brand-50); color: var(--brand); font-size: 1.2rem; margin-bottom: 14px;
}
.card h3 { font-size: 1.05rem; margin-bottom: 6px; }
.card p { color: var(--text-soft); font-size: .92rem; margin: 0 0 14px; }

.panel {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden;
}
.panel__head { padding: 20px 24px; border-bottom: 1px solid var(--border); }
.panel__head h2 { font-size: 1.1rem; }
.panel__body { padding: 22px 24px; }

/* Uitklapbaar paneel: voor een blok dat er wel moet zijn, maar zelden nodig is
   (zoals handmatig een account aanmaken). Dichtgeklapt neemt het één regel in. */
.panel--inklap > summary {
    display: flex; align-items: center; gap: 10px;
    padding: 13px 24px; cursor: pointer; user-select: none;
    list-style: none;
}
.panel--inklap > summary::-webkit-details-marker { display: none; }
.panel--inklap > summary::before {
    content: ''; flex: none; width: 7px; height: 7px; margin-left: 2px;
    border-right: 2px solid var(--text-faint); border-bottom: 2px solid var(--text-faint);
    transform: rotate(-45deg); transition: transform .15s ease;
}
.panel--inklap[open] > summary::before { transform: rotate(45deg); }
.panel--inklap[open] > summary { border-bottom: 1px solid var(--border); }
.panel--inklap > summary:hover { background: var(--surface-2); }
.panel--inklap > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.panel--inklap > summary h2 {
    display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
    font-size: .95rem; margin: 0;
}
.inklap-hint { color: var(--text-faint); font-size: .82rem; font-weight: 400; }
.empty { padding: 44px 24px; text-align: center; color: var(--text-soft); }
.empty p { margin: 0 0 4px; font-weight: 550; }
.empty small { color: var(--text-faint); }

/* ============================================================ Data list */
.data-list { margin: 0; }
.data-list > div {
    display: grid; grid-template-columns: 200px 1fr; gap: 16px;
    padding: 15px 24px; border-bottom: 1px solid var(--border);
}
.data-list > div:last-child { border-bottom: none; }
.data-list dt { color: var(--text-soft); font-size: .9rem; }
.data-list dd { margin: 0; font-weight: 550; }

.badge {
    display: inline-block; padding: 3px 10px; border-radius: 999px;
    font-size: .78rem; font-weight: 600;
    background: var(--surface-2); color: var(--text-soft); border: 1px solid var(--border);
}
.badge--active   { background: var(--success-bg); color: var(--success-tx); border-color: var(--success-bd); }
.badge--inactive { background: var(--info-bg);    color: var(--info-tx);    border-color: var(--info-bd); }
.badge--locked   { background: var(--error-bg);   color: var(--error-tx);   border-color: var(--error-bd); }

.note { color: var(--text-faint); font-size: .86rem; margin: 18px 2px 0; }

/* ============================================================= Responsive */
@media (max-width: 860px) {
    /* Het menu verlaat hier het raster: het wordt een paneel dat over de
       pagina schuift. Zie "Hoofdmenu op smalle schermen" verderop. Wat
       overblijft zijn twee rijen: de kopbalk en de inhoud.

       Die rijen moeten expliciet: .app is 100vh hoog, en zolang een pagina
       korter is dan het scherm — bijvoorbeeld terwijl de tabel nog geladen
       wordt — verdeelt een grid de ruimte die overblijft over zijn rijen. De
       witte kopbalk werd daardoor tijdelijk een paar honderd pixels hoog. Met
       1fr op de tweede rij slokt de inhoud die ruimte op en houdt de kopbalk
       de hoogte die hij hoort te hebben. */
    .app { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
    .content { padding: 26px 20px; }
    .data-list > div { grid-template-columns: 1fr; gap: 3px; padding: 13px 18px; }
    .data-list dt { font-size: .8rem; }
}

/* ============================================================= Accountbeheer */
.select {
    appearance: none;
    padding: 10px 34px 10px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface)
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b93a1' stroke-width='3'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")
        no-repeat right 12px center;
    color: var(--text);
    font: inherit;
    font-size: .92rem;
    cursor: pointer;
}
.select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-50); }
.select--sm { padding: 6px 28px 6px 10px; font-size: .84rem; background-position: right 9px center; }

.admin-create {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    align-items: end;
}
.admin-create > button { grid-column: 1 / -1; justify-self: start; }

.btn--sm { padding: 6px 12px; font-size: .82rem; }
.btn--danger {
    background: var(--error-bg); color: var(--error-tx); border: 1px solid var(--error-bd);
}
.btn--danger:hover { background: #f9dbd9; }

.panel__head--split {
    display: flex; align-items: center; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
}
.search { display: flex; align-items: center; gap: 8px; margin: 0; }
.search input[type=search] {
    width: 240px; max-width: 100%;
    padding: 8px 12px; font: inherit; font-size: .9rem;
    color: var(--text); background: var(--surface);
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
}
.search input[type=search]::placeholder { color: var(--text-faint); }
.search input[type=search]:focus {
    outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-50);
}

.inline-form { display: inline-block; margin: 0; }
.count-pill {
    display: inline-block; margin-left: 8px; padding: 1px 9px; border-radius: 999px;
    font-size: .78rem; font-weight: 600; background: var(--brand-50); color: var(--brand-600);
    vertical-align: middle;
}
.muted { color: var(--text-faint); }

/* position: relative is hier geen opmaak maar een anker. Een absoluut
   gepositioneerd kind zonder gepositioneerde voorouder — zoals de .sr-only in
   de kop van de cursustabel — hangt anders aan het document zelf. Het schuift
   dan niet mee met deze scrollbak en wordt er ook niet door geclipt, maar
   blijft staan op zijn plek ver rechts van het venster, waardoor de hele
   pagina horizontaal scrollbaar wordt. Met relative valt zo'n kind binnen
   deze bak en blijft de overflow waar hij hoort. */
.table-wrap { overflow-x: auto; position: relative; }
.admin-table { width: 100%; border-collapse: collapse; font-size: .92rem; }
.admin-table th, .admin-table td {
    text-align: left; padding: 12px 14px; border-bottom: 1px solid var(--border);
    vertical-align: middle; white-space: nowrap;
}
.admin-table th {
    font-size: .78rem; font-weight: 600; color: var(--text-soft);
    text-transform: uppercase; letter-spacing: .03em;
}
.admin-table tbody tr:last-child td { border-bottom: none; }
.admin-table tr:hover td { background: var(--surface-2); }
/* Geen display:flex op de cel zelf: dan is het geen tabelcel meer, volgt haar
   hoogte de knop in plaats van de rij, en loopt de onderrand niet meer gelijk
   met de andere kolommen. De tussenruimte gaat daarom via een marge. */
.admin-table .col-actions { white-space: normal; }
.admin-table td.col-actions > * { vertical-align: middle; margin: 2px 8px 2px 0; }
.admin-table td.col-actions > *:last-child { margin-right: 0; }

/* "Zelf wachtwoord instellen" — een uitklapper onder de resetknop. Ingeklapt,
   want in verreweg de meeste gevallen druk je gewoon op resetten; een open
   invoerveld op elke rij maakt de kolom onrustig. */
.ww-zelf { display: inline-block; }
.ww-zelf > summary {
    display: inline-block; cursor: pointer; list-style: none;
    font-size: .82rem; color: var(--text-soft);
}
.ww-zelf > summary::-webkit-details-marker { display: none; }
.ww-zelf > summary:hover { color: var(--brand); text-decoration: underline; }
.ww-zelf > summary:focus-visible {
    outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 3px;
}
.ww-zelf__form { display: flex; align-items: center; gap: 6px; margin: 6px 0 0; }
.ww-zelf__form input[type=text] { width: 180px; padding: 7px 10px; font-size: .84rem; }

@media (max-width: 860px) {
    .admin-create { grid-template-columns: 1fr; }
}

/* ---------- Cursisten uit Tribe ---------- */
.tenant-grid {
    display: grid; gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
}
.tenant-card {
    display: flex; flex-direction: column; gap: 3px;
    padding: 13px 15px; border: 1px solid var(--border); border-radius: var(--radius-sm);
    background: var(--surface-2); color: var(--text); text-decoration: none;
    transition: border-color .15s ease, background .15s ease;
}
.tenant-card:hover { border-color: var(--border-strong); }
.tenant-card strong { font-size: .94rem; font-weight: 620; }
.tenant-card small { font-size: .78rem; color: var(--text-soft); }
.tenant-card--active {
    border-color: var(--brand); background: var(--brand-50);
    box-shadow: 0 0 0 1px var(--brand);
}
.tenant-card__err { color: var(--error-tx) !important; }

.filterbar {
    display: flex; flex-wrap: wrap; gap: 8px;
    padding: 14px 24px; border-bottom: 1px solid var(--border);
}
.chip {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 5px 12px; border-radius: 999px; font-size: .83rem; font-weight: 550;
    border: 1px solid var(--border); background: var(--surface-2);
    color: var(--text-soft); text-decoration: none;
}
.chip:hover { border-color: var(--border-strong); color: var(--text); }
.chip--active { background: var(--brand-50); border-color: var(--brand); color: var(--brand); }
.chip__n { font-variant-numeric: tabular-nums; opacity: .75; font-size: .78rem; }

.admin-table .col-check { width: 34px; }
.admin-table .col-check input { width: 16px; height: 16px; accent-color: var(--brand); }
.admin-table tr.row--vervallen td { opacity: .55; }

.bulkbar {
    display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
    border-top: 1px solid var(--border);
}
.bulkbar--alt { padding-top: 0; border-top: none; }

.pager {
    display: flex; align-items: center; justify-content: center; gap: 14px;
    padding: 16px 24px; border-top: 1px solid var(--border); font-size: .88rem;
}

.linked-meta { margin: 3px 0 0; font-size: .78rem; color: var(--text-faint); }

@media (max-width: 720px) {
    .filterbar { padding: 12px 18px; }
    .bulkbar { flex-direction: column; align-items: flex-start; }
}

/* ---------- "Inloggen als"-balk (impersonatie) ---------- */
.impbar {
    position: sticky; top: 0; z-index: 60;
    display: flex; align-items: center; gap: 10px;
    height: var(--impbar-h);
    padding: 0 clamp(12px, 3vw, 24px);
    background: var(--warn-bg); color: var(--warn-tx);
    border-bottom: 1px solid var(--warn-bd);
    font-size: .82rem; line-height: 1;
}
.impbar__ico { font-size: .92rem; line-height: 1; flex: none; }
/* Alles op één regel; te lange namen worden afgekapt in plaats van af te breken. */
.impbar__text {
    margin: 0; flex: 1; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.impbar__text strong { font-weight: 680; }
.impbar__sub { opacity: .75; }
.impbar__form { flex: none; margin: 0; }
.impbar__btn {
    padding: 3px 10px; font-size: .78rem; line-height: 1.4;
    background: var(--warn-tx); color: var(--warn-bg);
    border: 1px solid transparent; font-weight: 600;
}
.impbar__btn:hover { filter: brightness(1.12); }

/* De sidebar blijft onder de balk plakken in plaats van eronder te schuiven. */
body.has-impbar .sidebar { top: var(--impbar-h); height: calc(100vh - var(--impbar-h)); }
body.has-impbar .app { min-height: calc(100vh - var(--impbar-h)); }

@media (max-width: 720px) {
    /* Op smalle schermen valt het e-mailadres weg zodat de balk één regel blijft. */
    .impbar__sub { display: none; }
}

/* ============================== Hoofdmenu op smalle schermen ==============
   Onder 860px past een vaste zijbalk van 264px niet meer naast de inhoud.
   Het menu wordt daar een paneel dat vanaf rechts over de pagina schuift,
   met een waas eroverheen.

   Deze regels staan bewust ná die van de impersonatiebalk: die zet met
   `body.has-impbar .sidebar` de bovenkant en de hoogte van het menu, en dat
   geldt niet meer zodra het menu een zwevend paneel is.

   Het paneel is hier de standaard en niet iets dat JavaScript aanzet. Zou het
   andersom zijn, dan stond het menu bij elke pagina eerst even in het oude
   formaat voordat het script het opvouwt. Voor bezoekers zonder JavaScript
   staat de oude weergave in een <noscript>-blok in layout.php.
   ======================================================================== */

.mobielkop, .menu-waas, .menu-sluit { display: none; }

@media (max-width: 860px) {

    /* ---- De balk met de hamburger ---- */
    .mobielkop {
        display: flex; align-items: center; gap: 12px;
        position: sticky; top: 0; z-index: 40;
        padding: 10px clamp(12px, 4vw, 20px);
        background: var(--surface); border-bottom: 1px solid var(--border);
    }
    /* Onder de impersonatiebalk blijven plakken, niet eronder verdwijnen. */
    body.has-impbar .mobielkop { top: var(--impbar-h); }

    .mobielkop .brand-link { flex: 1; }
    .mobielkop .brand-name {
        min-width: 0;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }

    .hamburger {
        flex: none; margin-left: auto;
        display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
        width: 44px; height: 44px; padding: 0 11px;
        background: transparent; color: var(--text);
        border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
        cursor: pointer;
    }
    .hamburger:hover { background: var(--surface-2); }
    .hamburger__streep {
        display: block; width: 100%; height: 2px; border-radius: 2px;
        background: currentColor;
        transition: transform .25s ease, opacity .15s ease;
    }
    /* Open: de buitenste strepen kruisen, de middelste verdwijnt. De strepen
       staan 7px uit elkaar (2px hoog, 5px ertussen), dus zoveel schuiven ze. */
    body.menu-open .hamburger__streep:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    body.menu-open .hamburger__streep:nth-child(2) { opacity: 0; }
    body.menu-open .hamburger__streep:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

    /* ---- De waas over de pagina ---- */
    .menu-waas {
        display: block;
        position: fixed; inset: 0; z-index: 70;
        background: rgba(15, 18, 25, .45);
        opacity: 0; visibility: hidden;
        /* visibility springt pas ná de overgang terug, anders is het paneel al
           weg voordat het uitgeschoven is. */
        transition: opacity .28s ease, visibility 0s .28s;
    }

    /* ---- Het paneel zelf ---- */
    .sidebar,
    body.has-impbar .sidebar {
        position: fixed; top: 0; right: 0; left: auto; z-index: 80;
        width: min(330px, 86vw);
        height: 100vh; height: 100dvh;
        flex-direction: column; align-items: stretch; flex-wrap: nowrap; gap: 0;
        padding: 18px 16px;
        overflow-y: auto; overscroll-behavior: contain;
        border-right: 0; border-left: 1px solid var(--border);
        box-shadow: -18px 0 50px rgba(16, 24, 40, .18);
        transform: translateX(100%);
        visibility: hidden;
        transition: transform .28s cubic-bezier(.22, .61, .36, 1), visibility 0s .28s;
    }

    .sidebar__brand { padding: 4px 6px 20px; }

    .menu-sluit {
        display: inline-flex; align-items: center; justify-content: center;
        flex: none; margin-left: auto;
        width: 36px; height: 36px; font-size: 1.5rem; line-height: 1;
        background: transparent; color: var(--text-soft);
        border: 0; border-radius: var(--radius-sm); cursor: pointer;
    }
    .menu-sluit:hover { background: var(--surface-2); color: var(--text); }

    /* ---- Open ---- */
    body.menu-open .menu-waas {
        opacity: 1; visibility: visible;
        transition: opacity .28s ease, visibility 0s;
    }
    body.menu-open .sidebar,
    body.has-impbar.menu-open .sidebar {
        transform: translateX(0);
        visibility: visible;
        transition: transform .28s cubic-bezier(.22, .61, .36, 1), visibility 0s;
    }
    /* De pagina eronder mag niet meescrollen zolang het paneel open staat. */
    body.menu-open { overflow: hidden; }

    /* De menu-items komen één voor één binnen; net genoeg om het paneel te
       laten voelen als iets dat aankomt in plaats van dat het er ineens is. */
    body.menu-open .sidebar__nav a {
        animation: menu-item .32s both cubic-bezier(.22, .61, .36, 1);
    }
    .sidebar__nav a:nth-child(1) { animation-delay: .04s; }
    .sidebar__nav a:nth-child(2) { animation-delay: .08s; }
    .sidebar__nav a:nth-child(3) { animation-delay: .12s; }
    .sidebar__nav a:nth-child(4) { animation-delay: .16s; }
    .sidebar__nav a:nth-child(5) { animation-delay: .20s; }
    .sidebar__nav a:nth-child(6) { animation-delay: .24s; }
    .sidebar__nav a:nth-child(7) { animation-delay: .28s; }
    .sidebar__nav a:nth-child(8) { animation-delay: .32s; }
}

@keyframes menu-item {
    from { opacity: 0; transform: translateX(14px); }
    to   { opacity: 1; transform: none; }
}

/* Wie beweging heeft uitgezet krijgt hetzelfde menu, maar dan zonder reis. */
@media (prefers-reduced-motion: reduce) {
    .sidebar, .menu-waas, .hamburger__streep { transition-duration: .01ms; }
    body.menu-open .sidebar, body.menu-open .menu-waas { transition-duration: .01ms; }
    body.menu-open .sidebar__nav a { animation: none; }
}

/* Op papier hoort een menu sowieso niet thuis. */
@media print { .mobielkop, .menu-waas { display: none !important; } }

/* ========================= Menu inklappen op brede schermen ===============
   Boven 860px staat het menu vast links en kost het 264px. Wie die ruimte
   liever aan de inhoud geeft — een cursusoverzicht met negen kolommen, een
   presentielijst — klapt het terug tot een smalle strook met alleen de
   pictogrammen. De pagina's die daarop wachten (.content--breed) worden
   daarmee in één klap een stuk breder.

   De klasse staat op <html> en niet op <body>: een kort script in de <head>
   zet hem al vóór de eerste verf, en op dat moment bestaat <body> nog niet.
   De keuze ligt in localStorage, dus hij blijft staan tussen pagina's door.

   Alles hieronder zit in een min-width-vraag. Onder 860px is het menu een
   schuifpaneel dat al dicht is; daar valt niets in te klappen, en de klasse
   uit localStorage mag daar dus niets doen.
   ======================================================================== */

.menu-inklap { display: none; }
/* Uitloggen krijgt alleen een pictogram als het woord wegvalt. */
.uitlog .nav-ico { display: none; }

@media (min-width: 861px) {

    .menu-inklap {
        display: inline-flex; align-items: center; justify-content: center;
        flex: none; margin-left: auto;
        width: 30px; height: 30px; line-height: 1; font-size: .95rem;
        background: transparent; color: var(--text-faint);
        border: 1px solid transparent; border-radius: 9px; cursor: pointer;
        transition: background .15s, color .15s, border-color .15s;
    }
    .menu-inklap:hover {
        background: var(--surface-2); color: var(--text); border-color: var(--border);
    }
    .menu-inklap:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
    .menu-inklap__ico::before { content: '\00AB'; }

    /* De breedte van de kolom is het enige dat echt beweegt; de rest is
       zichtbaar of niet. Browsers die grid-template-columns niet animeren
       springen gewoon, en dat is hier geen verlies. */
    .app { transition: grid-template-columns .22s cubic-bezier(.22, .61, .36, 1); }

    /* ---- Ingeklapt ---- */
    .menu-ingeklapt .app { grid-template-columns: var(--sidebar-w-smal) 1fr; }

    .menu-ingeklapt .sidebar {
        padding-left: 14px; padding-right: 14px;
        /* Boven de inhoud, anders schuift een tekstballon eronder. */
        z-index: 5;
    }

    /* Merk en knop passen niet naast elkaar in 76px, dus onder elkaar. */
    .menu-ingeklapt .sidebar__brand {
        flex-direction: column; gap: 10px; padding: 4px 0 18px;
    }
    .menu-ingeklapt .brand-link { justify-content: center; }
    .menu-ingeklapt .menu-inklap { margin-left: 0; }
    .menu-ingeklapt .menu-inklap__ico::before { content: '\00BB'; }

    /* Alle opschriften weg; de pictogrammen blijven staan. De schoolkeuze
       verdwijnt helemaal: een keuzelijst is niet terug te brengen tot een
       pictogram, en wie wil wisselen klapt het menu even open. */
    .menu-ingeklapt .brand-name,
    .menu-ingeklapt .nav-tekst,
    .menu-ingeklapt .user-chip__meta,
    .menu-ingeklapt .sidebar__school { display: none; }

    .menu-ingeklapt .sidebar__nav a { justify-content: center; padding: 11px 0; }
    .menu-ingeklapt .user-chip { justify-content: center; padding: 0; }
    .menu-ingeklapt .uitlog { padding-left: 0; padding-right: 0; }
    .menu-ingeklapt .uitlog .nav-ico { display: block; }

    /* ---- Tekstballon bij de pictogrammen ----
       Zonder opschrift is een pictogram een raadsel. De ballon hangt buiten
       de strook, dus het menu mag hier niets afknippen. */
    .menu-ingeklapt .sidebar__nav a,
    .menu-ingeklapt .uitlog { position: relative; }

    .menu-ingeklapt .sidebar__nav a::after,
    .menu-ingeklapt .uitlog::after {
        content: attr(data-tip);
        position: absolute; left: calc(100% + 16px); top: 50%; z-index: 90;
        transform: translateY(-50%);
        padding: 6px 10px; border-radius: 8px;
        background: var(--text); color: var(--surface);
        font-size: .82rem; font-weight: 550; white-space: nowrap;
        box-shadow: var(--shadow-md); pointer-events: none;
        opacity: 0; visibility: hidden;
        transition: opacity .12s ease, visibility 0s .12s;
    }
    .menu-ingeklapt .sidebar__nav a:hover::after,
    .menu-ingeklapt .sidebar__nav a:focus-visible::after,
    .menu-ingeklapt .uitlog:hover::after,
    .menu-ingeklapt .uitlog:focus-visible::after {
        opacity: 1; visibility: visible;
        transition: opacity .12s ease, visibility 0s;
    }
}

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

/* ---------- Inschrijvingen, detail en betaling ---------- */
.crumbs {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    margin: 0 0 18px; font-size: .86rem; color: var(--text-faint);
}
.crumbs span[aria-hidden] { opacity: .55; }

.link--strong { font-weight: 600; }

.inschrijvingen .col-jaar { white-space: nowrap; font-variant-numeric: tabular-nums; }
.inschrijvingen .col-geld,
.admin-table th.col-geld { text-align: right; white-space: nowrap;
    font-variant-numeric: tabular-nums; }

.badge--soft { background: var(--surface-2); color: var(--text-soft); }

/* Mijn inschrijvingen op mobiel: de tabel wordt een lijst met kaarten.
   Vijf kolommen passen niet op een telefoon; horizontaal scrollen door een
   tabel is daar onwerkbaar. Elke rij wordt daarom één blok met de cursus als
   kop, jaar en cursist als onderregel en het bedrag rechts daarvan. De hele
   kaart is aantikbaar via de bestaande link (zie .col-cursus .link::after),
   dus de losse "Bekijken"-knop — met een te kleine tap-target — vervalt. */
@media (max-width: 720px) {
    .inschrijvingen,
    .inschrijvingen tbody,
    .inschrijvingen tr,
    .inschrijvingen td { display: block; width: 100%; }

    .inschrijvingen thead { display: none; }

    .table-wrap--kaarten { overflow-x: visible; }

    .inschrijvingen tr {
        position: relative;
        display: flex; flex-wrap: wrap; align-items: baseline;
        gap: 2px 8px;
        padding: 14px 18px;
        border-bottom: 1px solid var(--border);
    }
    .inschrijvingen tbody tr:last-child { border-bottom: none; }
    .inschrijvingen tr:hover td { background: none; }
    .inschrijvingen tr:active { background: var(--surface-2); }

    .inschrijvingen td {
        width: auto; padding: 0; border-bottom: none;
        white-space: normal;
    }

    /* Cursusnaam als kop van de kaart; breekt netjes af bij lange namen. */
    .inschrijvingen .col-cursus {
        flex: 1 1 100%;
        font-size: 1rem; line-height: 1.35;
        overflow-wrap: anywhere;
    }
    .inschrijvingen .col-cursus .badge { margin-left: 6px; vertical-align: 2px; }

    /* Maakt de hele rij aantikbaar zonder extra markup. */
    .inschrijvingen .col-cursus .link::after {
        content: ""; position: absolute; inset: 0;
    }

    /* Onderregel: jaar · cursist links, bedrag rechts. */
    .inschrijvingen .col-jaar,
    .inschrijvingen .col-cursist {
        margin-top: 3px;
        font-size: .86rem; color: var(--text-soft);
    }
    .inschrijvingen .col-cursist::before {
        content: "·"; margin-right: 8px; color: var(--text-faint);
    }
    .inschrijvingen .col-geld {
        margin-top: 3px; margin-left: auto;
        font-size: .95rem; font-weight: 650; color: var(--text);
    }

    .inschrijvingen .col-actions { display: none; }
}

/* Facturen op mobiel: net als bij de inschrijvingen wordt elke rij een kaart.
   Hier blijven de knoppen wél staan — "Betalen" en "PDF openen" zijn echte
   acties — maar ze krijgen een volle regel en een grotere tap-target. De
   ingesprongen betalingsrijen blijven onder hun factuur hangen. */
@media (max-width: 720px) {
    .facturen,
    .facturen tbody,
    .facturen tr,
    .facturen td { display: block; width: 100%; }

    .facturen thead { display: none; }

    .facturen td {
        width: auto; padding: 0; border-bottom: none;
        white-space: normal;
    }
    .facturen tr:hover td { background: none; }

    /* Factuurrij als kaart: nummer + bedrag boven, datum + status eronder,
       daarna de knoppen. */
    .facturen tbody tr:not(.rij--betaling) {
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "nummer bedrag"
            "datum  status"
            "acties acties";
        gap: 4px 12px;
        padding: 15px 18px;
    }
    .facturen tbody tr:not(.rij--betaling):not(:first-child) {
        border-top: 1px solid var(--border);
    }
    .facturen .col-nummer { grid-area: nummer; overflow-wrap: anywhere; }
    .facturen .col-datum  { grid-area: datum; }
    .facturen .col-status { grid-area: status; justify-self: end; text-align: right; }
    .facturen .col-actions {
        grid-area: acties;
        display: flex; flex-wrap: wrap; gap: 8px;
        margin-top: 8px;
    }
    .facturen tbody tr:not(.rij--betaling) .col-geld {
        grid-area: bedrag; justify-self: end;
        font-weight: 650;
    }

    /* Ruimere knoppen: btn--sm is met de muis prima, met een duim niet. */
    .facturen .col-actions .btn { padding: 9px 15px; font-size: .86rem; }

    /* Betalingen: ingesprongen subregel onder de factuur, zonder scheidingslijn. */
    .facturen .rij--betaling {
        display: flex; flex-wrap: wrap; align-items: baseline;
        gap: 2px 10px;
        padding: 0 18px 13px 30px;
        border-top: none;
    }
    .facturen .rij--betaling .col-betaling { flex: 1 1 100%; }
    .facturen .rij--betaling .col-geld { font-weight: 600; }
    .facturen .rij--betaling .col-status { margin-left: auto; }
    .facturen .rij--betaling .col-actions { display: none; }
    .facturen .rij--betaling + tr td { border-top: none; }
    .facturen .betaling-pijl { width: auto; margin-right: 6px; }
}

/* Heel smal: minder witruimte rondom, zodat de kaarten meer ruimte krijgen. */
@media (max-width: 480px) {
    .content { padding: 22px 14px; }
    .page-head h1 { font-size: 1.45rem; }
    .page-head { margin-bottom: 22px; }
    .panel__head { padding: 16px 18px; }
    .panel__body { padding: 18px; }
    .empty { padding: 34px 20px; }
    .inschrijvingen tr { padding: 13px 14px; }
    .facturen tbody tr:not(.rij--betaling) { padding: 14px; }
    .facturen .rij--betaling { padding: 0 14px 12px 26px; }
}

.badge--betaald               { background: var(--success-bg); color: var(--success-tx); border-color: var(--success-bd); }
.badge--openstaand            { background: var(--warn-bg);    color: var(--warn-tx);    border-color: var(--warn-bd); }
.badge--nog_niet_gefactureerd { background: var(--info-bg);    color: var(--info-tx);    border-color: var(--info-bd); }
.badge--niet_factureren       { background: var(--surface-2);  color: var(--text-soft); }

.kpi-row { display: flex; flex-wrap: wrap; gap: 14px 40px; }
.kpi { display: flex; flex-direction: column; gap: 5px; }
.kpi__label { font-size: .78rem; text-transform: uppercase; letter-spacing: .07em;
    font-weight: 650; color: var(--text-faint); }
.kpi__value { font-size: 1.6rem; font-weight: 680; letter-spacing: -.02em;
    font-variant-numeric: tabular-nums; }
.kpi__value--sm { font-size: 1rem; font-weight: 500; }

.data-list--money dd { font-variant-numeric: tabular-nums; }
.data-list__total { font-weight: 680; }
.data-list__total dt, .data-list__total dd { border-top: 1px solid var(--border); padding-top: 12px; }

.note--lead { margin-top: 18px; font-size: .9rem; color: var(--text-soft); }
.note--inline { margin: 2px 2px 0; }

/* ---------- Mijn gegevens ---------- */
.form-kop {
    font-size: .78rem; text-transform: uppercase; letter-spacing: .08em;
    font-weight: 700; color: var(--text-faint);
    margin: 26px 0 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.profiel-form .form-kop:first-of-type { margin-top: 0; }
.veldgroep { display: grid; gap: 14px; }
.veldgroep--naam    { grid-template-columns: 1.4fr .7fr 1.6fr; }
.veldgroep--adres   { grid-template-columns: 2fr .7fr .7fr .9fr 1.4fr; }
.veldgroep--contact { grid-template-columns: repeat(3, 1fr); }
.veldgroep--bank    { grid-template-columns: minmax(0, 340px) 1fr 1fr; }
.form-acties { margin-top: 24px; }

@media (max-width: 860px) {
    .veldgroep--naam,
    .veldgroep--adres,
    .veldgroep--contact,
    .veldgroep--bank    { grid-template-columns: 1fr 1fr; }
    .kpi-row { gap: 14px 26px; }
}
@media (max-width: 560px) {
    .veldgroep { grid-template-columns: 1fr !important; }
}

/* ---------- Facturen en betalen ---------- */
.panel--actie { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.betaal-cta {
    display: flex; align-items: center; justify-content: space-between;
    gap: 18px; flex-wrap: wrap;
}
.betaal-cta h2 { font-size: 1.05rem; }

.facturen .col-geld { text-align: right; }
.facturen .rij--betaling td { padding-top: 4px; padding-bottom: 10px;
    font-size: .85rem; color: var(--text-soft); border-top: none; }
.facturen .rij--betaling + tr td { border-top: 1px solid var(--border); }
.betaling-pijl { display: inline-block; width: 18px; color: var(--text-faint); }

@media (max-width: 620px) {
    .betaal-cta { flex-direction: column; align-items: stretch; }
    .betaal-cta .btn { width: 100%; }
}

/* ---------- Presentielijst ---------- */
.periodebalk {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
}
.periodes { display: flex; gap: 8px; flex-wrap: wrap; }
.periode-datum { display: flex; align-items: flex-end; gap: 8px; margin: 0; }
.periode-datum .field { min-width: 0; }
.periode-datum input[type=date] {
    padding: 6px 10px; font: inherit; font-size: .85rem;
    color: var(--text); background: var(--surface-2);
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
}

/* Elke les is een uitklapper. Dichtgeklapt zie je waar de les over gaat —
   datum, tijd en de regel eronder — en pas als je hem opent de presentietabel.
   Het pijltje staat in een eigen kolom, zodat de tweede regel netjes onder de
   datum uitkomt en niet onder het pijltje. */
.les > summary {
    display: grid; grid-template-columns: auto 1fr; gap: 3px 12px;
    padding: 18px 24px; cursor: pointer; user-select: none; list-style: none;
}
.les > summary::-webkit-details-marker { display: none; }
.les > summary::before {
    content: ''; grid-row: 1; grid-column: 1;
    width: 7px; height: 7px; margin-top: 7px;
    border-right: 2px solid var(--text-faint); border-bottom: 2px solid var(--text-faint);
    transform: rotate(-45deg); transition: transform .15s ease;
}
.les[open] > summary::before { transform: rotate(45deg); }
.les[open] > summary { border-bottom: 1px solid var(--border); }
.les > summary:hover { background: var(--surface-2); }
.les > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.les > summary > * { grid-column: 2; min-width: 0; }

.les__kop { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
            font-size: 1.1rem; }
.les__datum { font-size: 1.05rem; }
.les__tijd {
    font-size: .9rem; font-weight: 600; color: var(--brand);
    background: var(--brand-50); padding: 2px 8px; border-radius: var(--radius-sm);
}
/* De cursus hoort in de hoofdregel: datum en tijd zeggen wanneer, de cursus
   zegt waarover. Bij een individuele les komt de naam van de cursist erachter,
   want anders heten twee lessen op één ochtend precies hetzelfde. Ze staan in
   een lichter gewicht dan de datum, zodat de regel niet één blok vet wordt. */
.les__cursus, .les__cursist { font-size: 1rem; font-weight: 500; }
.les__cursist { color: var(--text-soft); }
/* De scheidingsstip zit aan de cursist en niet in de tekst, zodat hij vanzelf
   wegvalt als er geen cursusnaam voor staat. */
.les__cursus + .les__cursist::before {
    content: '·'; margin-right: 8px; color: var(--text-faint);
}

/* Lokaal en instrument: kleiner, op de regel eronder. */
.les__meta { margin: 0; font-size: .85rem; color: var(--text-soft); }

.les__form { margin: 0; }
.les__acties {
    display: flex; justify-content: flex-end;
    padding: 14px 24px; border-top: 1px solid var(--border);
}

/* Invoervelden in de tabel: de labels zijn op desktop overbodig (de kolomkop
   zegt het al) en verschijnen pas in de kaartweergave op mobiel. */
.veld-mobiel { display: block; margin: 0; }
.veld-mobiel__label { display: none; }
/* De waarde zoals hij op papier hoort te staan; op het scherm staat op deze
   plek het invoerveld. Zie de afdrukweergave onderaan. */
.op-papier { display: none; }
.presentie .select--sm { width: 100%; min-width: 130px; }
.presentie .col-opmerking input[type=text] {
    width: 100%; padding: 6px 10px; font: inherit; font-size: .85rem;
    color: var(--text); background: var(--surface-2);
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
}
.presentie .col-opmerking input[type=text]:focus { outline: none; background: var(--surface); }

/* De presentielijst is een invulformulier, geen leestabel: hoe meer cursisten
   er tegelijk op het scherm passen, hoe minder je tijdens het aftekenen scrolt.
   De rijen zijn hier daarom strakker dan in de andere tabellen — de velden
   bepalen de hoogte en houden net genoeg lucht om uit elkaar te blijven.
   Alleen de verticale ruimte krimpt; links en rechts blijft het zoals het was.

   Bewust een min-width en niet gewoon deze regels vóór het mobiele blok: onder
   720px is dit geen tabel meer maar een rij kaarten, en daar hoort de ruimte
   juist te blijven — die wordt met een duim ingevuld. */
@media (min-width: 721px) {
    .presentie th { padding-top: 8px; padding-bottom: 8px; }
    .presentie td { padding-top: 5px; padding-bottom: 5px; }
    .presentie .select--sm,
    .presentie .col-opmerking input[type=text] { padding-top: 4px; padding-bottom: 4px; }

    /* E-mail en mobiel staan onder elkaar en zouden anders de hoogste cel van
       de rij worden; met een krappere regelafstand blijven ze binnen de
       rijhoogte die de keuzelijst bepaalt. */
    .presentie .col-contact { line-height: 1.35; }
}

@media (max-width: 560px) {
    .periodebalk { align-items: stretch; }
    .periodes .btn { flex: 1 1 auto; }
}

/* ---------- Presentielijst op een telefoon ----------
   Een presentielijst wordt staand in een lokaal ingevuld, dus daar telt elke
   tik. Onder 720px vervalt de tabelvorm: elke cursist wordt een kaart met de
   naam als kop en velden over de volle breedte, groot genoeg om met een duim
   te raken. De kolomkoppen verdwijnen; hun labels komen bij de velden terug. */
@media (max-width: 720px) {
    .presentie,
    .presentie tbody,
    .presentie tr,
    .presentie td { display: block; width: 100%; }

    .presentie thead { display: none; }

    .presentie tr {
        padding: 14px 0 16px;
        border-bottom: 1px solid var(--border);
    }
    .presentie tr:last-child { border-bottom: 0; }
    /* Zie de opmerking bij .cursussen: nowrap uit, anders lopen lange namen
       en e-mailadressen buiten het scherm. */
    .presentie td { border: 0; padding: 0 18px; white-space: normal; overflow-wrap: anywhere; }

    .presentie .col-naam { margin-bottom: 10px; font-size: 1rem; }
    .presentie .col-presentie,
    .presentie .col-opmerking { margin-bottom: 10px; }

    .veld-mobiel__label {
        display: block; margin-bottom: 4px;
        font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
        font-weight: 700; color: var(--text-faint);
    }
    /* 16px voorkomt dat iOS bij het focussen inzoomt. */
    .presentie .select--sm,
    .presentie .col-opmerking input[type=text] {
        font-size: 16px; padding: 10px 12px;
    }

    .presentie .col-contact { font-size: .85rem; }

    .les__acties { padding: 14px 18px; }
    .les__acties .btn { width: 100%; }
}

/* ---------- Informatiepagina ---------- */
.uitleg { margin: 0 0 12px; color: var(--text-soft); line-height: 1.6; }
.uitleg:last-child { margin-bottom: 0; }
.uitleg strong { color: var(--text); }
.uitleg-lijst {
    margin: 0; padding-left: 20px;
    color: var(--text-soft); line-height: 1.65; font-size: .94rem;
}
.uitleg-lijst li { margin-bottom: 6px; }
.uitleg-lijst li:last-child { margin-bottom: 0; }
.uitleg-lijst strong { color: var(--text); }
.uitleg-lijst + .note { margin-top: 14px; }

/* ---------- Uitvoer: exporteren en printen ---------- */
.kop-acties { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.uitvoer { display: flex; gap: 8px; }
.printkop { display: none; }

@media (max-width: 720px) {
    .kop-acties { width: 100%; }
    .kop-acties .search { flex: 1 1 100%; }
    .kop-acties .search input[type=search] { flex: 1 1 auto; width: auto; min-width: 0; }
    .uitvoer { flex: 1 1 100%; }
    .uitvoer .btn { flex: 1 1 auto; }
}

/* ---------- Afdrukweergave ----------
   Een presentielijst wordt uitgeprint om mee het lokaal in te nemen. Alles wat
   op papier niets doet gaat eruit: menu, filters, knoppen en de kolom met
   contactgegevens. De invoervelden worden platte tekst, want een keuzelijst
   drukt af als een leeg vakje. In plaats daarvan komt er per cursist een
   hokje om met de hand af te vinken. */
@media print {
    .sidebar, .impbar, .periodebalk, .kolomkeuze, .kop-acties, .les__acties,
    .page-head__sub, .eyebrow, .alert, .count-pill,
    /* Zoekveld, periodeknoppen en de knoppen "Exporteren" en "Printen": daar
       valt op papier niets meer mee te doen. */
    .panel--filters { display: none !important; }

    /* De paginakop staat al in .printkop, mét docent, periode en afdrukdatum.
       Twee keer "Presentielijst" onder elkaar is er één te veel, en de <h1>
       is de minst informatieve van de twee. Alleen waar zo'n printkop echt
       volgt: een browser zonder :has() houdt de oude, dubbele kop. */
    .page-head:has(~ .printkop) { display: none; }

    .app { display: block; }
    .content { padding: 0; }
    body { background: #fff; color: #000; }

    .printkop {
        display: block; margin-bottom: 14px;
        font-size: 11pt; border-bottom: 1px solid #000; padding-bottom: 6px;
    }

    .panel {
        border: 0; box-shadow: none; border-radius: 0;
        margin: 0 0 10px !important;
        break-inside: avoid; page-break-inside: avoid;
    }
    .panel__head,
    .les > summary { border-bottom: 1px solid #000; padding: 0 0 2px; }

    /* Op papier hoort een les gewoon open te staan: de lijst wordt uitgeprint
       om mee het lokaal in te nemen. inklap.js klapt ze open vlak voor het
       afdrukken; deze twee regels vangen op waar dat niet lukt (JavaScript uit)
       en halen het pijltje weg, dat op papier niets betekent. */
    .les > summary { display: block; }
    .les > summary::before { display: none; }
    .les:not([open]) > *:not(summary) { display: block; }

    .les__kop { font-size: 12pt; gap: 10px; }
    .les__tijd { background: none; color: #000; padding: 0; }
    /* Op papier moet juist de naam van de cursist opvallen. */
    .les__cursist { color: #000; }
    .les__meta { font-size: 9pt; color: #333; }

    .table-wrap { overflow: visible; }

    /* De planning wordt uitgeprint of meegenomen naar de administratie; op
       papier is de tabelvorm leesbaarder dan de kaarten van de mobiele
       weergave, dus die blijft hier gewoon een tabel. */
    .planning { width: 100%; border-collapse: collapse; font-size: 9.5pt; }
    .planning th, .planning td {
        border-bottom: 1px solid #999; padding: 5px 4px;
    }
    /* De voet van de planning (subtotalen en totaal) staat verderop, onder de
       schermregels: deze @media print komt in dit bestand vóór de sectie
       Planning, en bij gelijke specificiteit wint de regel die later staat. */

    .presentie { width: 100%; border-collapse: collapse; font-size: 10pt; }
    .presentie th, .presentie td {
        border-bottom: 1px solid #999; padding: 3px 4px; text-align: left;
        /* nowrap komt uit .admin-table en hoort hier niet: een lange naam of
           een uitgetypte opmerking moet op papier gewoon afbreken. */
        vertical-align: top; white-space: normal;
    }
    .presentie th { font-size: 7.5pt; }
    .presentie .col-contact { display: none; }
    .presentie th:nth-child(4) { display: none; }

    /* Kolombreedtes: in de opmerking wordt met de hand geschreven, dus die
       krijgt de meeste ruimte. Zonder dit verdeelt de browser de breedte naar
       de inhoud, en dan houdt een lege opmerking niets over. */
    .presentie .col-naam      { width: 34%; }
    .presentie .col-presentie { width: 22%; }
    .presentie .col-opmerking { width: 44%; }

    /* Bij een individuele les staat de naam al in de kop van de les en is er
       één regel. Kolomkoppen erboven zijn dan drie woorden ruis per les — over
       een dag met zeventien lessen scheelt dat een halve pagina. De naamkolom
       gaat om dezelfde reden weg: die zou de naam vijf millimeter lager nog
       een keer herhalen. Wat overblijft is een hokje, de stand, en ruimte om
       te schrijven. */
    .les--individueel .presentie thead { display: none; }
    .les--individueel .presentie .col-naam { display: none; }
    .les--individueel .presentie .col-presentie { width: 30%; }
    .les--individueel .presentie .col-opmerking { width: 70%; }

    /* Formuliervelden zijn op papier niets: een keuzelijst drukt af als een
       leeg vakje of als "— niet ingevuld —", en een invoervak als een grijs
       kadertje. Ze gaan eruit; wat erin stond komt terug als tekst. */
    .presentie .veld-mobiel { display: none; }
    .op-papier { display: inline; }

    /* Een opmerking wordt in het lokaal met de hand bijgeschreven. Er is dus
       schrijfruimte nodig, ook (juist) als er nog niets staat. Geen eigen
       onderlijn: die van de rij zit er al vlak onder, en twee lijntjes van
       drie pixels uit elkaar zien er rommelig uit. */
    .op-papier--lijn { display: block; min-height: 1.5em; }

    /* Ruimte om met de hand af te vinken. */
    .presentie .col-presentie::before {
        content: ''; display: inline-block;
        width: 11px; height: 11px; margin-right: 7px;
        border: 1px solid #000; vertical-align: -1px;
    }

    a[href]::after { content: none !important; }
}

/* ---------- Cursussen ---------- */
.cursussen .col-getal { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cursussen th.col-getal { text-align: right; }
.cursussen .col-cursus { min-width: 200px; }
/* De cursusnaam is de regel waar je op zoekt in de kolom; de rest eronder is
   toelichting. 650 in plaats van de 700 van <strong>: dat is de dikte die de
   rest van het portaal aanhoudt. */
.cursussen .col-cursus strong { font-weight: 650; }
/* De naam van de cursist onder een individuele les is geen bijschrift maar de
   reden dat je die regel zoekt. Donkerder dan de standaard .linked-meta, die
   elders (accountbeheer) wél een terzijde is — vandaar hier en niet daar. */
.cursussen .linked-meta { color: var(--text); }
.cursussen .col-planning { min-width: 150px; }
.cursussen .totaalrij td {
    border-top: 2px solid var(--border-strong);
    background: var(--surface-2); font-variant-numeric: tabular-nums;
}

@media (max-width: 720px) {
    .cursussen,
    .cursussen tbody,
    .cursussen tfoot,
    .cursussen tr,
    .cursussen td { display: block; width: 100%; }

    .cursussen thead { display: none; }

    .cursussen tbody tr {
        padding: 14px 18px 16px;
        border-bottom: 1px solid var(--border);
    }
    /* De globale tabelregel zet white-space op nowrap. In een kaart mag niets
       meer nowrap zijn: een cursusnaam van negentig tekens duwt de pagina
       anders breder dan het scherm. Alleen de getallen blijven bij elkaar. */
    .cursussen td { border: 0; padding: 0 0 6px; text-align: left !important;
                    white-space: normal; overflow-wrap: anywhere; }
    .cursussen .col-getal { white-space: nowrap; overflow-wrap: normal; }
    .cursussen .col-cursus { padding-bottom: 10px; font-size: 1rem; min-width: 0; }

    /* De labels die op desktop de kolomkop zijn, komen hier bij de waarde. */
    .cursussen .veld-mobiel__label {
        display: inline-block; min-width: 120px; margin: 0;
        font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
        font-weight: 700; color: var(--text-faint);
    }
    .cursussen .col-cursus .veld-mobiel__label { display: none; }
    .cursussen .col-planning small { display: inline; }

    /* De actieknop wordt op een kaart een gewone, volle knop met tekst: een
       los icoontje van 30px is te klein om met een duim te raken en zegt
       zonder kolomkop ook niets meer. */
    .cursussen .col-actions { padding: 10px 0 0; }
    .cursussen .col-actions .btn { width: 100%; padding: 10px 14px; }

    .cursussen .totaalrij td { padding: 3px 18px; }
    .cursussen .totaalrij td:first-child { padding-top: 12px; }
    /* Kolommen die op een kaart niets toevoegen. */
    .cursussen .col-leeg { display: none; }
}

/* Tekst die alleen in de kaartweergave zin heeft. */
.knop-tekst, .alleen-mobiel { display: none; }

@media (max-width: 720px) {
    .knop-tekst { display: inline; }
    .alleen-mobiel { display: inline; font-weight: 400; color: var(--text-soft); }
}

/* ---------- Planning ----------
   Dezelfde opzet als de cursustabel: rechts uitgelijnde getallen op desktop,
   en onder 720px valt de tabel uiteen in kaarten met de kolomkop bij de
   waarde. De eenheid staat in de kolomkop en niet in elke cel, anders wordt
   een kolom van louter "30 min" onnodig breed en rekent hij niet mee. */
.planning .col-getal { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.planning th.col-getal { text-align: right; }
.planning .col-datum { min-width: 150px; }
/* Zoals de cursusnaam op Cursussen: de datum is waar je op zoekt in de rij.
   650 in plaats van de 700 van <strong>, de dikte van de rest van het portaal. */
.planning .col-datum strong { font-weight: 650; }
.planning .col-tijd { white-space: nowrap; font-variant-numeric: tabular-nums; }
.planning .col-cursus { min-width: 200px; white-space: normal; }
.planning .totaalrij td {
    border-top: 1px solid var(--border-strong);
    background: var(--surface-2); font-variant-numeric: tabular-nums;
}
/* De subtotalen per leeftijdscategorie staan boven de totaalregel: dezelfde
   band, maar rustiger, zodat het totaal de regel blijft die opvalt. */
.planning .subtotaalrij td {
    border-top: 1px solid var(--border);
    background: var(--surface-2); color: var(--text-soft);
    font-variant-numeric: tabular-nums;
}
.planning .subtotaalrij__aantal { margin-left: 8px; color: var(--text-faint); font-size: .85em; }
/* De zware lijn hoort tussen de lessen en de voet, en dus op de eerste regel
   daarvan — of dat nu een subtotaal is of meteen het totaal. */
.planning tfoot tr:first-child td { border-top: 2px solid var(--border-strong); }
/* In een kolomkop mag de eenheid rustiger staan dan de kop zelf. */
.planning th .eenheid { font-weight: 400; text-transform: none; letter-spacing: 0; }

/* Weggevinkte kolommen.
   Drie klassen tegen twee (`.planning td` in de kaartweergave), dus deze
   regel wint op specificiteit — ook onder 720px, waar cellen blokken worden.
   Daarom is hier geen !important nodig. */
.planning--zonder-voorbereiding .col-voorbereiding,
.planning--zonder-totaal .col-totaal { display: none; }

/* Op papier geen grijze balken: een vlak van 30% grijs over de hele breedte
   kost toner en leest slechter dan een lijn. Dit blok staat bewust hier en
   niet bij de andere printregels hierboven — het moet ná de schermregels
   komen om ze te kunnen overschrijven. */
@media print {
    .planning tfoot tr:first-child td { border-top: 1px solid #000; }
    .planning .subtotaalrij td { border-top: 1px solid #999; background: none; color: #333; }
    .planning .totaalrij td { border-top: 1px solid #000; background: none; }
}

/* De balk met de vinkjes: een rustige regel onder de periodeknoppen. */
.kolomkeuze {
    display: flex; align-items: center; gap: 8px 18px; flex-wrap: wrap;
    padding-top: 14px; padding-bottom: 14px;
    border-top: 1px solid var(--border);
}
.kolomkeuze__label {
    font-size: .78rem; font-weight: 600; color: var(--text-soft);
    text-transform: uppercase; letter-spacing: .03em;
}
.kolomkeuze__opties { display: flex; gap: 18px; flex-wrap: wrap; }
.kolomkeuze .checkbox { font-size: .88rem; }

@media (max-width: 720px) {
    .planning,
    .planning tbody,
    .planning tfoot,
    .planning tr,
    .planning td { display: block; width: 100%; }

    .planning thead { display: none; }

    .planning tbody tr {
        padding: 14px 18px 16px;
        border-bottom: 1px solid var(--border);
    }
    /* De globale tabelregel zet white-space op nowrap. In een kaart mag niets
       meer nowrap zijn: een cursusnaam van negentig tekens duwt de pagina
       anders breder dan het scherm. Alleen de getallen blijven bij elkaar. */
    .planning td { border: 0; padding: 0 0 6px; text-align: left !important;
                   white-space: normal; overflow-wrap: anywhere; }
    .planning .col-getal { white-space: nowrap; overflow-wrap: normal; }

    /* De datum is de kop van de kaart; de tijd komt er als eerste veld onder. */
    .planning .col-datum { padding-bottom: 4px; font-size: 1rem; min-width: 0; }
    .planning .col-tijd { padding-bottom: 10px; }

    /* De labels die op desktop de kolomkop zijn, komen hier bij de waarde. */
    .planning .veld-mobiel__label {
        display: inline-block; min-width: 120px; margin: 0;
        font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
        font-weight: 700; color: var(--text-faint);
    }

    .planning .totaalrij td,
    .planning .subtotaalrij td { padding: 3px 18px; }
    .planning .totaalrij td:first-child,
    .planning .subtotaalrij td:first-child { padding-top: 12px; }
}

/* ---------- Bijladen van een tabel ---------- */
.laden {
    display: flex; flex-direction: column; align-items: center;
    gap: 10px; padding: 56px 24px; text-align: center;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--radius); box-shadow: var(--shadow-sm);
}
.laden p { margin: 0; font-weight: 550; color: var(--text-soft); }
.laden small { color: var(--text-faint); }
.laden__spin {
    width: 26px; height: 26px; border-radius: 50%;
    border: 3px solid var(--border);
    border-top-color: var(--brand);
    animation: laden-draai .8s linear infinite;
}
@keyframes laden-draai { to { transform: rotate(360deg); } }

/* Wie liever geen beweging ziet, krijgt een rustige puls. */
@media (prefers-reduced-motion: reduce) {
    .laden__spin { animation: laden-puls 1.4s ease-in-out infinite; }
    @keyframes laden-puls { 50% { opacity: .35; } }
}

/* Tijdens het verversen blijft de oude inhoud staan, maar wat vager, zodat
   de pagina niet opspringt bij het wisselen van een filter. */
.tabel-doel[aria-busy="true"] .panel { opacity: .55; transition: opacity .15s; }

@media print { .laden { display: none; } }

/* ---------- Detailvenster (individuele les) ---------- */
.venster {
    width: min(1180px, calc(100vw - 32px));
    max-height: calc(100vh - 64px);
    padding: 0; border: 1px solid var(--border);
    border-radius: var(--radius); background: var(--surface); color: var(--text);
    box-shadow: 0 18px 50px rgba(0,0,0,.22);
}
.venster::backdrop { background: rgba(15, 18, 25, .45); }
.venster__kop {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    padding: 16px 20px; border-bottom: 1px solid var(--border);
    position: sticky; top: 0; background: var(--surface); z-index: 1;
}
.venster__titel { margin: 0; font-size: 1rem; }
.venster__inhoud { padding: 20px; overflow: auto; max-height: calc(100vh - 140px); }

/* De wachtmelding over het venster heen, terwijl een wijziging naar de
   administratie gaat. Het formulier post gewoon door, dus het venster mag niet
   worden leeggemaakt — deze laag gaat er overheen en houdt tegelijk de knoppen
   buiten bereik, zodat niemand er nog een tweede keer op drukt.

   inset werkt tegen het venster zelf: een <dialog> staat van zichzelf al
   absoluut. */
.venster__bezig {
    position: absolute; inset: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    padding: 24px; background: var(--surface);
}
.venster__bezig .laden { border: 0; box-shadow: none; background: none; }

.detail-kolommen { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; }
.detail-blok h3 {
    margin: 0 0 10px; font-size: .78rem; text-transform: uppercase; letter-spacing: .08em;
    color: var(--text-faint);
}

/* De gewone .data-list heeft een labelkolom van 200px plus 24px zijmarge; in
   een venstervak van een kleine 560px gaat daar te veel aan op. Hier dus een
   smaller label, geen zijmarge, en waarden die afbreken in plaats van uit hun
   cel te lopen — een cursusnaam kan lang zijn. */
.detail-blok .data-list > div {
    grid-template-columns: 116px minmax(0, 1fr);
    gap: 12px; padding: 9px 0; align-items: baseline;
}
.detail-blok .data-list dt { font-size: .82rem; }
.detail-blok .data-list dd {
    font-weight: 550; min-width: 0;
    overflow-wrap: anywhere; word-break: break-word;
}
.detail-scroll { max-height: 380px; overflow: auto; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.planningtabel th {
    position: sticky; top: 0; background: var(--surface-2); z-index: 1;
}
.planningtabel td, .planningtabel th { white-space: nowrap; }
.planningtabel th, .planningtabel td { padding: 9px 12px; }

@media (max-width: 720px) {
    /* In een schermvullend venster is 4 kolommen krap; kleiner lettertype en
       minder marge houdt de tabel binnen de breedte in plaats van hem
       horizontaal te laten schuiven. */
    .planningtabel { font-size: .84rem; }
    .planningtabel th, .planningtabel td { padding: 8px 7px; }
    .detail-scroll { max-height: none; }
    .venster__inhoud { padding: 16px; }
    .venster__kop { padding: 13px 16px; }
}

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

@media (max-width: 900px) {
    .detail-kolommen { grid-template-columns: 1fr; gap: 22px; }
}

@media (max-width: 720px) {
    .detail-blok .data-list > div { grid-template-columns: 104px minmax(0, 1fr); gap: 10px; }
    /* dvh houdt rekening met de balken van een mobiele browser; vh doet dat
       niet, waardoor de onderkant van het venster wegvalt. */
    .venster {
        width: 100vw; max-width: 100vw;
        max-height: 100vh; max-height: 100dvh;
        border-radius: 0; border: 0;
    }
    .venster__inhoud {
        max-height: calc(100vh - 62px);
        max-height: calc(100dvh - 62px);
    }
    .cursussen .col-actions { padding-top: 8px; }
    .cursussen .col-actions .btn { width: auto; }
}

@media print { .venster { display: none; } }

/* ---------- Wijzigformulieren in het cursusvenster ---------- */
.wijzigingen { display: grid; gap: 10px; margin-top: 22px; }
.wijzigingen .panel--inklap > summary { padding: 12px 16px; }
.wijzigingen .panel--inklap > summary h2 { font-size: .9rem; }
.wijzigingen .panel__body { padding: 16px; }
.wijzigingen .form { display: grid; gap: 14px; }
.wijzigingen .field__hint { margin-top: 3px; }
.wijzigingen .btn { justify-self: start; }

@media (max-width: 720px) {
    .wijzigingen { margin-top: 18px; }
    .wijzigingen .btn { justify-self: stretch; width: 100%; }
    /* 16px voorkomt inzoomen op iOS bij het aantikken van een veld. */
    .wijzigingen input, .wijzigingen select { font-size: 16px; }
}

/* ---------- Aanstelling ---------- */
.aanstelling__kop { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.aanstelling__jaar {
    font-size: .9rem; font-weight: 700; color: var(--brand);
    background: var(--brand-50); padding: 2px 9px; border-radius: var(--radius-sm);
}
.aanstelling__cijfers {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px;
}
.cijferblok h3 {
    margin: 0 0 8px; font-size: .74rem; text-transform: uppercase; letter-spacing: .08em;
    color: var(--text-faint);
}
.cijferblok .data-list > div {
    grid-template-columns: minmax(0, 1fr) auto; gap: 12px; padding: 7px 0;
}
.cijferblok .data-list dt { font-size: .84rem; }
.cijferblok .data-list dd { font-variant-numeric: tabular-nums; text-align: right; }

.saldo {
    margin: 0; font-size: 2rem; font-weight: 700; line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.saldo small { font-size: .9rem; font-weight: 550; color: var(--text-faint); margin-left: 6px; }
/* Meer gepland dan de aanstelling toelaat is het geval om op te vallen. */
.saldo--over  { color: var(--error-tx); }
.saldo--onder { color: var(--text); }
.saldo__uitleg { margin: 8px 0 0; font-size: .88rem; color: var(--text-soft); }
.saldo__datum { margin: 10px 0 0; font-size: .78rem; color: var(--text-faint); }

.aanstelling__notities { border: 0; border-top: 1px solid var(--border); border-radius: 0; box-shadow: none; }
/* Geen justify-items:start op het formulier zelf: dan krimpen de velden tot
   hun eigen inhoud en heeft de width:100% van het tekstvak niets om zich aan
   te meten. Alleen de knop hoeft links te blijven staan. */
.notitie-form { display: grid; gap: 10px; margin-bottom: 18px; }
.notitie-form .btn { justify-self: start; }
.notitie-form .field { width: 100%; }
.notitie-form textarea {
    width: 100%; min-width: 0; box-sizing: border-box;
    padding: 10px 12px; font: inherit; font-size: .9rem;
    color: var(--text); background: var(--surface-2);
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm); resize: vertical;
}
.notities { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.notities li {
    padding: 12px 14px; background: var(--surface-2);
    border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.notitie__tekst { font-size: .92rem; line-height: 1.5; }
.notitie__voet {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-top: 8px;
}

@media (max-width: 900px) {
    .aanstelling__cijfers { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
    .aanstelling__cijfers { grid-template-columns: 1fr; gap: 18px; }
    .notitie-form .btn { width: 100%; }
    .notitie-form textarea { font-size: 16px; }
}

/* ---------- Accountbeheer op een telefoon ----------
   De beheertabellen hebben vijf of zes kolommen met keuzelijsten en knoppen
   erin; horizontaal door zoiets scrollen is op een telefoon onwerkbaar. Elke
   rij wordt daarom een kaart met de naam als kop en de kolomkop bij de waarde.

   Bewust op .beheer en niet op .admin-table: Cursussen en Planning dragen die
   klasse ook, en die hebben hun eigen kaartweergave. Twee sets regels met
   dezelfde zwaarte zouden elkaar dan overschrijven. */
@media (max-width: 720px) {
    .beheer,
    .beheer tbody,
    .beheer tr,
    .beheer td { display: block; width: 100%; }

    .beheer thead { display: none; }

    .beheer tbody tr {
        position: relative;
        padding: 14px 18px 16px;
        border-bottom: 1px solid var(--border);
    }
    .beheer tbody tr:last-child { border-bottom: none; }
    .beheer tr:hover td { background: none; }

    /* De globale tabelregel zet white-space op nowrap. In een kaart mag niets
       meer nowrap zijn: een e-mailadres van veertig tekens duwt de pagina
       anders breder dan het scherm. */
    .beheer td {
        border: 0; padding: 0 0 6px; text-align: left !important;
        white-space: normal; overflow-wrap: anywhere;
    }
    .beheer .col-hoofd { padding-bottom: 10px; font-size: 1rem; }

    .beheer .veld-mobiel__label {
        display: inline-block; min-width: 118px; margin: 0;
        font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
        font-weight: 700; color: var(--text-faint);
    }

    /* Een keuzelijst naast zo'n label wordt anders een paar tekens breed. */
    .beheer .inline-form { display: block; margin-top: 4px; }
    .beheer .select--sm { width: 100%; }

    /* Het vinkje hoort bij de naam, niet op een eigen regel eronder. Rechts
       bovenin, en groot genoeg om met een duim te raken. */
    .beheer .col-check {
        position: absolute; top: 12px; right: 16px;
        width: auto; padding: 0;
    }
    .beheer .col-check input { width: 22px; height: 22px; }
    /* Met het vinkje rechtsboven mag de naam daar niet onderdoor lopen. */
    .beheer .col-hoofd { padding-right: 40px; }

    /* Knoppen onder elkaar en over de volle breedte: naast elkaar worden het
       raakdoelen van nog geen centimeter. */
    .beheer .col-actions {
        display: flex; flex-direction: column; gap: 8px;
        padding: 10px 0 0;
    }
    .beheer td.col-actions > * { margin: 0; }
    .beheer .col-actions .btn { width: 100%; padding: 10px 14px; }

    /* Het wachtwoordveld naast een knop van een halve regel is niet te typen:
       veld over de volle breedte, knop eronder. */
    .beheer .ww-zelf { display: block; }
    .beheer .ww-zelf__form { flex-wrap: wrap; gap: 8px; }
    .beheer .ww-zelf__form input[type=text] { flex: 1 1 100%; width: auto; }

    /* Onderaan de Tribe-lijst: knop en uitleg onder elkaar. */
    .bulkbar { flex-direction: column; align-items: stretch; gap: 10px; }
    .bulkbar .btn { width: 100%; }
    .pager { flex-wrap: wrap; gap: 10px; }
}

/* ====================== Invoervelden op een telefoon ======================
   iOS Safari zoomt automatisch in zodra je een invoerveld aantikt waarvan de
   letter kleiner is dan 16px — en zoomt daarna niet vanzelf terug, waardoor de
   pagina scheefgetrokken blijft staan. Alles waar je in typt of kiest gaat op
   een smal scherm daarom naar precies 16px.

   De selectors zijn met opzet dezelfde als die van de compacte maten hierboven
   en dit blok staat achteraan: bij gelijke zwaarte wint de laatste regel, dus
   dit hoeft niet met !important. Op desktop blijven de compacte maten staan.
   ======================================================================== */
@media (max-width: 860px) {
    .select,
    .select--sm,
    .search input[type=search],
    .periode-datum input[type=date],
    .presentie .col-opmerking input[type=text],
    .ww-zelf__form input[type=text],
    .notitie-form textarea { font-size: 16px; }
}

/* Het codeveld op de tweestapspagina: zes cijfers die je overtikt uit een
   mail. Groot, met ruimte tussen de cijfers, zodat je ziet wat je typt en
   niet halverwege de tel kwijtraakt. */
.codeveld {
    width: 100%; padding: 14px 16px;
    font: inherit; font-size: 1.6rem; font-weight: 650;
    letter-spacing: .38em; text-indent: .38em; text-align: center;
    font-variant-numeric: tabular-nums;
    color: var(--text); background: var(--surface);
    border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
}
.codeveld::placeholder { color: var(--text-faint); font-weight: 400; }
.codeveld:focus {
    outline: none; border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-50);
}

/* =========================================================================
   Satdesign portal — onderdelen die alleen dit portaal heeft
   ========================================================================= */

/* --- Cijferkaarten op het overzicht ---------------------------------------
   Eén rij met de aantallen die ertoe doen. Alleen "openstaande facturen"
   vraagt om actie, en die is daarom de enige met kleur; zouden ze allemaal
   opvallen, dan valt er niets meer op. */
.kaartrij {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 14px;
    margin-bottom: 22px;
}
.kaart {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 18px 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: inherit;
    transition: border-color .15s ease, transform .15s ease;
}
.kaart:hover { border-color: var(--border-strong); transform: translateY(-1px); }
.kaart__getal { font-size: 30px; font-weight: 650; line-height: 1.1; }
.kaart__label { font-size: 13px; color: var(--text-soft); }
.kaart--let-op { border-color: var(--warn-bd); background: var(--warn-bg); }
.kaart--let-op .kaart__getal { color: var(--warn-tx); }
.kaart--let-op .kaart__label { color: var(--warn-tx); }

/* --- Tabellen ------------------------------------------------------------- */
/* Brede tabellen schuiven binnen hun eigen kader; de pagina zelf hoort nooit
   horizontaal mee te schuiven. */
.tabel-scroll { overflow-x: auto; }
.admin-table td.num, .admin-table th.num { text-align: right; }
.admin-table td.nowrap, .admin-table th.nowrap { white-space: nowrap; }
.subtekst {
    display: block;
    font-size: 12px;
    line-height: 17px;
    color: var(--text-soft);
    margin-top: 2px;
}
.rij--open td { background: color-mix(in srgb, var(--warn-bg) 45%, transparent); }

/* --- Statuslabels --------------------------------------------------------- */
.status {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 550;
    white-space: nowrap;
    background: var(--info-bg);
    color: var(--info-tx);
    border: 1px solid var(--info-bd);
}
.status--ok   { background: var(--success-bg); color: var(--success-tx); border-color: var(--success-bd); }
.status--open { background: var(--warn-bg);    color: var(--warn-tx);    border-color: var(--warn-bd); }

/* --- Filterbalk boven een overzicht --------------------------------------- */
.filterbalk {
    display: flex;
    align-items: flex-end;
    gap: 12px;
    margin-bottom: 16px;
}
.filterbalk .field { margin: 0; min-width: 220px; }

/* --- Totaalbedrag onder het onderhoud -------------------------------------
   Het bedrag groot, de opbouw eronder klein: de meeste mensen willen alleen
   het bedrag, en wie het niet vertrouwt leest de regel eronder. */
.totaalblok {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px 24px;
    padding: 16px 20px;
    border-top: 1px solid var(--border);
    background: var(--surface-2);
}
.totaalblok__label { display: block; font-size: 12px; color: var(--text-soft); }
.totaalblok__waarde { font-size: 24px; font-weight: 650; }
.totaalblok__sub { font-size: 12px; color: var(--text-soft); margin-left: 4px; }
.totaalblok .note { margin: 0; max-width: 62ch; }

/* --- Acties --------------------------------------------------------------- */
.onder-actie { margin: 18px 0 0; }
.form__acties { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }

/* Een knop die eruitziet als een link, voor een handeling binnen een zin. */
.knop-als-link {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--brand);
    text-decoration: underline;
    cursor: pointer;
}
.knop-als-link:hover { color: var(--brand-600); }
.domein-uitslag { display: block; margin-top: 4px; }

/* --- Termijnkeuze bij "incasso activeren" ---------------------------------
   Zit in een <details> zodat de keuze pas verschijnt als iemand hem nodig
   heeft; anders staat er in elke factuurregel een keuzelijst die vrijwel
   nooit gebruikt wordt. */
.incasso-keuze { display: inline-block; text-align: left; }
.incasso-keuze > summary { list-style: none; cursor: pointer; }
.incasso-keuze > summary::-webkit-details-marker { display: none; }
.incasso-keuze__form {
    position: absolute;
    z-index: 20;
    right: 16px;
    margin-top: 8px;
    padding: 16px;
    width: 280px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    text-align: left;
}
.incasso-keuze__form .note { font-size: 12px; line-height: 17px; }

@media (max-width: 680px) {
    .incasso-keuze__form { position: static; width: auto; box-shadow: none; }
    .totaalblok { flex-direction: column; align-items: flex-start; }
}

/* --- Logo in plaats van merkletters --------------------------------------
   Het Satdesign-blokje heeft zijn eigen kleur en vorm, dus de gekleurde
   achtergrond en de schaduw eromheen kunnen weg: die vochten met het logo. */
.brand-mark:has(img) {
    background: none;
    box-shadow: none;
    border-radius: 0;
}
.brand-mark img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* --- Klantkoppelingen in het accountbeheer -------------------------------
   Staan onder het e-mailadres in dezelfde cel: een account heeft er meestal
   maar één, en je wilt hem zien naast het adres waar hij bij hoort. */
.koppelingen { margin-top: 6px; }
.koppel-lijst { list-style: none; margin: 2px 0 6px; padding: 0; }
.koppel-lijst li {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 13px;
    line-height: 19px;
}
.koppel-form { display: flex; gap: 6px; align-items: center; margin-top: 4px; }
.koppel-form .select { max-width: 240px; }

/* Een tekstknop die niet met de echte acties concurreert. */
.knop-als-link--stil {
    color: var(--text-faint);
    font-size: 12px;
    text-decoration: underline;
}
.knop-als-link--stil:hover { color: var(--error-tx); }

/* --- Blokken naast elkaar op het overzicht -------------------------------
   .detail-blok komt uit het docentenportaal, waar het altijd binnen een
   lichtbak stond die zijn eigen witte vlak meebracht. Op de overzichtspagina
   staat het los op de paginakleur, dus krijgt het hier hetzelfde vlak als een
   .panel — anders zweeft de tabel op de grijze achtergrond. */
.detail-blok {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
    min-width: 0;
}
.detail-blok > .panel__head { padding: 16px 20px 12px; }
.detail-blok > .empty { padding: 20px; }
.detail-blok > .note { margin: 0; padding: 12px 20px 16px; }

/* --- Lange teksten in overzichtstabellen ---------------------------------
   .admin-table zet alle cellen op nowrap; dat werkt voor het accountbeheer,
   waar elke cel kort is. In de overzichten staat er een omschrijving in
   ("Online overleg met Tim over de nieuwe formulieren…") en die liep dan door
   de kolom ernaast heen. Hier mogen cellen dus afbreken; datums en bedragen
   houden hun nowrap via .nowrap en .num. */
.detail-blok .admin-table th,
.detail-blok .admin-table td,
.tabel-scroll .admin-table th,
.tabel-scroll .admin-table td {
    white-space: normal;
    overflow-wrap: anywhere;
}
.detail-blok .admin-table td.num,
.detail-blok .admin-table th.num,
.detail-blok .admin-table td.nowrap,
.tabel-scroll .admin-table td.num,
.tabel-scroll .admin-table th.num,
.tabel-scroll .admin-table td.nowrap,
.tabel-scroll .admin-table th.nowrap {
    white-space: nowrap;
    overflow-wrap: normal;
}
.detail-blok .admin-table th,
.detail-blok .admin-table td { padding: 10px 20px; }

/* --- Stappenuitleg vóór een handeling met gevolgen ------------------------
   Staat op de incassopagina boven het formulier: er wordt een échte betaling
   gedaan, en dat hoort niet pas bij Mollie duidelijk te worden. */
.stappen {
    margin: 0 0 20px;
    padding-left: 20px;
    color: var(--text-soft);
    font-size: .92rem;
    line-height: 1.55;
}
.stappen li { margin-bottom: 6px; }
.stappen li::marker { color: var(--brand); font-weight: 600; }
