/* ============================================
   inlyn - Mobile First CSS
   ============================================ */

/* --- Reset --- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* --- CSS Variables --- */
:root {
    /* Brand (overschrijfbaar via config) */
    --brand: #fd3d3a;
    --brand-rgb: 253, 61, 58;

    /* Light mode */
    --bg: #f0f4f8;
    --card: #fff;
    --card2: #f8fafc;
    --border: rgba(0, 0, 0, .08);
    --border2: rgba(0, 0, 0, .15);
    --text: #1a202c;
    --muted: #64748b;
    --subtle: rgba(0, 0, 0, .03);

    /* Semantic */
    --green: #22c55e;
    --blue: #4f7fff;
    --amber: #f59e0b;
    --red: #ef4444;
    --red-rgb: 239, 68, 68;
    /* Voor een schaal die verder loopt dan goed/let op/fout: oranje zit tussen amber en rood in,
       paars staat voor "niet meer van jou" (uit handen bij een incassobureau). */
    --orange: #f97316;
    --purple: #8b5cf6;

    /* Meldingsvlakken: een gekleurd vlak hoort zijn eigen tekstkleur mee te
       brengen. Zonder dat erft de tekst --text, en dan staat er in donkere modus
       lichte tekst op een lichte achtergrond. Dat is precies wat er misging op
       Materiaalstand en de Beschikbaarheid-check. */
    --goed-bg: #dcfce7;
    --goed-tekst: #15803d;
    --letop-bg: #fef3c7;
    --letop-tekst: #92400e;
    --fout-bg: #fee2e2;
    --fout-tekst: #991b1b;

    /* Layout */
    --nav-w: 220px;
    --radius: 10px;
    --radius-sm: 7px;
    --radius-xs: 5px;
}

[data-theme="dark"] {
    --bg: #0d1117;
    --card: #161b22;
    --card2: #1c2333;
    --border: rgba(255, 255, 255, .08);
    --border2: rgba(255, 255, 255, .14);
    --text: #e6edf3;
    --muted: #8b949e;
    --subtle: rgba(255, 255, 255, .04);

    --goed-bg: rgba(34, 197, 94, .16);
    --goed-tekst: #6ee7a7;
    --letop-bg: rgba(245, 158, 11, .16);
    --letop-tekst: #fbbf24;
    --fout-bg: rgba(239, 68, 68, .16);
    --fout-tekst: #fca5a5;
}

/* Vlakken en badges met een betekenis. Altijd achtergrond én tekstkleur samen. */
.vlak-goed  { background: var(--goed-bg);  color: var(--goed-tekst); }
.vlak-letop { background: var(--letop-bg); color: var(--letop-tekst); }
.vlak-fout  { background: var(--fout-bg);  color: var(--fout-tekst); }

/* Een rustig vlak binnen een kaart: uitgeklapte regels, code-uitvoer, een
   voorbeeldtekst. --subtle is doorschijnend en volgt daarom het thema. */
.vlak-rustig {
    background: var(--subtle);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
/* Logo light/dark switching */
.nav-logo-dark { display: none; }
[data-theme="dark"] .nav-logo-light { display: none; }
[data-theme="dark"] .nav-logo-dark { display: block; }

/* --- Base --- */
html { font-size: 13px; -webkit-text-size-adjust: 100%; }
body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.5;
    min-height: 100vh;
    min-height: 100dvh;
}
a { color: var(--brand); text-decoration: none; }
a:hover { opacity: .85; }
img { max-width: 100%; height: auto; }

/* --- Typography --- */
h1 { font-size: 18px; font-weight: 700; }
h2 { font-size: 15px; font-weight: 700; }
h3 { font-size: 13px; font-weight: 600; }
.muted { color: var(--muted); }
.label {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
}

/* --- App Shell --- */
.app {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}

/* --- Sidebar Nav (mobile: overlay) --- */
.nav {
    position: fixed;
    top: 48px;
    left: 0;
    bottom: 0;
    width: var(--nav-w);
    background: var(--card);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    z-index: 50;
    transform: translateX(-100%);
    transition: transform .2s ease;
}
.nav.open { transform: translateX(0); }

.nav-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .5);
    z-index: 49;
}
.nav-overlay.open { display: block; }

.nav-top {
    padding: 14px 14px 10px;
}
.nav-logo {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
}
.nav-logo img:not(.nav-logo-circle) {
    height: 28px;
    width: auto;
}
.nav-logo-circle {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-xs);
    object-fit: contain;
    flex-shrink: 0;
    border: 2px solid var(--border);
    padding: 3px;
    background: var(--card);
}
.nav-logo-text {
    font-family: 'Rubik', sans-serif;
    font-size: 20px;
    font-weight: 900;
    letter-spacing: -.06em;
    color: var(--text);
}
.nav-logo-dot {
    color: var(--brand);
}
.nav-logo-text-plain {
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
}

.nav-menu {
    flex: 1;
    overflow-y: auto;
    padding: 8px;
}
.nav-group-label {
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted);
    padding: 12px 10px 4px;
    opacity: .6;
}
.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 13px;
    font-weight: 400;
    transition: background .15s;
    cursor: pointer;
}
.nav-item:hover { background: var(--subtle); }

/* Het getal naast een menu-item: wat daar vandaag jouw hand vraagt. Alleen zichtbaar als er
   werkelijk iets staat, want een teller op nul is ruis. Hij pulseert één bezoek lang als het
   getal hoger is dan de vorige keer; daarna staat hij stil. Wie dat niet wil zet het uit op
   /settings/account. */
.nav-sein {
    margin-left: auto;
    min-width: 15px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--brand);         /* merkrood: valt op en blijft in de huisstijl */
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 15px;
    text-align: center;
    font-variant-numeric: tabular-nums;
    flex: 0 0 auto;
}
.nav-sein.nieuw { animation: nav-sein-klop 1.8s ease-out 3; }
@keyframes nav-sein-klop {
    0%   { box-shadow: 0 0 0 0 rgba(var(--brand-rgb), .55); }
    70%  { box-shadow: 0 0 0 6px rgba(var(--brand-rgb), 0); }
    100% { box-shadow: 0 0 0 0 rgba(var(--brand-rgb), 0); }
}
@media (prefers-reduced-motion: reduce) { .nav-sein.nieuw { animation: none; } }
/* Ingeklapt menu: het label is weg, dus het getal schuift naar de rand van het icoon. */
.sidebar.collapsed .nav-sein, .nav-collapsed .nav-sein {
    position: absolute; top: 2px; right: 2px; min-width: 0; padding: 0 4px; font-size: 9px;
    line-height: 13px;
}
.nav-item.active {
    background: rgba(var(--brand-rgb), .1);
    color: var(--brand);
    font-weight: 600;
}
.nav-item svg {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.nav-bottom {
    padding: 6px 8px;
    border-top: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.nav-powered {
    font-size: 9px;
    color: var(--muted);
    opacity: .6;
}
.nav-bottom-user {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    color: var(--text);
    text-decoration: none;
    transition: background .15s;
    cursor: pointer;
}
.nav-bottom-user:hover { background: var(--subtle); opacity: 1; }
.nav-bottom-user.active { background: rgba(var(--brand-rgb), .1); }
.nav-bottom-user svg { flex-shrink: 0; color: var(--muted); }

/* Entity switcher */
.nav-entity-switcher {
    padding: 0px;
    position: relative;
}
.nav-entity-current {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--radius-xs);
    cursor: pointer;
    font-size: 16px;
    font-weight: 700;
    color: var(--text);
    transition: background .15s;
}
.nav-entity-current:hover { background: var(--subtle); }
.nav-entity-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.nav-entity-dropdown {
    position: absolute;
    left: 8px;
    right: 8px;
    top: 100%;
    background: var(--card);
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(0,0,0,.15);
    z-index: 60;
    overflow: hidden;
}
.nav-entity-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    font-size: 12px;
    color: var(--text);
    text-decoration: none;
    transition: background .1s;
}
.nav-entity-option:hover { background: var(--subtle); opacity: 1; }
.nav-entity-option.active { background: rgba(var(--brand-rgb), .08); }

/* Bottom actions row */
.nav-bottom-actions {
    display: none;
    gap: 4px;
    margin-bottom: 4px;
}
.nav-collapse-btn {
    flex: 1;
    padding: 6px;
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    border-radius: var(--radius-xs);
    transition: background .15s;
    text-decoration: none;
    text-align: center;
}
.nav-collapse-btn:hover { background: var(--subtle); color: var(--text); opacity: 1; }
.nav-collapse-btn svg { display: block; margin: 0 auto; transition: transform .2s; }
.nav-user {
    flex: 1;
    overflow: hidden;
}
.nav-user-name {
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nav-user-role {
    font-size: 10px;
    color: var(--muted);
}

/* --- Topbar (mobile) --- */
.topbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--card);
    border-bottom: 1px solid var(--border);
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 99;
}
.topbar-menu-btn {
    background: none;
    border: none;
    color: var(--text);
    padding: 4px;
    cursor: pointer;
}
.topbar-menu-btn svg { width: 20px; height: 20px; }
.topbar-title {
    flex: 1;
    font-size: 15px;
    font-weight: 700;
}
.topbar-actions {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Topbar user/avatar */
.topbar-user {
    display: flex;
    align-items: center;
    text-decoration: none;
    margin-left: 2px;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}
.topbar-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--border);
    transition: border-color .15s;
}
.topbar-user:hover .topbar-avatar { border-color: var(--brand); }
.topbar-avatar-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--card2);
    color: var(--muted);
    font-size: 13px;
    font-weight: 700;
}

/* Topbar user dropdown */
.topbar-user-wrap { position: relative; }
.topbar-user-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    width: 200px;
    background: var(--card);
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(0,0,0,.15);
    z-index: 60;
    overflow: hidden;
}
.topbar-user-info {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
}
.topbar-user-name { font-size: 13px; font-weight: 600; }
.topbar-user-email { font-size: 11px; color: var(--muted); }
.topbar-user-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 12px;
    font-size: 12px;
    color: var(--text);
    text-decoration: none;
    transition: background .1s;
    background: none;
    border: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
    font-family: inherit;
}
.topbar-user-item:hover { background: var(--subtle); opacity: 1; }
.topbar-user-logout { color: var(--red); }

/* Hover dropdown - bridge tussen avatar en dropdown */
.topbar-user-wrap::before {
    content: '';
    position: absolute;
    top: 100%;
    right: 0;
    width: 220px;
    height: 12px;
    display: none;
}
.topbar-user-wrap:hover::before { display: block; }
.topbar-user-wrap:hover .topbar-user-dropdown,
.topbar-user-dropdown:hover {
    display: block !important;
}

/* --- Main content --- */
.main {
    flex: 1;
    padding: 68px 16px 16px;
    min-width: 0;
    max-width: 100%;
}

/* --- Cards --- */
.card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.card-header {
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.card-header h2 { margin: 0; }
.card-body { padding: 16px; }
.card-footer {
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}

/* --- Een kaart die je open- en dichtklapt --- */
/* .card-header zet justify-content:space-between, en dat duwt de titel en de toelichting naar
   de twee randen. Alleen display:flex zetten helpt dus niet; het gaat om die uitlijning zelf.
   Geen driehoekje of ander teken ervoor: de kop is klikbaar en dat is genoeg. */
details.card { overflow: hidden; }
details.card > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: baseline;
    gap: 10px;
    justify-content: flex-start;
}
details.card > summary::-webkit-details-marker { display: none; }
/* Het pijltje. Stond in vier instelviews apart, en in de andere zes die `details.card` gebruiken
   dus niet - daar klapte een kaart open zonder dat er iets aanwees dat dat kon. */
details.card > summary::after {
    content: ''; width: 16px; height: 16px; flex-shrink: 0; transition: transform .2s;
    background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") no-repeat center;
}
details[open].card > summary::after { transform: rotate(180deg); }
details[open].card > summary { border-bottom-color: var(--border); }

/* === Instellingen: de inhoudsopgave in de kantlijn ===================================
 *
 * Eerst kregen categorieën tot zes regels een tabbalk en de rest niets. Per scherm te verdedigen, maar
 * zes van de negen hadden een balk en drie niet - en dan ziet de gebruiker geen regel maar willekeur.
 * Een kolom staat er altijd, toont de hele structuur, laat zien waar je bent, en werkt bij
 * zesenvijftig regels waar een balk dat niet kan.
 */
.set-blad { display: grid; grid-template-columns: 232px minmax(0, 1fr); gap: 24px; align-items: start; }
.set-inhoud { min-width: 0; }

.set-nav { position: sticky; top: 16px; font-size: 13px; }
.set-nav-zoek { position: relative; margin-bottom: 12px; }
.set-nav-treffers {
    position: absolute; top: 100%; left: 0; right: 0; z-index: 20; margin-top: 4px;
    max-height: 340px; overflow-y: auto; background: var(--card);
    border: 1px solid var(--border); border-radius: var(--radius);
    box-shadow: 0 4px 16px rgba(0,0,0,.08);
}
/* De treffers stonden met inline-stijl in de javascript die ze maakte, inclusief twee
   onmouseover-handlers voor de hover. Dat werkt, maar dan staat de opmaak buiten het stijlblad en
   doet de hover het niet met het toetsenbord. */
.set-nav-treffers a { display: block; padding: 8px 12px; text-decoration: none; color: var(--text);
    border-bottom: 1px solid var(--border); }
.set-nav-treffers a:last-child { border-bottom: 0; }
.set-nav-treffers a:hover, .set-nav-treffers a:focus { background: var(--card2); }
.set-nav-treffer-naam { display: block; font-weight: 500; }
.set-nav-treffer-sub { display: block; font-size: 11px; color: var(--muted); margin-top: 1px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.set-nav-groep > summary { list-style: none; cursor: pointer; padding: 6px 8px; border-radius: 6px;
    font-weight: 600; font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
    color: var(--muted); display: flex; align-items: center; gap: 6px; }
.set-nav-groep > summary::-webkit-details-marker { display: none; }
/* Eén pijl die draait, in plaats van twee tekens die elkaar aflossen.
   Zelf getekend met twee randen: ▸ was op 9px nauwelijks te zien, en ▸ en ▾ hebben niet dezelfde
   optische zwaarte en niet dezelfde basislijn, dus het sprong bij elke klik een pixel op en neer.
   currentColor houdt hem gelijk aan de kop, ook in het donkere thema. */
.set-nav-groep > summary::before { content: ''; flex: none; width: 7px; height: 7px; margin: 0 2px;
    border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg); transition: transform .15s ease; }
.set-nav-groep[open] > summary::before { transform: rotate(45deg); }
.set-nav-groep > summary a { color: inherit; text-decoration: none; }
.set-nav-groep > summary:hover { background: var(--card2); }

.set-nav-groep ul { list-style: none; margin: 2px 0 8px; padding: 0 0 0 16px; }
.set-nav-groep li a { display: block; padding: 5px 8px; border-radius: 6px; color: var(--text);
    text-decoration: none; }
.set-nav-groep li a:hover { background: var(--card2); }
/* Waar je bent. Een streep en niet een kleurvlak: het is een plaatsaanduiding en geen knop. */
.set-nav-groep li.aan a { font-weight: 600; box-shadow: inset 2px 0 0 var(--brand); background: var(--card2); }

/* Smal scherm: de kolom gaat boven de inhoud staan en klapt dicht. Dan is `terug` in de kopregel de
   korte weg, en die staat er daarom nog. */
@media (max-width: 900px) {
    .set-blad { grid-template-columns: 1fr; gap: 12px; }
    .set-nav { position: static; }
}

/* Een scheidingslijn tussen twee instellingen in dezelfde kaart.
   Stond zes keer apart in een view gedefinieerd en werd op acht plekken gebruikt, dus op drie plekken
   (account, ai, de takenhook) tekende hij niets. Eén regel, hier. */
.settings-row { padding-top: 14px; margin-top: 16px; border-top: 1px solid var(--border); }
details.card > summary::marker { content: ""; }
details.card > summary h2 { margin: 0; }
details.card > summary .row-sub { font-weight: 400; }
details.card > summary .btn,
details.card > summary form { margin-left: auto; align-self: center; }

/* Zonder card-body zit de tabel tegen de rand van de kaart. */
details.card > .table-wrap, details.card > table { margin: 0; }
details.card > *:not(summary):not(.card-body) { padding: 0; }
details.card > .card-body { padding-top: 10px; }

/* --- Insights --- */
.insights-grid { display: flex; flex-direction: column; gap: 8px; }
.insight-card {
    display: flex;
    gap: 12px;
    padding: 12px 16px;
    background: var(--card);
    border: 1px solid var(--border);
    border-left: 3px solid var(--brand);
    border-radius: var(--radius);
    transition: opacity .2s;
}
.insight-icon { width: 18px; height: 18px; color: var(--brand); flex-shrink: 0; margin-top: 2px; }
.insight-icon svg { width: 18px; height: 18px; }
.insight-body { flex: 1; min-width: 0; }
.insight-title { font-size: 13px; font-weight: 600; }
.insight-desc { font-size: 12px; color: var(--muted); margin-top: 2px; }
.insight-actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }

/* --- KPI Cards --- */
.kpi-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 10px;
    margin-bottom: 16px;
}
.kpi-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-width: 0;
    overflow: hidden;
    transition: border-color .15s, transform .15s, box-shadow .15s;
}
.kpi-card:hover { border-color: var(--border2); }
a.kpi-card { text-decoration: none; color: inherit; }
a.kpi-card.kpi-clickable { cursor: pointer; }
a.kpi-card.kpi-clickable:hover { border-color: var(--brand); transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0,0,0,.04); }
a.kpi-card.kpi-clickable:hover .kpi-icon { background: rgba(var(--brand-rgb), .1); }
a.kpi-card.kpi-clickable:hover .kpi-icon svg { color: var(--brand); }
.kpi-icon {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-sm);
    background: var(--card2);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.kpi-icon svg { width: 16px; height: 16px; color: var(--muted); }
.kpi-value { font-size: 22px; font-weight: 700; line-height: 1.2; }
.kpi-label { font-size: 11px; color: var(--muted); }

/* --- Jaarkiezer ---
   Eén kaart met de jaren erin, zodat hij in dezelfde rij past als de kerngetallen ernaast.
   Als losse rij eronder zweefde hij, en als vier eigen kaarten nam hij de plek in van cijfers
   die belangrijker zijn. */
.jaarkiezer { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.jaarkiezer a {
    display: inline-flex;
    flex-direction: column;
    gap: 1px;
    padding: 5px 9px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    text-decoration: none;
    color: var(--text);
    font-size: 12px;
    line-height: 1.2;
    transition: border-color .15s, background .15s;
}
.jaarkiezer a:hover { border-color: var(--brand); }
.jaarkiezer a.aan { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 10%, var(--card)); font-weight: 600; }
.jaarkiezer .jaarkiezer-sub { font-size: 10px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* --- Buttons --- */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 13px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border2);
    background: var(--card2);
    color: var(--text);
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: all .15s;
    white-space: nowrap;
    font-family: inherit;
}
.btn:hover { border-color: var(--brand); color: var(--brand); }
.btn svg { width: 13px; height: 13px; }

.btn-primary {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
}
.btn-primary:hover { opacity: .88; color: #fff; }

.btn-danger {
    background: rgba(239, 68, 68, .1);
    border-color: var(--red);
    color: var(--red);
}
.btn-danger:hover { background: var(--red); color: #fff; }

.btn-ghost {
    background: transparent;
    border-color: transparent;
}
.btn-ghost:hover { background: var(--subtle); border-color: var(--border); }

.btn.active {
    color: var(--brand);
    border-color: var(--brand);
    background: color-mix(in srgb, var(--brand) 10%, transparent);
}
.btn.active:hover { color: var(--brand); border-color: var(--brand); }

.btn-sm { padding: 4px 9px; font-size: 11px; }
.btn-icon {
    width: 32px;
    height: 32px;
    padding: 0;
    justify-content: center;
}

/* --- Forms --- */
.form-row { margin-bottom: 14px; }
/* Custom fields auto-grid: korte velden naast elkaar, lange velden over alle kolommen. */
.cf-fields-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0 16px;
}
.cf-fields-grid .form-row { margin-bottom: 14px; }
.cf-fields-grid .cf-wide,
.cf-fields-grid .line-section { grid-column: 1 / -1; }
@media (max-width: 700px) {
    .cf-fields-grid { grid-template-columns: 1fr; }
}
.form-row-2,
.form-row-3,
.form-row-4 {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
    margin-bottom: 14px;
}
/* Auto-vullend veldraster: vormt kolommen zodra er ruimte is, stapelt op smal. */
.field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
    margin-bottom: 14px;
}
/* Tegel-grid met klikbare cards (Settings, Help, etc.) */
.settings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 12px;
}
.settings-card {
    display: flex;
    gap: 12px;
    padding: 16px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--text);
    transition: all .15s;
}
.settings-card:hover {
    border-color: var(--brand);
    background: var(--card2);
    transform: translateY(-1px);
}
.settings-card-icon {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(var(--brand-rgb), .08);
    color: var(--brand);
    border-radius: var(--radius-xs);
}
.settings-card-body { min-width: 0; }
.settings-card .row-title { font-weight: 500; margin-bottom: 2px; }
.settings-card .row-sub { font-size: 12px; color: var(--muted); }
/* Een kopje binnen een formulier.
 *
 * Een formulier van vijftien velden onder elkaar is een lijst, geen vorm: je leest hem van
 * boven naar beneden om te zien of er nog iets komt. Met kopjes erin zie je in een oogopslag
 * waar je moet zijn - en zie je ook dat je klaar bent. Bewust een regel en geen kaart per
 * blok: kaders om kaders maken het formulier zwaarder dan het is. */
.form-sectie {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--muted);
    padding-bottom: 6px;
    margin: 22px 0 14px;
    border-bottom: 1px solid var(--border);
}
.form-sectie.is-eerste { margin-top: 0; }

.form-label {
    display: block;
    font-size: 10px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .05em;
    margin-bottom: 5px;
}
/* Een invoerveld groeit niet verder mee dan je kunt overzien.
   Zonder deze grens werd een naamveld op een breed scherm 1600 pixels breed: je typt links en
   de rand zit ergens rechts buiten je blikveld. 560 is ruim genoeg voor een e-mailadres of een
   bedrijfsnaam, en velden die in een raster staan blijven gewoon hun kolom volgen.
   Een eigen breedte in de opmaak van een scherm wint hier altijd van. */
.form-input {
    width: 100%;
    max-width: 560px;
    background: var(--card2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 9px 11px;
    font-size: 16px;
    color: var(--text);
    font-family: inherit;
    transition: border-color .15s, box-shadow .15s;
}
.form-input:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(var(--brand-rgb), .1);
}
.form-input::placeholder { color: var(--muted); }

/* Een tekstvak bevat hele zinnen, dus die mag breder - maar niet onbeperkt, want een regel van
   1800 pixels lees je niet terug. */
textarea.form-input { max-width: 820px; }

/* In een raster bepaalt de kolom de breedte; daar is de grens overbodig en soms in de weg. */
.form-row-2 .form-input,
.form-row-3 .form-input,
.form-row-4 .form-input,
.field-grid .form-input,
.cf-fields-grid .form-input,
.card-body > form .flex .form-input { max-width: 100%; }

/* Datum en tijd op iOS.
 *
 * Safari geeft die velden zijn eigen opmaak: een andere hoogte, een eigen binnenmarge en tekst
 * die niet links uitlijnt met de rest. Op een iPad staat zo'n veld dus net iets anders dan het
 * tekstveld ernaast, en dat zie je meteen. appearance uit, en dezelfde hoogte afdwingen als de
 * andere velden; min-height omdat een leeg datumveld anders inklapt. */
input[type="date"].form-input,
input[type="time"].form-input,
input[type="datetime-local"].form-input,
input[type="month"].form-input {
    appearance: none;
    -webkit-appearance: none;
    min-height: 40px;
    line-height: 20px;
    text-align: left;
}
/* Het klokje of kalendertje rechts, zodat het veld niet leeg oogt zonder waarde. */
input[type="date"].form-input::-webkit-date-and-time-value,
input[type="time"].form-input::-webkit-date-and-time-value,
input[type="datetime-local"].form-input::-webkit-date-and-time-value {
    text-align: left;
    margin: 0;
}
input[type="date"].form-input::-webkit-calendar-picker-indicator,
input[type="time"].form-input::-webkit-calendar-picker-indicator {
    opacity: .55;
    margin-left: auto;
}

select.form-input {
    cursor: pointer;
    appearance: none;
    background-image: 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='%2364748b' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 30px;
}

textarea.form-input {
    resize: vertical;
    min-height: 80px;
}

/* File input */
input[type="file"] {
    font-size: 12px;
    color: var(--muted);
    padding: 8px 0;
}
input[type="file"]::file-selector-button {
    background: var(--card2);
    border: 1px solid var(--border2);
    border-radius: var(--radius-xs);
    padding: 5px 12px;
    font-size: 11px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
    font-family: inherit;
    margin-right: 8px;
    transition: all .15s;
}
input[type="file"]::file-selector-button:hover {
    border-color: var(--brand);
    color: var(--brand);
}

/* Toggle switch */
.toggle {
    /* inline-block, want een label is van zichzelf inline en dan doen breedte en hoogte niets.
       Dat viel niet op omdat hij overal in een flex- of grid-blok stond en daar alsnog een
       eigen doos kreeg; in een tabelcel klapte hij dicht en zag je helemaal niets. */
    display: inline-block;
    vertical-align: middle;
    position: relative;
    width: 38px;
    height: 21px;
    cursor: pointer;
}
.toggle input { display: none; }
.toggle-slider {
    position: absolute;
    inset: 0;
    background: var(--card2);
    border: 1px solid var(--border2);
    border-radius: 99px;
    transition: all .2s;
}
.toggle-slider::before {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 13px;
    height: 13px;
    background: var(--muted);
    border-radius: 50%;
    transition: all .2s;
}
.toggle input:checked + .toggle-slider {
    background: var(--brand);
    border-color: var(--brand);
}
.toggle input:checked + .toggle-slider::before {
    background: #fff;
    transform: translateX(17px);
}

/* --- Tables --- */
.table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
table {
    width: 100%;
    border-collapse: collapse;
}
th {
    text-align: left;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
td {
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    font-size: 13px;
}
/* Een tabel met veel kolommen. Twaalf getallen naast elkaar passen niet op een laptop met de
   standaard binnenmarge, en dan schuift het scherm horizontaal: dat leest slecht en je mist
   precies de kolom rechts waar het om ging. Minder ruimte tussen de kolommen scheelt genoeg. */
.table.dicht th,
.table.dicht td { padding: 8px 7px; }
.table.dicht td { font-size: 12.5px; }
.table.dicht th:first-child,
.table.dicht td:first-child { padding-left: 12px; }
.table.dicht th:last-child,
.table.dicht td:last-child { padding-right: 12px; }

tr:last-child td { border-bottom: none; }
tr:hover td { background: var(--subtle); }

/* --- Table component (dryve-table) --- */
.dryve-table {
    overflow: hidden;
}
.dryve-table-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin-bottom: 12px;
}
.dryve-table-filters {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;
    width: 100%;
}
.dryve-table-filters .form-input {
    width: 100%;
    min-width: 0;
    font-size: 12px;
    padding: 6px 8px;
}
.dryve-table-actions {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}
.dryve-table-count {
    font-size: 13px;
    color: var(--muted);
    padding: 6px 10px;
    background: var(--subtle);
    border-radius: var(--radius-sm);
    flex-shrink: 0;
    cursor: help;
}
.table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}
@media (min-width: 768px) {
    .form-input { font-size: 13px; }
    .dryve-table-filters { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}

/* --- Rows (settings style) --- */
.row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 16px;
    border-bottom: 1px solid var(--border);
}
.row:last-child { border-bottom: none; }
.row-icon {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-sm);
    background: var(--card2);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.row-icon svg { width: 14px; height: 14px; color: var(--muted); }
.row-body { flex: 1; min-width: 0; }
.row-title { font-size: 13px; font-weight: 600; }
.row-sub { font-size: 11px; color: var(--muted); }
.row-actions { display: flex; gap: 6px; flex-shrink: 0; }

/* --- Notification bell --- */
.topbar-timer { display: flex; align-items: center; }
.topbar-timer-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 10px;
    background: var(--card2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    transition: all .15s;
    font-family: inherit;
    font-variant-numeric: tabular-nums;
}
.topbar-timer-btn:hover { background: var(--subtle); }
.topbar-timer-btn.is-running { background: rgba(var(--brand-rgb), .15); border-color: var(--brand); color: var(--brand); }
.topbar-timer-btn svg { display: block; }

.notif-bell {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 1.5px solid var(--border);
    background: var(--card);
    color: var(--text);
    transition: background .15s;
    text-decoration: none;
}
.notif-bell:hover { background: var(--subtle); opacity: 1; }
.notif-bell svg { display: block; }
.notif-bell.has-unread svg {
    animation: bellShake 0.5s ease-in-out;
    animation-iteration-count: 1;
}
.notif-bell.has-unread { animation: bellRemind 8s ease-in-out infinite; }
@keyframes bellShake {
    0%, 100% { transform: rotate(0); }
    15% { transform: rotate(14deg); }
    30% { transform: rotate(-12deg); }
    45% { transform: rotate(8deg); }
    60% { transform: rotate(-6deg); }
    75% { transform: rotate(2deg); }
}
@keyframes bellRemind {
    0%, 90%, 100% { transform: rotate(0); }
    92% { transform: rotate(10deg); }
    94% { transform: rotate(-8deg); }
    96% { transform: rotate(5deg); }
    98% { transform: rotate(-3deg); }
}
.notif-bell-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 14px;
    height: 14px;
    padding: 0 4px;
    border-radius: 20px;
    background: var(--brand);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

/* --- Kanban board --- */
.kanban-board {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    padding-bottom: 16px;
    -webkit-overflow-scrolling: touch;
}
.kanban-col {
    min-width: 260px;
    flex: 1;
    display: flex;
    flex-direction: column;
}
/* Vlakken delen één ronding, labels zijn capsules.
 *
 * Dat is de regel waar dit op uitkomt. Het wringende zat niet in de pil maar in de maten
 * eromheen: de kop deed 8, de kaart 9, en het tokenstelsel houdt 10/7/5 aan. Drie maten die
 * niemand ooit gekozen heeft. Nu allebei var(--radius), en de pil mag capsule blijven - dat is
 * geen vlak maar een woord met een kleur eromheen.
 *
 * (Het vlak onder de kop is er even af geweest. Zonder dat vlak wordt het bord luchtiger, maar
 * de kop valt dan uit elkaar in losse onderdelen en dat weegt niet op tegen de winst.)
 */
.kanban-col-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 10px 12px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 8px;
}

/* Links wat de kolom ís - de naam en, waar dat speelt, het bedrag dat erin omgaat. Rechts wat
 * je ermee doet: het aantal en de knop. Het bedrag staat naast de naam en niet eronder, want
 * een kop van twee regels laat de kaarten eronder verspringen zodra één kolom een bedrag heeft
 * en de andere niet. */
.kanban-col-regel {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.kanban-col-regel .row-sub { white-space: nowrap; }
.kanban-col-title {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
}
/* Is de kop zelf een pil, dan doet de kleur het werk en hoeven de kapitalen niet meer. Zonder
   dit staat er een geschreeuwde regel in een gekleurd bolletje, en dat leest slechter dan de
   grijze variant die er stond. De klasse blijft staan voor het inklappen: app.js zoekt de
   kolomnaam op .kanban-col-title.

   En hij is groter dan een gewone badge. Dezelfde vorm betekent niet dezelfde maat: op een
   kaart is een badge een bijschrift bij iets anders, hier is hij de titel van de hele kolom.
   Op 10px las de kop als het kleinste op het scherm terwijl hij het eerste hoort te zijn. */
.kanban-col-title.badge {
    text-transform: none;
    letter-spacing: 0;
    padding: 4px 12px;
    font-size: 12px;
    line-height: 1.35;
}
.kanban-col-body {
    min-height: 100px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1;
}
.kanban-col-body.drag-over {
    background: rgba(var(--brand-rgb), .05);
    border-radius: 8px;
}
.kanban-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px;
    cursor: grab;
    transition: all .15s;
}
.kanban-card:hover {
    border-color: var(--border2);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .08);
}
.kanban-card.dragging { opacity: .5; }
.kanban-card-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    text-decoration: none;
    display: block;
    margin-bottom: 4px;
}
.kanban-card-title:hover { color: var(--brand); opacity: 1; }
.kanban-card-meta {
    font-size: 11px;
    color: var(--muted);
}

/* Een kolom die je erbij wilt houden maar niet elke dag hoeft te lezen - afgewezen, geparkeerd -
   klapt in tot een strook met de naam en het aantal erop. Hij staat er nog, hij vraagt alleen je
   blik niet meer. De klik zit op de hele kop, de chevron zegt welke kant het op gaat. */
.kanban-col-head { cursor: pointer; }
.kanban-col-rechts { display: flex; align-items: center; gap: 6px; }
.kanban-col-klap { display: inline-flex; color: var(--muted); opacity: .4; transition: opacity .15s; }
.kanban-col-head:hover .kanban-col-klap { opacity: 1; }

.kanban-col.is-ingeklapt { min-width: 44px; flex: 0 0 44px; }
.kanban-col.is-ingeklapt .kanban-col-head {
    flex: 1;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    gap: 10px;
    padding: 10px 4px;
    margin-bottom: 0;
}
/* Ingeklapt staat alles onder elkaar in een strook van 44 pixels: eerst de naam, gedraaid,
   daaronder het aantal en de knop. Blijft de rij horizontaal, dan schuift het aantal de strook
   uit en zweeft het los naast het bord. */
.kanban-col.is-ingeklapt .kanban-col-rechts { flex-direction: column; }
.kanban-col.is-ingeklapt .kanban-col-regel { flex-direction: column; }
.kanban-col.is-ingeklapt .kanban-col-naam {
    writing-mode: vertical-rl;
    white-space: nowrap;
    max-height: 260px;
    overflow: hidden;
}
/* Gedraaid wisselen de assen van betekenis: de 12 pixels die staand links en rechts van de
   tekst stonden zijn liggend de dikte van de strook, en dan wordt een pil van 44 breed een
   worst. Ruim langs de leesrichting, smal dwars erop. */
.kanban-col.is-ingeklapt .kanban-col-title.badge {
    padding: 10px 4px;
    font-size: 11px;
}
/* Bedragen onder de kolomnaam zijn in een strook van 44 pixels toch niet te lezen. */
.kanban-col.is-ingeklapt .kanban-col-body,
.kanban-col.is-ingeklapt .kanban-col-head .row-sub { display: none; }

/* --- Search modal (mobile-friendly) --- */
.search-modal {
    max-width: 560px;
    margin-top: 60px;
    align-self: flex-start;
    overflow: hidden;
}
.search-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
    padding: 0 14px;
    border-bottom: 1px solid var(--border);
}
.search-input-icon { color: var(--muted); flex-shrink: 0; }
.search-input {
    flex: 1;
    border: none;
    outline: none;
    background: transparent;
    padding: 16px 12px;
    font-size: 16px; /* >=16px voorkomt iOS-zoom op focus */
    color: var(--text);
    font-family: inherit;
    min-width: 0;
}
.search-input::-webkit-search-cancel-button { display: none; }
.search-input-close {
    background: none;
    border: none;
    padding: 8px;
    color: var(--muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    border-radius: 6px;
}
.search-input-close:hover { background: var(--card2, #f4f4f5); color: var(--text); }
.search-results {
    max-height: 60vh;
    overflow-y: auto;
    padding: 8px;
    -webkit-overflow-scrolling: touch;
}

/* Topbar zoek-knop (alleen op mobile zichtbaar) */
.topbar-search-btn {
    /* Ook op desktop zichtbaar. Cmd+K en de spatiebalk werken al, maar een sneltoets die je
       nergens ziet bestaat voor de meeste mensen niet. De knop laat de sneltoets zien in plaats
       van hem te vervangen. */
    display: inline-flex;
    background: var(--card);
    border: 1.5px solid var(--border);
    border-radius: 50%;
    width: 30px;
    height: 30px;
    align-items: center;
    justify-content: center;
    color: var(--text);
    cursor: pointer;
    margin-right: 4px;
    flex-shrink: 0;
}
@media (max-width: 900px) {
    .search-modal {
        margin-top: 0;
        max-width: 100%;
        max-height: 100%;
        height: 100dvh;
        border-radius: 0;
        align-self: stretch;
    }
    .search-modal .modal-body { height: 100%; display: flex; flex-direction: column; }
    .search-results { flex: 1; max-height: none; }
}

/* --- Modal --- */
.overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .6);
    backdrop-filter: blur(4px);
    z-index: 100;
    align-items: center;
    justify-content: center;
    padding: 16px;
}
.overlay.open { display: flex; }

.modal {
    background: var(--card);
    border: 1px solid var(--border2);
    border-radius: 14px;
    width: 100%;
    max-width: 500px;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
}
.modal-head {
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.modal-title { font-size: 15px; font-weight: 700; }
.modal-close {
    background: none;
    border: none;
    color: var(--muted);
    font-size: 18px;
    cursor: pointer;
    border-radius: var(--radius-xs);
    padding: 2px 6px;
}
.modal-close:hover { color: var(--text); }
.modal-body { padding: 20px; }
.modal-footer {
    padding: 14px 20px;
    border-top: 1px solid var(--border);
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}

/* --- Toast (micro, bottom center) --- */
.toast {
    position: fixed;
    bottom: 20px;
    /* Gecentreerd met left/right en auto-marges, niet met left:50% plus een transform.
       Met alleen left:50% loopt de ruimte van het midden tot de rechterrand, dus op een telefoon
       paste een foutmelding in 195 pixels en werd de pil vier regels hoog terwijl de linkerhelft
       van het scherm leeg bleef. Een maximumbreedte helpt daar niet tegen: die begrenst, hij
       maakt geen ruimte. */
    left: 0;
    right: 0;
    margin: 0 auto;
    width: fit-content;
    transform: translateY(12px);
    background: var(--card);
    border: 1px solid var(--border);
    padding: 8px 16px;
    border-radius: 20px;
    font-size: 12px;
    font-weight: 600;
    box-shadow: 0 8px 32px rgba(0, 0, 0, .15);
    z-index: 10000;
    display: flex;
    align-items: center;
    gap: 6px;
    opacity: 0;
    pointer-events: none;
    transition: all .2s ease;
}
.toast.show {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
}
/* De kleur als stip en niet als randje links.
   Dat randje was 3px op een pil met een straal van 20, dus het werd afgerond tot een streepje
   van niks - precies de verkeerde plek om te bezuinigen nu de kleur ook iets betékent: groen
   verdwijnt vanzelf, rood blijft staan tot je hem wegklikt. */
.toast::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%;
                 background: var(--muted); }
.toast.success::before { background: var(--green); }
.toast.error::before   { background: var(--red); }
.toast.info::before    { background: var(--blue); }
.toast.warning::before { background: var(--amber); }
/* Een foutmelding is vaak een hele zin, en zonder breedte rekt de pil tot bijna het hele scherm.
   Op een telefoon telt dat dubbel, want daar staat hij over de inhoud heen. */
.toast { max-width: min(92vw, 560px); }
.toast-tekst { text-align: left; }
.toast-weg {
    flex: none; width: 26px; height: 26px; margin: -4px -10px -4px 2px;
    display: flex; align-items: center; justify-content: center;
    background: none; border: 0; border-radius: 50%; cursor: pointer;
    color: var(--muted); font-size: 17px; line-height: 1;
}
.toast-weg:hover { color: var(--text); background: var(--border); }

/* --- Notification toast (right side, richer) --- */
.notif-toast {
    position: fixed;
    bottom: 24px;
    right: 16px;
    left: 16px;
    background: var(--card);
    border: 1px solid var(--border2);
    border-left: 3px solid var(--brand);
    border-radius: var(--radius);
    padding: 12px 14px 10px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, .18);
    z-index: 9999;
    animation: toastIn .25s ease;
}
@keyframes toastIn {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: translateY(0); }
}
.notif-toast-title { font-size: 12px; font-weight: 600; margin-bottom: 4px; }
.notif-toast-body { font-size: 11px; color: var(--muted); line-height: 1.5; }
.notif-toast-close {
    position: absolute;
    top: 10px;
    right: 10px;
    background: none;
    border: none;
    color: var(--muted);
    cursor: pointer;
    font-size: 14px;
}

/* --- Badges --- */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 20px;
    font-size: 10px;
    font-weight: 600;
}
.badge-green { background: rgba(34, 197, 94, .12); color: var(--green); }
.badge-red { background: rgba(239, 68, 68, .12); color: var(--red); }
.badge-blue { background: rgba(79, 127, 255, .12); color: var(--blue); }
.badge-amber { background: rgba(245, 158, 11, .12); color: var(--amber); }
.badge-orange { background: rgba(249, 115, 22, .12); color: var(--orange); }
.badge-purple { background: rgba(139, 92, 246, .14); color: var(--purple); }
.badge-muted { background: var(--subtle); color: var(--muted); }
/* Er stond op een paar plekken badge-grey terwijl die klasse niet bestaat: dan valt de kleur
   gewoon weg en zie je een label zonder achtergrond, zonder dat iets erop wijst dat er iets mis
   is. Vandaar deze regel, en niet een zoek-en-vervang door alle schermen heen. */
.badge-grey { background: var(--subtle); color: var(--muted); }
/* Een badge in een regel tekst (de subregel op een kaartje, een lijstregel) zakt anders naar de
   onderkant, omdat hij inline-flex is. */
.row-sub .badge { vertical-align: middle; }

/* --- Timeline (chatter) --- */
.timeline { position: relative; padding-left: 12px; }
.timeline::before {
    content: '';
    position: absolute;
    left: 23px;
    top: 8px;
    bottom: 8px;
    width: 1px;
    background: var(--border);
}
.timeline-item {
    display: flex;
    gap: 12px;
    position: relative;
    padding: 8px 0;
}
.timeline-icon {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    z-index: 1;
    background: var(--card2)!important;
}
.timeline-icon svg { width: 12px; height: 12px; }
.timeline-body { flex: 1; padding-bottom: 8px; }
.timeline-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 2px;
}
.timeline-title a { color: inherit; text-decoration: none; }
.timeline-title a:hover { color: var(--brand); opacity: 1; }
.timeline-content {
    font-size: 12px;
    color: var(--muted);
    margin-bottom: 4px;
    line-height: 1.5;
}
.timeline-meta {
    font-size: 10px;
    color: var(--muted);
}

/* --- Tag pill (selector) --- */
.tag-pill {
    cursor: pointer;
    border: 1px solid transparent;
    border-radius: 20px;
    padding: 0;
    transition: all .15s;
    user-select: none;
}
.tag-pill span {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 20px;
    font-size: 11px;
    font-weight: 600;
    opacity: .4;
    transition: opacity .15s;
}
.tag-pill:has(input:checked) span { opacity: 1; }

/* --- Empty state --- */
.empty-state {
    text-align: center;
    padding: 40px 20px;
    color: var(--muted);
}
.empty-state svg { width: 40px; height: 40px; margin-bottom: 12px; opacity: .4; }
.empty-state p { font-size: 13px; }

/* --- Cookie consent --- */
.cookie-consent {
    position: fixed;
    bottom: 16px;
    left: 16px;
    right: 16px;
    max-width: 600px;
    margin: 0 auto;
    background: var(--card);
    border: 1px solid var(--border2);
    border-radius: var(--radius);
    padding: 14px 18px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, .2);
    display: flex;
    align-items: center;
    gap: 16px;
    z-index: 9999;
    font-size: 12px;
    color: var(--text);
}
.cookie-consent-text { flex: 1; }
.cookie-consent-text a { color: var(--brand); font-weight: 600; }

/* --- Powered by inlyn --- */
.powered-by, .powered-by-fixed {
    font-size: 10px;
    color: var(--muted);
    display: flex;
    align-items: center;
    gap: 4px;
}
.powered-by { text-align: center; padding: 16px; justify-content: center; }
.powered-by-fixed {
    padding: 16px;
    justify-content: center;
}
.powered-by a, .powered-by-fixed a { color: inherit; text-decoration: none; }
.inlyn-wordmark {
    font-family: 'Rubik', sans-serif;
    font-weight: 900;
    font-size: 13px;
    letter-spacing: -.06em;
    color: var(--text);
}
.inlyn-dot { color: #fd3d3a; }

/* --- Pagination --- */
.pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 16px 0;
}
.pagination-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--text);
    font-size: 12px;
    font-weight: 500;
    text-decoration: none;
    transition: all .15s;
}
.pagination-btn:hover { border-color: var(--brand); color: var(--brand); opacity: 1; }
.pagination-btn.active {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
}
.pagination-dots {
    font-size: 12px;
    color: var(--muted);
    padding: 0 4px;
}

/* --- Search results --- */
.search-result {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    color: var(--text);
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: background .1s;
    margin: 2px 4px;
}
.search-result:hover { background: var(--subtle); opacity: 1; }
.search-result-label { font-size: 13px; font-weight: 500; }
.search-result-sub { font-size: 11px; color: var(--muted); flex: 1; }
.search-result-type {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    color: var(--muted);
    background: var(--card2);
    padding: 2px 6px;
    border-radius: 4px;
    margin-left: auto;
}
.search-group-head {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--muted);
    padding: 10px 12px 4px;
    letter-spacing: .04em;
}

/* De detailkeuze op het kanbanbord gebruikt nu .zoom - zie core/Kop.php. De eigen stijl die
   hier stond deed hetzelfde met andere maten en dat viel op zodra de twee naast elkaar
   kwamen te staan. */

/* Mode-specific hiding regels (cards moeten data-kanban-modeable parent hebben) */
.kanban-mode-compact .kanban-meta-extra,
.kanban-mode-compact .kanban-card-meta,
.kanban-mode-compact .kanban-card-badges { display: none !important; }

.kanban-mode-normal .kanban-meta-extra { display: none !important; }

/* Uitgebreid = alles zichtbaar, geen hide-regels nodig */
@media (max-width: 900px) {
    .search-result { padding: 14px 16px; min-height: 44px; }
    .search-result-label { font-size: 15px; }
    .search-result-sub { font-size: 13px; }
}

/* --- Utility --- */
.flex { display: flex; }
.flex-between { display: flex; justify-content: space-between; align-items: center; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.gap-4 { gap: 4px; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mb-8 { margin-bottom: 8px; }
.mb-16 { margin-bottom: 16px; }

/* Deze ontbraken, terwijl mt-4 in tweeënveertig views wordt gebruikt en mb-12 in twaalf. Die
   ruimte deed dus nergens iets: het stond er wel, het gebeurde niet. Vandaar de hele reeks in
   één keer, op dezelfde schaal als de rest. */
.mt-4  { margin-top: 4px; }
.mt-12 { margin-top: 12px; }
.mt-24 { margin-top: 24px; }
.mb-4  { margin-bottom: 4px; }
.mb-12 { margin-bottom: 12px; }
.mb-24 { margin-bottom: 24px; }

/* Een kop boven een blok, met lucht erboven zodat hij niet aan de vorige kaart plakt. */
.sectie-kop { font-size: 13px; font-weight: 600; margin: 28px 0 4px; }
.sectie-kop:first-child { margin-top: 0; }
.p-16 { padding: 16px; }
.hidden { display: none !important; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.w-full { width: 100%; }

/* ============================================
   Tablet (>= 640px) — large phones landscape, kleine tablets
   ============================================ */
@media (min-width: 640px) {
    .kpi-grid { grid-template-columns: repeat(2, 1fr); }
    .form-row-2 { grid-template-columns: 1fr 1fr; }
    /* Op een tablet zijn drie of vier smalle keuzelijsten naast elkaar onleesbaar; die gaan
       eerst in tweeen en pas op een breed scherm helemaal naast elkaar. */
    .form-row-3, .form-row-4 { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 1000px) {
    .form-row-3 { grid-template-columns: repeat(3, 1fr); }
    .form-row-4 { grid-template-columns: repeat(4, 1fr); }
}

/* ============================================
   Desktop (>= 768px) — tablets portrait/landscape, sidebar zichtbaar
   ============================================ */
@media (min-width: 768px) {

    /* Nav altijd zichtbaar */
    .nav {
        transform: translateX(0);
        position: fixed;
        top: 0;
    }
    .nav-overlay { display: none !important; }
    .topbar-menu-btn { display: none; }

    /* Content naast nav */
    .main {
        margin-left: var(--nav-w);
        padding: 74px 24px 24px;
        /* Geen grens van 1400 meer. Die was er voor leesbaarheid, maar hij stond op de verkeerde
           plek: hij kapte de hele pagina terwijl alleen een tekstregel en een invoerveld te breed
           kunnen worden. Een tabel van acht kolommen zat geperst in 1352 pixels terwijl er 1100
           wit bleven, en onder de rechterkant van de bovenbalk stond niets.

           De grens staat nu op het veld en op het tekstblok, waar hij hoort. */
        max-width: calc(100vw - var(--nav-w));
    }
    .topbar {
        left: var(--nav-w);
        padding: 12px 24px;
    }

    /* Bottom actions zichtbaar op desktop */
    .nav-bottom-actions { display: flex; }

    /* Grid uitbreidingen */
    .kpi-grid { grid-template-columns: repeat(2, 1fr); }
    .form-row-2 { grid-template-columns: 1fr 1fr; }

    /* === Sidebar transitions === */
    .nav { transition: width .2s ease; }
    .main { transition: margin-left .2s ease; }
    .topbar { transition: left .2s ease; }
    .nav-logo-text-plain { transition: opacity .15s ease, width .15s ease; overflow: hidden; white-space: nowrap; }
    .nav-label { transition: opacity .15s ease, width .15s ease; overflow: hidden; white-space: nowrap; }
    .nav-user { transition: opacity .15s ease, width .15s ease; overflow: hidden; }

    /* === Compact sidebar === */
    html.nav-compact .nav { width: 56px; }
    html.nav-compact .nav-logo-text-plain { opacity: 0; width: 0; }
    html.nav-compact .nav-label { opacity: 0; width: 0; }
    html.nav-compact .nav-user { opacity: 0; width: 0; }
    html.nav-compact .nav-bottom-user { gap: 0; padding: 10px; justify-content: center; }
    html.nav-compact .nav-bottom-user svg { width: 18px; height: 18px; flex-shrink: 0; }
    html.nav-compact .nav-entity-current { justify-content: center; padding: 8px; }
    html.nav-compact .nav-entity-dropdown { left: 56px; right: auto; top: 0; width: 200px; }
    html.nav-compact .nav-logo { justify-content: center; }
    html.nav-compact .nav-logo-circle { width: 28px; height: 28px; }
    html.nav-compact .nav-top { padding: 12px 8px 8px; }
    html.nav-compact .nav-menu { padding: 4px; }
    html.nav-compact .nav-item {
        justify-content: center;
        padding: 8px;
        gap: 0;
    }
    html.nav-compact .nav-logo { gap: 0; }
    html.nav-compact .nav-item svg { width: 16px; height: 16px; }
    html.nav-compact .nav-bottom { padding: 6px 4px; }
    html.nav-compact .nav-bottom-user {
        justify-content: center;
        padding: 8px;
    }
    html.nav-compact .nav-collapse-btn svg { transform: rotate(180deg); }
    html.nav-compact .main {
        margin-left: 56px;
        max-width: calc(100vw - 56px);
    }
    html.nav-compact .topbar { left: 56px; }

    /* Powered by fixed rechtsonder */
    .powered-by-fixed {
        position: fixed;
        bottom: 12px;
        left: 50%;
        transform: translateX(-50%);
        padding: 0;
        z-index: 10;
    }

    /* Notif toast rechts */
    .notif-toast {
        left: auto;
        right: 24px;
        width: 300px;
    }
}

/* ============================================
   Large desktop (>= 1024px)
   ============================================ */
@media (min-width: 1024px) {
    .kpi-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ============================================
   Breed scherm: meer tegels naast elkaar
   ============================================

   Een tegel is een icoon van 36 pixels plus een getal. Bij drie kolommen was er 434 pixels per
   tegel, en met veertien tegels stond alles wat erna komt vijf rijen lager.

   Vaste stappen en geen auto-fit: die zou op een 27-inch negen tegels naast elkaar zetten, en dan
   is het een rij cijfers in plaats van iets dat je in een oogopslag leest.

   De stappen liggen waar het label nog op een regel past. Van een tegel gaat 76 pixels op aan
   padding en icoon, en bij de drie tegels met een balkje nog eens 60. Het langste label daarvan
   is "Per maand terugkerend" en dat vraagt 116 pixels; bij vijf kolommen haal je dat vanaf een
   scherm van 1600. Op 1500 blijft er 102 over en breekt het af. */
@media (min-width: 1400px) {
    .kpi-grid { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 1600px) {
    .kpi-grid { grid-template-columns: repeat(5, 1fr); }
}
@media (min-width: 2200px) {
    .kpi-grid { grid-template-columns: repeat(6, 1fr); }
}

/* ============================================
   Offerteregel: omschrijving naast de bedragen
   ============================================

   De omschrijving is een tekstvak waar je een paar zinnen in kwijt wilt; de bedragen ernaast zijn
   korte velden. Onder elkaar kostte dat twee keer zoveel hoogte per regel, en bij een offerte met
   acht regels scroll je jezelf suf.

   Op een smal scherm stapelt hij, want dan is een derde van de breedte geen veld meer maar een
   kolom van drie tekens. */
.quote-line-body {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
    align-items: start;
}
/* Soort, aantal en prijs horen op een regel: dat is de zin die je leest als je naar een
   offerteregel kijkt - "per maand, 1 stuk, 39 euro". Korting en btw eronder, want die zijn de
   uitzondering en niet de hoofdzaak.

   Flex en geen raster, zodat de velden de breedte krijgen die bij hun inhoud past: een soort is
   een woord of drie, een aantal is een cijfer. */
.quote-line-cijfers {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: flex-end;
}
/* Twee regels van drie. Boven wat de regel is - per maand, 1 stuk, 39 euro - en daaronder de
   uitzonderingen: korting, btw, en of de klant hem mag uitvinken. */
.quote-line-cijfers > .soort     { flex: 1 1 44%; min-width: 118px; }
.quote-line-cijfers > .aantal    { flex: 1 1 20%; min-width: 58px; }
.quote-line-cijfers > .prijs     { flex: 1 1 26%; min-width: 76px; }
.quote-line-cijfers > .korting   { flex: 1 1 28%; min-width: 96px; }
/* De btw is een keuze geworden en "0% goederen in de EU" past niet in 96 pixels. */
.quote-line-cijfers > .btw       { flex: 1 1 42%; min-width: 150px; }
.quote-line-cijfers > .optioneel { flex: 1 1 26%; min-width: 96px; }
.quote-line-cijfers > .breed     { flex: 1 1 100%; }

@media (min-width: 1024px) {
    .quote-line-body { grid-template-columns: 2fr 1fr; }
}

/* ============================================
   Leesbare tekstbreedte
   ============================================

   De pagina mag nu de volle breedte gebruiken, maar lopende tekst niet. Een alinea van 1800
   pixels lees je niet terug: je oog raakt het begin van de volgende regel kwijt. Rond de 75
   tekens is de grens, en dat is bij deze lettergrootte ongeveer 760 pixels.

   Alleen op tekst die je echt leest - de help, de uitleg bij een sectie. Een tabel of een rij
   tegels heeft er niets mee te maken. */
.help-section-body,
.help-card .card-body { max-width: 760px; }

/* ============================================
   Privacy mode: bedragen blurren als klant meekijkt
   ============================================ */
html.privacy-mode .privacy-amount {
    filter: blur(6px);
    transition: filter .15s ease;
    user-select: none;
}
html.privacy-mode .privacy-amount:hover {
    filter: blur(0);
}
html.privacy-mode #privacyIconOff { display: none; }
html.privacy-mode #privacyIconOn { display: block !important; }
html.privacy-mode #privacyToggleBtn { color: var(--brand); }

/* ============================================
   Generieke tabel UI (Table::render)
   ============================================ */
.dryve-table { display: flex; flex-direction: column; gap: 12px; }
.dryve-table-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}
.dryve-table-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1;
    min-width: 200px;
}
.dryve-table-filter {
    height: 30px;
    font-size: 12px;
    padding: 3px 8px;
    flex: 1 1 calc(50% - 3px);
    min-width: 0;
    max-width: 100%;
}
@media (min-width: 768px) {
    .dryve-table-filter {
        flex: 0 1 auto;
        min-width: 90px;
        max-width: 160px;
    }
}
.dryve-table-filter-bool {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    padding: 0 8px;
    height: 30px;
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    background: var(--card);
    cursor: pointer;
}
.dryve-table-actions {
    display: flex;
    gap: 6px;
    align-items: center;
    margin-left: auto;
}
@media (max-width: 767px) {
    .dryve-table-toolbar { flex-direction: column; align-items: stretch; }
    .dryve-table-actions { margin-left: 0; justify-content: flex-end; }
}
.dryve-table-sort {
    color: inherit;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
}
.dryve-table-sort:hover { color: var(--brand); }

.dryve-table tbody tr[data-url] { cursor: pointer; }
.dryve-table tbody tr[data-url]:hover { background: rgba(var(--brand-rgb), .04); }
.dryve-table tbody tr[data-url] td.no-click { cursor: default; }

.dryve-column-modal-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 50vh;
    overflow-y: auto;
}
.dryve-column-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-xs);
    background: var(--card);
    cursor: grab;
    font-size: 13px;
    transition: background .15s;
}
.dryve-column-row.dragging { opacity: .4; }
.dryve-column-row.drag-over { border-top: 2px solid var(--brand); }
.dryve-column-row .grip {
    color: var(--muted);
    flex-shrink: 0;
}
.dryve-column-row label {
    flex: 1;
    cursor: pointer;
    user-select: none;
}

/* Attachments */
.attachments-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.attachment-item { position: relative; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.attachment-item img { display: block; max-width: 160px; max-height: 120px; object-fit: cover; }
.attachment-item .attachment-file { display: flex; align-items: center; gap: 6px; padding: 8px 12px; font-size: 12px; color: var(--text); text-decoration: none; }
.attachment-remove { position: absolute; top: 2px; right: 2px; background: rgba(0,0,0,.6); color: #fff; border: none; border-radius: 50%; width: 20px; height: 20px; font-size: 14px; line-height: 20px; text-align: center; cursor: pointer; opacity: 0; transition: opacity .15s; }
.attachment-item:hover .attachment-remove { opacity: 1; }
.attachment-upload { margin-top: 8px; display: flex; align-items: center; gap: 10px; padding: 10px; border: 1px dashed var(--border); border-radius: 8px; transition: border-color .15s, background .15s; }
.attachment-upload.is-dragover { border-color: var(--brand); background: rgba(var(--brand-rgb), .06); }
.attachment-upload.is-dragover .attachment-drop-hint { color: var(--brand); }
.attachment-drop-hint { font-size: 12px; color: var(--muted); }
.attachment-upload-btn { cursor: pointer; flex-shrink: 0; }
.attachment-upload-btn input[type=file] { display: none; }
@media (max-width: 600px) { .attachment-drop-hint { display: none; } }

/* Rich text editor */
.rich-editor-wrap { margin-bottom: 14px; }
.rich-editor { min-height: 120px; background: var(--card2); border: 1px solid var(--border); border-radius: 0 0 8px 8px; padding: 12px; font-size: 13px; color: var(--text); line-height: 1.6; outline: none; }
.rich-editor:focus { border-color: var(--brand); }
.rich-editor ul, .rich-editor ol { padding-left: 15px; margin: 4px 0; }
.rich-editor li { margin: 2px 0; }
.rich-toolbar { display: flex; align-items: center; gap: 2px; padding: 4px; background: var(--card2); border: 1px solid var(--border); border-radius: 8px 8px 0 0; }
.rich-toolbar button { background: none; border: none; padding: 4px 8px; border-radius: 4px; font-size: 11px; color: var(--muted); cursor: pointer; display: flex; align-items: center; }
.rich-toolbar button:hover { background: var(--subtle); color: var(--text); }
.rich-sep { width: 1px; height: 16px; background: var(--border); margin: 0 4px; }
.rich-editor table, .rich-content table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 13px; }
.rich-editor th, .rich-editor td, .rich-content th, .rich-content td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
.rich-editor th, .rich-content th { background: var(--subtle); font-weight: 600; }
.rich-content ul, .rich-content ol { padding-left: 15px; margin: 4px 0; }
.rich-content li { margin: 2px 0; }
.rich-content a { color: var(--brand); text-decoration: underline; }

/* AI Drawer */
.ai-drawer {
    position: fixed;
    bottom: 0;
    right: 80px;
    width: 360px;
    max-height: 55vh;
    background: var(--card);
    border: 1px solid var(--border);
    border-bottom: none;
    border-radius: 12px 12px 0 0;
    box-shadow: 0 -4px 20px rgba(0,0,0,.1);
    z-index: 91;
    display: flex;
    flex-direction: column;
    transition: transform .3s ease;
    transform: translateY(calc(100% - 40px));
}

/* Mobile bottom nav */
.mobile-bottom-nav {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 90;
    background: var(--card);
    border-top: 1px solid var(--border);
    padding: 10px 0;
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
}
.mobile-bottom-nav-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-decoration: none;
    color: var(--muted);
    font-size: 10px;
    padding: 4px 0;
    transition: color .15s;
}
.mobile-bottom-nav-item.active { color: var(--brand); }
.mobile-bottom-nav-icon svg { width: 24px; height: 24px; }
.mobile-bottom-nav-label { font-weight: 500; line-height: 1; }

@media (max-width: 767px) {
    .mobile-bottom-nav { display: flex; }
    .main { padding-bottom: 80px; }
    .nav-menu { padding-bottom: 80px; }
    .ai-drawer { bottom: 80px; right: 16px; width: calc(100% - 32px); }
}

/* Sub-records sectie-tabel: cards op mobiel */
@media (max-width: 767px) {
    .line-table thead { display: none; }
    .line-table, .line-table tbody, .line-table tr.line-row, .line-table td {
        display: block;
        width: 100%;
    }
    .line-table tr.line-row {
        border: 1px solid var(--border);
        border-radius: 6px;
        margin-bottom: 8px;
        padding: 8px;
        background: var(--card);
        position: relative;
    }
    .line-table td {
        padding: 4px 0 !important;
        text-align: left !important;
    }
    .line-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 10px;
        color: var(--muted);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        margin-bottom: 2px;
    }
    .line-table td input,
    .line-table td select {
        text-align: left !important;
    }
    .line-table td.line-actions {
        position: absolute;
        top: 4px;
        right: 4px;
        width: auto !important;
        padding: 0 !important;
    }
}

/* --- Kopregel: titel, acties, tabs, zoom ------------------------------------
   Zie core/Kop.php voor waarom dit drie dingen zijn en niet één rij knoppen. */

.kop {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.kop-titel h1 { margin: 0; }
.kop-acties { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }

/* Tabs: zusterschermen. De balk is de verzameling, dus hij loopt door over de
   volle breedte en de actieve tab hangt eraan vast. */
.tabs {
    display: flex;
    gap: 2px;
    flex-wrap: wrap;
    border-bottom: 1px solid var(--border);
    margin: -4px 0 18px;
}
.tabs a {
    padding: 8px 13px 9px;
    margin-bottom: -1px;
    font-size: 13px;
    font-weight: 500;
    color: var(--muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    white-space: nowrap;
    transition: color .15s;
}
.tabs a:hover { color: var(--text); }
.tabs a.aan { color: var(--text); font-weight: 600; border-bottom-color: var(--brand); }
.tab-telling {
    display: inline-block;
    min-width: 17px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--subtle);
    border: 1px solid var(--border);
    font-size: 10px;
    font-weight: 600;
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.tabs a.aan .tab-telling { background: var(--brand); border-color: var(--brand); color: #fff; }

/* Zoom: dezelfde gegevens anders getekend. Aan elkaar vast, want het is één
   keuze - niet een rij losse bestemmingen. */
.zoom {
    display: inline-flex;
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    overflow: hidden;
    vertical-align: middle;
}
.zoom a,
.zoom button {
    padding: 5px 12px;
    border: 0;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    color: var(--muted);
    background: var(--card2);
    text-decoration: none;
    white-space: nowrap;
    transition: color .15s;
}
.zoom a + a,
.zoom button + button { border-left: 1px solid var(--border2); }
.zoom a:hover,
.zoom button:hover { color: var(--text); }
.zoom a.aan,
.zoom button.aan { background: var(--brand); color: #fff; }

/* Meer: alles boven de derde actie. */
.kop-meer { position: relative; }
.kop-meer-lijst {
    display: none;
    position: absolute;
    right: 0;
    top: calc(100% + 4px);
    z-index: 40;
    min-width: 172px;
    padding: 4px;
    background: var(--card);
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .13);
}
.kop-meer.open .kop-meer-lijst { display: block; }
/* Een icoonknop in de kopregel: een kanaal, of de Meer-knop.
 *
 * `padding: 0` was fout: `.btn-sm` haalt zijn hoogte uit zijn verticale padding (4px), en met nul
 * kromp de knop tot de hoogte van het tekentje zelf - zichtbaar lager dan de knoppen ernaast.
 *
 * Dus de verticale padding van `.btn-sm` overnemen en alleen horizontaal inknijpen. Plus
 * `align-self: stretch`: `.kop-acties` is een flexrij, dus dan wordt de knop exact zo hoog als zijn
 * buren - ook als iemand later aan `.btn-sm` sleutelt. Dat is zelfherstellend waar een vaste hoogte
 * dat niet is. */
.kop-kanaal,
.kop-meer-knop {
    display: inline-flex; align-items: center; justify-content: center;
    align-self: stretch; min-width: 28px; padding: 4px 6px;
}
.kop-kanaal svg,
.kop-meer-knop svg { display: block; }

/* Het kopje boven een groepje in het Meer-menu. Klein en stil: het is een scheiding, geen keuze -
   wie erop klikt hoort niets te zien gebeuren. */
.kop-meer-kopje {
    padding: 8px 12px 4px; font-size: 11px; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--muted); cursor: default; user-select: none;
}
.kop-meer-kopje:not(:first-child) { border-top: 1px solid var(--border); margin-top: 4px; }
.kop-meer-lijst a,
.kop-meer-lijst button {
    display: block;
    width: 100%;
    padding: 7px 10px;
    border: 0;
    border-radius: 5px;
    background: none;
    color: var(--text);
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    text-align: left;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}
.kop-meer-lijst a:hover,
.kop-meer-lijst button:hover { background: var(--subtle); }
/* display:block hierboven wint het anders van het hidden-attribuut. */
.kop-meer-lijst [hidden] { display: none; }

/* Twee keuzes over dezelfde inhoud op één regel: welke tekening links, hoeveel detail rechts.
   Los onder elkaar stonden ze te zweven zonder dat je zag dat ze bij elkaar hoorden. */
.zoom-rij { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.zoom-vul { flex: 1 1 auto; }
.zoom-icoon { display: inline-flex; align-items: center; justify-content: center; padding: 5px 11px; }
.zoom-icoon svg { width: 14px; height: 14px; display: block; }

/* Terug: links, boven de titel. Klein en rustig - het is een uitweg, geen aanbod. */
.kop-terug {
    display: inline-block;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 500;
    color: var(--muted);
    text-decoration: none;
}
.kop-terug:hover { color: var(--brand); }

/* --- Zoekbalk: zoeken en filteren op elk overzicht, zie core/Zoekbalk.php --- */
.zoekbalk {
    display: flex;
    gap: 6px;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.zoekbalk-term { position: relative; flex: 1 1 220px; min-width: 180px; display: block; }
.zoekbalk-loep {
    position: absolute; left: 9px; top: 50%; transform: translateY(-50%);
    display: flex; color: var(--muted); pointer-events: none;
}
.zoekbalk-loep svg { width: 14px; height: 14px; }
.zoekbalk input[type="search"] {
    width: 100%;
    padding: 6px 10px 6px 29px;
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    background: var(--card);
    color: var(--text);
    font-family: inherit;
    font-size: 12px;
}
.zoekbalk select {
    padding: 6px 9px;
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    background: var(--card);
    color: var(--text);
    font-family: inherit;
    font-size: 12px;
    max-width: 190px;
}
/* Een filter die aanstaat hoort op te vallen, anders zoek je je rot naar waarom de lijst leeg is. */
.zoekbalk select.aan { border-color: var(--brand); color: var(--brand); font-weight: 500; }
.zoekbalk input[type="search"]:focus,
.zoekbalk select:focus { outline: 2px solid var(--brand); outline-offset: -1px; }
.zoekbalk-leeg { font-size: 12px; color: var(--muted); text-decoration: none; padding: 0 4px; }
.zoekbalk-leeg:hover { color: var(--brand); }

/* Tijdens het ophalen even doffer, zodat je ziet dat er iets gebeurt zonder dat het springt. */
#scherm-inhoud.bezig { opacity: .55; transition: opacity .12s; }

/* Zonder JS is de Zoek-knop de enige manier; met JS is hij overbodig maar niet storend. */
@media (max-width: 560px) { .zoekbalk-term { flex-basis: 100%; } }

/* --- Regels op een kaartje, zie modules/custom_records/Kaartje.php ---------------------------
   Alles wordt gerenderd; het detailniveau verbergt met CSS. Dan staat de schakelaar meteen goed
   zonder de server opnieuw te bevragen, en zo deed het bord het al. */
.kaart-regel {
    font-size: 11px;
    color: var(--muted);
    line-height: 1.45;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.kaart-regel + .kaart-regel { margin-top: 1px; }

/* Een bon die over zijn datum is. Zag er precies hetzelfde uit als een bon van morgen: een
   datum, verder niets. Daardoor bleef er een vierendertig dagen op Gepland staan zonder dat
   iemand het merkte. */
.kaart-regel.kaart-laat { color: var(--red, #dc2626); font-weight: 600; }

/* Compact toont alleen wat op "altijd" staat, normaal daar bovenop "vanaf normaal". */
.kanban-mode-compact .kaart-vanaf-normaal,
.kanban-mode-compact .kaart-vanaf-uitgebreid,
.kanban-mode-normal  .kaart-vanaf-uitgebreid { display: none; }
/* Andersom komt ook voor: een korte regel die op de uitgebreide kaart wordt vervangen door een
   vollediger blok. Dan wil je hem daar juist weg hebben, anders staat het bedrag er twee keer. */
.kanban-mode-expanded .kaart-tot-uitgebreid { display: none; }

/* Label links, bedrag rechts, zodat de bedragen onder elkaar uitlijnen en je ze kunt vergelijken
   zonder te lezen wat ervoor staat. */
.kaart-bedrag { display: flex; justify-content: space-between; gap: 8px; }

/* Pillen zijn inline-block, dus die hebben hun eigen verbergregel nodig. */
.kanban-mode-compact .kaart-pil.kaart-vanaf-normaal,
.kanban-mode-compact .kaart-pil.kaart-vanaf-uitgebreid,
.kanban-mode-normal  .kaart-pil.kaart-vanaf-uitgebreid { display: none; }

/* display van .topbar-timer wint het anders van het hidden-attribuut. */
.topbar-timer[hidden] { display: none; }

/* Pillen op een kaartje: het ene of twee dingen die je van een afstand wil zien. Naast elkaar op
   één rij, want twee pillen onder elkaar leest als twee regels en dan is de vorm zinloos. */
.kaart-pillen { display: flex; flex-wrap: wrap; gap: 3px; margin-bottom: 3px; }
.kaart-pil {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 9px;
    border: 1px solid var(--border2);
    background: var(--subtle);
    color: var(--muted);
    font-size: 10px;
    font-weight: 600;
    line-height: 1.6;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Aanvinklijst in de zoekbalk. Een select met multiple werkt op een telefoon niet en laat niet
   zien wat je hebt aangevinkt zonder hem open te klappen. */
.zoek-lijst { position: relative; }
.zoek-lijst-knop {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 6px 10px;
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    background: var(--card);
    color: var(--text);
    font-family: inherit; font-size: 12px;
    cursor: pointer; white-space: nowrap;
}
.zoek-lijst.aan .zoek-lijst-knop { border-color: var(--brand); color: var(--brand); font-weight: 500; }
.zoek-aantal {
    display: inline-block; min-width: 16px; padding: 0 4px;
    border-radius: 8px; background: var(--brand); color: #fff;
    font-size: 10px; font-weight: 600; text-align: center;
}
.zoek-lijst-opties {
    display: none;
    position: absolute; left: 0; top: calc(100% + 4px); z-index: 40;
    min-width: 210px; max-height: 320px; overflow-y: auto;
    padding: 4px;
    background: var(--card);
    border: 1px solid var(--border2);
    border-radius: var(--radius-sm);
    box-shadow: 0 8px 24px rgba(0, 0, 0, .13);
}
.zoek-lijst.open .zoek-lijst-opties { display: block; }
.zoek-lijst-opties label {
    display: flex; align-items: center; gap: 7px;
    padding: 6px 8px; border-radius: 5px;
    font-size: 12px; cursor: pointer;
}
.zoek-lijst-opties label:hover { background: var(--subtle); }
.zoek-lijst-opties label span:first-of-type { flex: 1; }
.zoek-telling { color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.zoek-lijst-hint {
    padding: 7px 8px 4px; margin-top: 2px;
    border-top: 1px solid var(--border);
    font-size: 11px; color: var(--muted);
}

/* Kopje boven de eigen velden van een record. Zonder scheiding leest het als het label van het
   volgende veld in plaats van als kopje van de groep eronder. */
.eigen-velden-kop {
    margin-top: 22px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
}
.eigen-velden-kop .label { font-weight: 600; color: var(--text); }

/* --- Kijker: foto's en pdf's bekijken zonder downloaden ------------------------------------- */
.kijker {
    display: none;
    position: fixed; inset: 0; z-index: 3000;
    background: rgba(0, 0, 0, .82);
    padding: 48px 56px 64px;
}
.kijker.open { display: block; }
.kijker-inhoud {
    width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
}
.kijker-inhoud img {
    max-width: 100%; max-height: 100%;
    object-fit: contain;
    border-radius: 4px;
    background: #fff;
}
.kijker-inhoud iframe {
    width: 100%; height: 100%;
    border: 0; border-radius: 4px; background: #fff;
}
.kijker-sluit, .kijker-vorige, .kijker-volgende {
    position: absolute; z-index: 1;
    background: rgba(255, 255, 255, .1);
    border: 0; border-radius: 50%;
    color: #fff; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    transition: background .15s;
}
.kijker-sluit:hover, .kijker-vorige:hover, .kijker-volgende:hover { background: rgba(255, 255, 255, .24); }
.kijker-sluit { top: 12px; right: 14px; width: 38px; height: 38px; font-size: 26px; line-height: 1; }
.kijker-vorige, .kijker-volgende { top: 50%; margin-top: -22px; width: 44px; height: 44px; font-size: 30px; }
.kijker-vorige { left: 8px; }
.kijker-volgende { right: 8px; }
/* Bij één bestand zijn de pijlen alleen maar in de weg. */
.kijker.alleen-een .kijker-vorige,
.kijker.alleen-een .kijker-volgende { display: none; }
.kijker-voet {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 14px 20px;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    color: rgba(255, 255, 255, .82); font-size: 13px;
}
.kijker-naam { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kijker-download { color: #fff; text-decoration: underline; white-space: nowrap; }
@media (max-width: 640px) {
    .kijker { padding: 44px 8px 60px; }
    .kijker-vorige, .kijker-volgende { width: 36px; height: 36px; font-size: 24px; }

    /* Meer: op een telefoon geen zwevend doosje maar een blad onder de kop.
       Het menu hing met zijn rechterkant aan de knop en werd zo breed als het langste label,
       want de regels mochten niet afbreken. Stond de knop links op een afgebroken rij, dan
       liep het menu het scherm uit aan de linkerkant - en wat je nog wel zag waren regels van
       twaalf pixels met zeven pixels lucht ertussen, waar je met een vinger niet tussen komt. */
    .kop { position: relative; }
    .kop-meer { position: static; }
    .kop-meer-lijst {
        left: 0;
        right: 0;
        top: calc(100% + 4px);
        min-width: 0;
        padding: 6px;
    }
    .kop-meer-lijst a,
    .kop-meer-lijst button {
        padding: 12px 12px;
        font-size: 14px;
        white-space: normal;
        line-height: 1.35;
    }
    .kop-meer-lijst a + a,
    .kop-meer-lijst a + button,
    .kop-meer-lijst button + a,
    .kop-meer-lijst button + button { border-top: 1px solid var(--border); }
}

/* ============================================
   Mobiel (< 768px) — wat er op een telefoon anders moet
   Toegevoegd 12-10-2026, zie de drie redenen per blok hieronder.
   ============================================ */

/* Rij met kerncijfers die niet het kpi-component gebruikt. Stond in twee views als een
   inline raster, en inline wint van elke stylesheet: mobiel was dat dus niet bij te stellen. */
.statrij {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
}

/* Filterblok. Op een scherm is dit gewoon de filterkaart zoals hij altijd was en is het
   kopje weg; op een telefoon is het kopje de knop waarmee je de filters openvouwt.
   De <details> staat in de markup altijd open, zodat de filters ook zonder javascript
   zichtbaar zijn. App.initFilterblok() klapt hem op een telefoon dicht. */
.filterblok > summary {
    display: none;
    cursor: pointer;
    padding: 12px 16px;
    font-size: 13px;
    font-weight: 500;
    align-items: center;
    gap: 8px;
    list-style: none;
}
.filterblok > summary::-webkit-details-marker { display: none; }
/* Het pijltje is een gewone svg, net als elk ander icoon in dit raamwerk. Eerst stond hier
   een vierkantje van twee gedraaide randen; dat is een trucje dat op een telefoon scheef en
   te zwaar oogt, en het lijnt niet uit met de iconen ernaast. */
.filterblok > summary svg {
    width: 16px;
    height: 16px;
    margin-left: auto;
    color: var(--muted);
    flex-shrink: 0;
    transition: transform .15s ease;
}
.filterblok[open] > summary svg { transform: rotate(180deg); }
.filterblok-telling {
    font-size: 11px;
    font-weight: 600;
    color: #fff;
    background: var(--brand);
    border-radius: 999px;
    padding: 1px 7px;
}

@media (max-width: 767px) {
    /* 1. Een tabel in een kaart was onbereikbaar.
       .card heeft overflow: hidden voor zijn ronde hoeken, en acht kolommen passen niet op
       390 breed. Wat eruit viel was daarmee niet alleen onzichtbaar maar ook onbereikbaar:
       er was geen element dat kon scrollen. 86 van de 235 tabellen in de views staan zonder
       .table-wrap, dus dit hoort hier en niet 86 keer in de markup. overflow-y blijft
       hidden, dus de ronde hoeken blijven heel. */
    .card:has(> table),
    .card:has(> .card-body > table),
    .card:has(> form > .card-body > table),
    .card-body:has(> table) {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* 2a. Tabbalk: één schuifbare regel. Met flex-wrap werden tien tabs vier regels, en
       .tabs a heeft white-space: nowrap dus smaller worden ze niet. Een schuifbare rij is
       hetzelfde patroon als het kanban-bord en de zoomkiezer. */
    .tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        /* overflow-y moet er expliciet bij staan. Zet je alleen overflow-x, dan maakt de
           browser van de andere as ook 'auto', en omdat .tabs a met margin-bottom: -1px over
           de onderrand heen hangt is de inhoud een pixel te hoog. Je kon de balk dus naast
           het schuiven ook een klein stukje op en neer trekken. De padding van die ene pixel
           vangt de overhang op, zodat de streep onder de actieve tab niet afgeknipt wordt. */
        overflow-y: hidden;
        padding-bottom: 1px;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        /* En niet doorschuiven naar de pagina als je voorbij het einde swipet. */
        overscroll-behavior-x: contain;
    }
    .tabs::-webkit-scrollbar { display: none; }

    /* 2b. De titel krijgt zijn eigen regel. Anders deelt hij de breedte met de knoppen,
       breekt over drie regels en wordt de kop juist hoger dan wanneer hij alleen staat.
       De knopgroep blijft rechts uitlijnen: rechts is de primaire plek, net als op een
       scherm (zie NAVIGATIE.md). */
    .kop { gap: 10px; }
    .kop-titel { flex: 1 1 100%; min-width: 0; }
    .kop-acties { flex: 1 1 100%; justify-content: flex-end; }

    /* 2c. Kerncijfers twee naast elkaar in plaats van onder elkaar. Vier tegels van 90px
       hoog kostten 360px voordat er één gegeven in beeld kwam; nu de helft. Op een scherm
       vanaf 768px staan ze al op twee, dus dit is dezelfde vorm en geen nieuwe. */
    .kpi-grid,
    .statrij { grid-template-columns: 1fr 1fr; }

    /* Twee kaarten naast elkaar is op 390 breed zo'n 174px per kaart. Daar blijft met een
       icoon van 36px ernaast en 32px binnenmarge nog 94px tekst over, en dan vervormt de
       kaart: het bedrag wordt geknepen en het label breekt over drie regels. Het icoon gaat
       daarom boven de tekst staan, zodat de tekst de volle breedte van de kaart heeft. */
    .kpi-card {
        flex-direction: column;
        gap: 8px;
        padding: 12px;
    }
    .kpi-icon { width: 28px; height: 28px; }
    .kpi-icon svg { width: 14px; height: 14px; }
    .kpi-value { font-size: 19px; }

    /* 3. Filterblok: op een telefoon ingeklapt, met het aantal actieve filters in het kopje. */
    .filterblok > summary { display: flex; }
}
