* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
    /* Light theme (default) */
    --bg: #f7f6f3;
    --bg-main: #f5f0eb;
    --sidebar: #05141E;
    --primary: #05141E;
    --accent: #85754E;
    --card: #fff;
    --text: #1a2a3a;
    --text-primary: #05141E;
    --text-secondary: #6B7280;
    /* Donkerder dan de oorspronkelijke #8C9091 (3,22:1 op wit). Deze
     * variabele wordt 39 keer als TEKSTkleur gebruikt — de kleine bijschriften
     * onder de KPI-tegels op het dashboard — en niet één keer als rand of
     * vlak. Gemeten: 4,83:1 op wit. */
    --text-muted: #6B7280;
    /* Donkerder dan de oorspronkelijke #9ca3a6. Die haalde op wit 2.56:1 en op
     * de paginakleur 2.37:1, waar de norm 4.5:1 is — en deze variabele wordt 487
     * keer als TEKSTkleur gebruikt en geen enkele keer als rand of achtergrond.
     * Het bleef dus niet bij een subtiel bijschrift: bijna elk klein grijs
     * lijntje tekst in de app stond eronder. #666e71 haalt 5.21:1 op wit en
     * 4.82:1 op de paginakleur, en blijft dezelfde koele grijstint. */
    --muted: #666e71;
    --border: #e4e2de;
    --border-color: #e0e0e0;
    --hover-bg: rgba(0,0,0,0.03);
    --green: #5a9e6f;
    --green-soft: #e8f5ec;
    /* --green is een vlakkleur, geen tekstkleur: #5a9e6f haalt op wit
     * maar 2,7:1. Deze wel — 5,9:1. */
    --green-tekst: #23603d;
    /* Gedempte TEKST die leesbaar moet blijven.
     *
     * --muted (#9ca3a6) haalt op wit 2.56:1 terwijl de norm 4.5:1 is. Voor een
     * rand of een streepje is dat prima; voor tekst die iemand moet lezen niet.
     * --muted donkerder maken zou overal de rust wegnemen, dus staat de
     * leesbare variant er apart naast. Gemeten: 4.83:1 op wit. */
    /* Op wit haalde #6B7280 4,83:1, maar op de paginakleur --bg (#f7f6f3)
     * bleef er 4,47:1 over — drie honderdsten tekort, en dat op de knoppen die
     * op die paginakleur staan (de wis-knop op het dashboard, de tabbladen in
     * CRM). Gemeten: 4,82:1 op de paginakleur, 5,21:1 op wit. */
    --muted-leesbaar: #666e71;
    /* Rood voor knopvlakken. Het pastelrood --red (#c17b6e) haalt met witte
     * tekst 3.32:1 en met donkere tekst 3.07:1 — het ligt precies in het midden
     * en zakt dus langs beide kanten door de norm. Deze donkerdere variant is
     * alleen voor knoppen; rijen en randen blijven pastel. Gemeten: 5.36:1. */
    --red-knop: #a05646;
    /* Rood als TEKST. --red (#c17b6e) is de vlak- en randkleur en haalt als
     * tekst op wit 3,32:1, terwijl hij 123 keer als tekstkleur gebruikt wordt —
     * "te laat", "verloren", de SLA-waarschuwingen. Zelfde waarde als
     * --red-knop, maar met een eigen naam zodat duidelijk blijft waarvoor je
     * hem pakt. Gemeten: 5,36:1 op wit. */
    --red-tekst: #a05646;
    --orange: #c9a84c;
    --orange-soft: #fdf5e6;
    /* Amber als TEKST op een lichte achtergrond. --orange (#c9a84c) is gekozen
     * als vlakkleur en haalt op wit maar 2.29:1 — prima voor een balkje, niet
     * voor "64 dgn" in een tabel. Gemeten: 4.90:1 op wit. In het donkere thema
     * is --orange zelf al ruim voldoende (7.55:1), dus daar blijft het zoals
     * het is. */
    --orange-tekst: #8a6d1f;
    --red: #c17b6e;
    --red-soft: #faf0ee;
    --blue: #6a9fc7;
    --blue-soft: #edf4fa;
    /* Blauw als TEKST. --blue (#6a9fc7) is de vlak- en randkleur en haalt als
     * tekst op wit 2,84:1 — dat is waarom de badges in het vak "Afspraken met
     * de klant" onzichtbaar waren. Zelfde waarde als --melding-info-fg, de
     * donkerste blauwtint die al in dit bestand stond, maar met een eigen naam
     * zodat duidelijk blijft dat je hem als letterkleur pakt en niet als vlak.
     * Gemeten: 9,05:1 op wit. */
    --blue-tekst: #1f4d68;
    --gold: #85754E;
    --silver: #9ca3a6;
    --midnight: #05141E;
    --purple: #9b8bbf;
    --purple-soft: #f3f0f8;
    /* Paars als TEKST. --purple (#9b8bbf) haalt op wit 3,07:1. Dit is de
     * donkerste paarstint die al in dit bestand voorkwam (.aandacht-verzet).
     * Gemeten: 9,39:1 op wit. */
    --purple-tekst: #6a1b9a;

    /* ---- Meldingsniveaus (licht thema) -------------------------------
     * Eén bron voor alle meldingsblokken. De kleur volgt de ERNST:
     *   informatie   = blauw    (neutraal, "even weten")
     *   waarschuwing = amber    ("kijk hier naar")
     *   ernstig      = rood     ("dit blokkeert / dit gaat mis")
     *   ok           = groen    (bevestiging)
     * De -bg waarden zijn de bestaande pastel *-soft tinten; de -fg
     * waarden zijn diepe tonen van dezelfde tint, zodat het rustig blijft.
     * Contrast fg-op-bg (WCAG 2.1, berekend + nagemeten in Chrome):
     *   informatie   #1f4d68 op #edf4fa =  8,16 : 1
     *   waarschuwing #6b4c10 op #fdf5e6 =  7,27 : 1
     *   ernstig      #7d3325 op #faf0ee =  7,91 : 1
     *   ok           #23603d op #e8f5ec =  6,65 : 1
     * Allemaal ruim boven de eis van 4,5 : 1.
     *
     * De -zacht varianten zijn voor bijzin-tekst binnen een melding
     * (het "grijze" regeltje eronder). Ze blijven ingetogen maar halen
     * nog steeds 4,5 : 1 — dat grijs was juist het probleem:
     *   #7f6630 op #fdf5e6 =  5,04 : 1   (was #aaa = 2,14 : 1)
     *   #3d6478 op #edf4fa =  5,75 : 1
     *   #8f5245 op #faf0ee =  5,42 : 1
     *   #3a7252 op #e8f5ec =  5,04 : 1
     * ------------------------------------------------------------------ */
    --melding-info-bg: #edf4fa;
    --melding-info-fg: #1f4d68;
    --melding-info-fg-zacht: #3d6478;
    --melding-info-rand: #6a9fc7;
    --melding-waarschuwing-bg: #fdf5e6;
    --melding-waarschuwing-fg: #6b4c10;
    --melding-waarschuwing-fg-zacht: #7f6630;
    --melding-waarschuwing-rand: #c9a84c;
    --melding-ernstig-bg: #faf0ee;
    --melding-ernstig-fg: #7d3325;
    --melding-ernstig-fg-zacht: #8f5245;
    --melding-ernstig-rand: #c17b6e;
    --melding-ok-bg: #e8f5ec;
    --melding-ok-fg: #23603d;
    --melding-ok-fg-zacht: #3a7252;
    --melding-ok-rand: #5a9e6f;
    /* Terugvalkleur voor oude hard-gecodeerde accentkleuren in de JS
     * (color:#856404, color:#e65100, ...) BUITEN een meldingsblok.
     * #6b4c10 op wit = 7,88 : 1 — #8f3a2c op wit = 7,47 : 1. */
    --legacy-amber-fg: #6b4c10;
    --legacy-rood-fg: #8f3a2c;

    --input-bg: #fff;
    --input-text: #1a2a3a;
    --table-header-bg: #f8f9fa;
    --table-hover: #f8f9fb;
    --modal-overlay: rgba(0,0,0,.4);
    --dropdown-bg: #fff;
    /* Ronde 2 (22-04-2026): multi-layer shadow tokens voor 3D-depth
       op dashboard-cards. Volledige box-shadow strings (inclusief
       inner highlight + ambient shadow). Vroeger waren dit alleen
       kleuren; ze werden nergens als var() gebruikt, dus veilig om
       om te zetten naar volledige shadow-strings. */
    --shadow-xs: 0 1px 2px rgba(0,0,0,.04);
    --shadow-sm: 0 1px 0 rgba(255,255,255,.8) inset, 0 2px 6px rgba(0,0,0,.04), 0 8px 24px -12px rgba(0,0,0,.08);
    --shadow-md: 0 1px 0 rgba(255,255,255,.8) inset, 0 4px 12px rgba(0,0,0,.08), 0 16px 40px -16px rgba(0,0,0,.15);
    --shadow-lg: 0 1px 0 rgba(255,255,255,.8) inset, 0 8px 24px rgba(0,0,0,.1), 0 24px 64px -24px rgba(0,0,0,.2);
    --card-gradient: linear-gradient(180deg, #ffffff 0%, #fafaf8 100%);
}

[data-theme="dark"] {
    --bg: #0f1923;
    --bg-main: #0f1923;
    --sidebar: #0a1018;
    --primary: #e8e6e3;
    --accent: #c4a862;
    --card: #1a2633;
    --text: #e8e6e3;
    --text-primary: #e8e6e3;
    --text-secondary: #9ca3af;
    /* GEDEMPTE TEKST MOET NOG STEEDS TEKST ZIJN.
     *
     * Stond op #6b7280. Gemeten op het donkere thema: 3,17:1 op een kaart en
     * 3,57:1 op de paginakleur, terwijl de norm 4,5:1 is. Dat raakte juist de
     * kleine bijschriften -- "Hit Ratio", "Overdue", "Lopend", "Gem.
     * doorlooptijd" -- op 11 en 12 pixels, op schermen die in de werkplaats
     * van een halve meter afstand gelezen worden.
     *
     * Deze tint blijft duidelijk gedempt (donkerder dan --text-secondary, dus
     * de rangorde in het scherm blijft staan) maar is leesbaar. Gemeten:
     * 5,07:1 op een kaart, 5,86:1 op de paginakleur, 6,31:1 op de zijbalk. */
    --text-muted: #8b95a5;
    /* --muted blijft donker: dat is een RAND- en streepjeskleur, geen tekst. */
    --muted: #7a8a9a;
    --border: #2d3b47;
    --border-color: #2d3b47;
    --hover-bg: rgba(255,255,255,0.05);
    --green: #6ec485;
    --green-soft: #1a3324;
    --green-tekst: #7fd39a;
    /* Op donker is de vlakkleur zelf al leesbaar als tekst. */
    --orange-tekst: var(--orange);
    /* Zie het lichte thema. Hier is de achtergrond donker, dus gaat de leesbare
     * variant juist lichter. Gemeten: 7.68:1 op de kaartachtergrond. */
    --muted-leesbaar: #a0aec3;
    /* Op donker haalt het pastelrood met de achtergrondkleur als tekst 7.64:1;
     * daar is geen aparte knopkleur nodig. */
    --red-knop: #dd9488;
    /* En rood als TEKST gaat op donker juist LICHTER, niet donkerder. Zonder
     * deze regel bleef #a05646 uit het lichte thema staan — een donkerrode
     * letter op een donkerblauwe kaart, 1,7:1. Dat raakte in één keer 143
     * plaatsen in de app. Gemeten: 5,42:1 op de kaartachtergrond. */
    --red-tekst: #dd9488;
    --orange: #d4b55a;
    --orange-soft: #332b14;
    --red: #d4877a;
    --red-soft: #331a15;
    --blue: #7ab5d9;
    --blue-soft: #152a3d;
    /* Op donker is de vlakkleur zelf al ruim leesbaar als tekst — net als bij
     * --orange-tekst hierboven. var() wordt pas bij gebruik ingevuld, dus dit
     * volgt automatisch de definitieve --blue (#7dafc9 uit het tweede donkere
     * blok). Gemeten: 7,27:1 op de kaartachtergrond. */
    --blue-tekst: var(--blue);
    --gold: #c4a862;
    --silver: #7a8a9a;
    --midnight: #e8e6e3;
    --purple: #b0a0d4;
    --purple-soft: #2a2438;
    /* Idem voor paars. Gemeten: 7,25:1 op de kaartachtergrond. */
    --purple-tekst: var(--purple);

    /* ---- Meldingsniveaus (donker thema) ------------------------------
     * Zelfde vier niveaus als in :root, omgekeerd opgebouwd: donkere
     * tint van de kleur als achtergrond, lichte tint als tekst.
     * LET OP: bewust VOLLEDIG DEKKENDE hex-waarden, geen var(--*-soft).
     * In het donkere thema zijn --orange-soft/--red-soft/--blue-soft
     * namelijk halftransparante rgba()-lagen (zie het tweede
     * [data-theme="dark"] blok, "Design tokens"), waardoor het contrast
     * zou afhangen van wat er toevallig achter het blok ligt. Voor
     * meldingen moet het contrast vastliggen, dus dekkend.
     * Contrast fg-op-bg (WCAG 2.1, berekend + nagemeten in Chrome):
     *   informatie   #a9d0ea op #14283a =  9,25 : 1
     *   waarschuwing #ecd08a op #322913 =  9,54 : 1
     *   ernstig      #f2b3a6 op #38211c =  8,40 : 1
     *   ok           #96d9ab op #17301f =  8,66 : 1
     * De -bg tinten liggen bewust dicht bij de paginakleur (#0a1421):
     * het blok mag opvallen door de tekstkleur, niet door te schreeuwen.
     *
     * De -zacht varianten (bijzin-tekst binnen een melding):
     *   #c2ab7a op #322913 =  6,43 : 1
     *   #8fb3cc op #14283a =  6,80 : 1
     *   #cf9c92 op #38211c =  6,29 : 1
     *   #7fbb94 op #17301f =  6,38 : 1
     * ------------------------------------------------------------------ */
    --melding-info-bg: #14283a;
    --melding-info-fg: #a9d0ea;
    --melding-info-fg-zacht: #8fb3cc;
    --melding-info-rand: #7ab5d9;
    --melding-waarschuwing-bg: #322913;
    --melding-waarschuwing-fg: #ecd08a;
    --melding-waarschuwing-fg-zacht: #c2ab7a;
    --melding-waarschuwing-rand: #d4b55a;
    --melding-ernstig-bg: #38211c;
    --melding-ernstig-fg: #f2b3a6;
    --melding-ernstig-fg-zacht: #cf9c92;
    --melding-ernstig-rand: #d4877a;
    --melding-ok-bg: #17301f;
    --melding-ok-fg: #96d9ab;
    --melding-ok-fg-zacht: #7fbb94;
    --melding-ok-rand: #6ec485;
    /* Terugvalkleur buiten meldingsblokken (donker thema).
     * #d4b55a op de kaartkleur #0f1b2e = 8,68 : 1
     * #d4877a op de kaartkleur #0f1b2e = 6,20 : 1 */
    --legacy-amber-fg: #d4b55a;
    --legacy-rood-fg: #d4877a;

    --input-bg: #1e2d3a;
    --input-text: #e8e6e3;
    --table-header-bg: #152030;
    --table-hover: #1e2d3a;
    --modal-overlay: rgba(0,0,0,.6);
    --dropdown-bg: #1a2633;
    /* Dark variant: geen witte inner-highlight, diepere ambient */
    --shadow-xs: 0 1px 2px rgba(0,0,0,.2);
    --shadow-sm: 0 1px 0 rgba(255,255,255,.04) inset, 0 2px 6px rgba(0,0,0,.2), 0 8px 24px -12px rgba(0,0,0,.35);
    --shadow-md: 0 1px 0 rgba(255,255,255,.04) inset, 0 4px 12px rgba(0,0,0,.28), 0 16px 40px -16px rgba(0,0,0,.45);
    --shadow-lg: 0 1px 0 rgba(255,255,255,.04) inset, 0 8px 24px rgba(0,0,0,.35), 0 24px 64px -24px rgba(0,0,0,.6);
    --card-gradient: linear-gradient(180deg, #1c2a38 0%, #182432 100%);
}
html, body { height: 100%; }
body { font-family: 'Segoe UI', Arial, sans-serif; background: var(--bg); color: var(--text); display: flex; height: 100vh; overflow: hidden; }

/* Login */
/* min-height is essentieel: zonder hoogte heeft align-items:center niets om
   binnen te centreren en plakt de loginkaart bovenaan met een leeg vlak
   eronder. 100dvh vangt de adresbalk op mobiel/tablet correct af (de
   werkplaats werkt op tablet); 100vh blijft als fallback voor oudere browsers. */
.login-page { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 100vh; min-height: 100dvh; }
.login-box { background: var(--card); padding: 2.5rem; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,.1); width: 360px; }
.login-box h1 { font-size: 1.5rem; margin-bottom: .5rem; color: var(--primary); }
.login-box p { color: var(--muted-leesbaar); margin-bottom: 1.5rem; font-size: .9rem; }
.login-box input { width: 100%; padding: .7rem; border: 1px solid var(--border); border-radius: 6px; margin-bottom: 1rem; font-size: .95rem; background: var(--input-bg); color: var(--input-text); }
.login-box button { width: 100%; padding: .7rem; background: var(--primary); color: #fff; border: none; border-radius: 6px; font-size: 1rem; cursor: pointer; }
.login-box button:hover { background: #0a2535; }
.login-error { color:var(--red-tekst); font-size: .85rem; margin-bottom: .5rem; display: none; }

/* Sidebar */
.sidebar { width: 220px; background: var(--sidebar); color: #fff; padding: 1.5rem 0; flex-shrink: 0; display: flex; flex-direction: column; }
.sidebar .logo { padding: 0 1.2rem 1.5rem; font-size: 1.3rem; font-weight: 700; border-bottom: 1px solid rgba(255,255,255,.1); }
.sidebar .logo span { font-size: .7rem; opacity: .5; display: block; }
.sidebar nav { flex: 1 1 0; min-height: 0; overflow-y: auto; padding: 1rem 0; }
/* fix 22-04-2026: zonder overflow+min-height kon nav zijn eigen content-hoogte
   afdwingen en daardoor .user-info (incl. Uitloggen-knop) onder de viewport
   duwen op schermen met veel menuitems. flex:1 1 0 + min-height:0 + overflow-y:auto
   laat nav netjes scrollen binnen de flex-ruimte, user-info blijft onderaan. */
.sidebar nav a { display: flex; align-items: center; gap: .6rem; padding: .7rem 1.2rem; color: rgba(255,255,255,.7); text-decoration: none; font-size: .9rem; transition: .2s; }
.sidebar nav a:hover, .sidebar nav a.active { background: rgba(133,117,78,.25); color: #fff; border-left: 3px solid var(--gold); }
.sidebar .user-info { padding: .8rem 1.2rem; border-top: 1px solid rgba(255,255,255,.1); font-size: .85rem; }
.sidebar .user-info .name { font-weight: 600; }
.sidebar .user-info .role { opacity: .5; font-size: .75rem; }
.sidebar .logout-btn { background: none; border: none; color: rgba(255,255,255,.5); cursor: pointer; font-size: .8rem; padding: .3rem 0; }
.sidebar .logout-btn:hover { color: #fff; }

/* Sidebar drag & drop reordering */
.sidebar a[draggable="true"] {
    transition: transform 0.15s, opacity 0.15s;
    position: relative;
}
.sidebar a[draggable="true"]:hover {
    cursor: grab;
}
.sidebar a[draggable="true"]:active {
    cursor: grabbing;
}
.sidebar-dragging {
    opacity: 0.4 !important;
}
.sidebar-dragover {
    border-top: 2px solid var(--accent) !important;
    padding-top: calc(.7rem - 2px);
}
.sidebar a[draggable="true"]::before {
    content: '\2807';
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    opacity: 0;
    font-size: 14px;
    color: rgba(255,255,255,0.4);
    transition: opacity 0.15s;
}
.sidebar a[draggable="true"]:hover::before {
    opacity: 1;
}

/* Main */
.main { flex: 1; display: flex; flex-direction: column; overflow: hidden; min-height: 0; }
.topbar { background: var(--card); padding: .8rem 1.5rem; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; }
.topbar h2 { font-size: 1.1rem; color: var(--primary); }
.content { flex: 1; padding: 1.5rem; overflow-y: auto; }

/* Cards */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
.kpi-card { background: var(--card); border-radius: 10px; padding: 1.2rem; box-shadow: 0 1px 4px rgba(0,0,0,.06); }
.kpi-card .label { font-size: .8rem; color: var(--muted-leesbaar); text-transform: uppercase; letter-spacing: .5px; }
.kpi-card .value { font-size: 1.8rem; font-weight: 700; margin: .3rem 0; }
.kpi-card .sub { font-size: .8rem; color: var(--muted-leesbaar); }
.kpi-card.green .value { color: var(--green); }
/* --orange-tekst, niet --orange: dit is een getal om te lezen, geen vlak.
 * Op wit haalde de vlakkleur 2.29:1. */
.kpi-card.orange .value { color: var(--orange-tekst); }
.kpi-card.red .value { color:var(--red-tekst); }

/* Tables */
.table-wrap { background: var(--card); border-radius: 10px; box-shadow: 0 1px 4px rgba(0,0,0,.06); overflow: hidden; }
.table-toolbar { display: flex; justify-content: space-between; align-items: center; padding: .8rem 1rem; border-bottom: 1px solid var(--border); gap: .5rem; flex-wrap: wrap; }
.table-toolbar select, .table-toolbar input { padding: .4rem .6rem; border: 1px solid var(--border); border-radius: 6px; font-size: .85rem; }
/* Een knop zonder eigen vlakkleur had helemaal GEEN achtergrond en viel dus
 * terug op het lichtgrijs van de browser — in beide thema's hetzelfde, en in
 * het donkere thema een lichte vlek midden op een donker scherm. De
 * filterknoppen in CRM waren daar het duidelijkste voorbeeld van.
 *
 * De modificaties (.btn-primary, .btn-danger, ...) blijven dit overschrijven;
 * dit is alleen wat er staat als niemand iets zegt. */
.btn {
    padding: .5rem 1rem;
    background: var(--card);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 6px;
    cursor: pointer;
    font-size: .85rem;
    font-weight: 600;
}
.btn:hover { background: var(--hover-bg); }
/* Globale disabled-state voor elke .btn - voorkomt dat disabled buttons
   er klikbaar uitzien. Pointer-events:none blokkeert ook hover-tooltip
   zodat we zeker zijn dat de click niet doorkomt. */
.btn:disabled, .btn[disabled] { opacity: .45; cursor: not-allowed; pointer-events: none; filter: grayscale(.3); }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: #0c2a4d; }
.btn-sm { padding: .3rem .6rem; font-size: .8rem; }
/* --red-knop in plaats van --red: het pastelrood haalt met witte tekst
 * 3.32:1 en met donkere tekst 3.07:1 — het ligt precies in het midden en
 * zakt langs beide kanten door de norm van 4.5:1. Rijen en randen blijven
 * wel pastel; alleen het knopvlak gaat donkerder. */
.btn-danger { background: var(--red-knop); color: #fff; }
.btn-success { background: var(--green); color: #fff; }

/* SalesSync tabs — 3D segmented control.
   Gebruikt door Wagenpark (leveringen.js) en Verkoop (sales.js). Doel:
   niet langer "één blok" maar een subtiele tray met spacing tussen de
   tabs, en een duidelijk opgetilde actieve tab. Tokens uit het dark-
   design-systeem (--shadow-sm, --card-gradient, --accent) zodat licht
   én donker thema consistent blijven. */
.ss-tabs {
    display: inline-flex;
    gap: .35rem;
    padding: .3rem;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-xs);
    margin-bottom: 1rem;
}
.ss-tab {
    appearance: none;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-secondary);
    padding: .55rem 1.1rem;
    border-radius: 8px;
    font-size: .9rem;
    font-weight: 500;
    cursor: pointer;
    transition: background .18s ease,
                color .18s ease,
                box-shadow .2s cubic-bezier(.4,0,.2,1),
                transform .2s cubic-bezier(.4,0,.2,1),
                border-color .18s ease;
    position: relative;
    letter-spacing: .1px;
}
.ss-tab:hover:not(.is-active) {
    background: var(--hover-bg);
    color: var(--text-primary);
}
.ss-tab:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.ss-tab.is-active {
    background: var(--card-gradient);
    color: var(--text-primary);
    border-color: var(--border);
    font-weight: 700;
    box-shadow: var(--shadow-sm);
    transform: translateY(-1px);
}
.ss-tab.is-active::after {
    content: '';
    position: absolute;
    left: 18%;
    right: 18%;
    bottom: -1px;
    height: 2px;
    background: var(--accent);
    border-radius: 2px;
    opacity: .9;
}

table { width: 100%; border-collapse: collapse; font-size: .85rem; }
thead th { background: var(--table-header-bg); padding: .6rem .8rem; text-align: left; font-weight: 600; color: var(--muted-leesbaar); text-transform: uppercase; font-size: .75rem; letter-spacing: .5px; border-bottom: 2px solid var(--border); white-space: nowrap; }
tbody td { padding: .6rem .8rem; border-bottom: 1px solid var(--border); }
tbody tr:hover { background: var(--table-hover); }
.badge { display: inline-block; padding: .15rem .5rem; border-radius: 20px; font-size: .75rem; font-weight: 600; }
.badge-stock { background: #e3f2fd; color: #1565c0; }
.badge-verkocht { background: #e8f5e9; color: #2e7d32; }
.badge-demo { background: #fff3e0; color: #e65100; }

/* Modal */
/* z-index 10001 so the main modal always sits above #chat-widget (z:9999)
   and #chat-toast-stack (z:10000). Otherwise a user clicking an image in a
   chat message would open the image modal behind the chat panel and see
   nothing happen. */
.modal-overlay { position: fixed; inset: 0; background: var(--modal-overlay); display: flex; align-items: center; justify-content: center; z-index: 10001; }
.modal { background: var(--card); border-radius: 12px; padding: 1.5rem; width: 550px; max-height: 80vh; overflow-y: auto; box-shadow: 0 8px 30px rgba(0,0,0,.2); }

/* TinyMCE editor in modal: zijn floating UI (dropdowns, dialogs, menus)
   moet boven z-index:10001 van de modal-overlay komen, anders openen dialogen
   (link, image, font-size) achter de modal en 'lijkt het alsof de knop niks doet'.
   .tox-tinymce-aux = container voor dropdowns/menus buiten de editor.
   .tox-dialog-wrap = containment voor Link/Image-dialogs. */
.tox-tinymce-aux { z-index: 100000 !important; }
.tox-dialog-wrap { z-index: 100001 !important; }
.tox-silver-sink { z-index: 100000 !important; }

/* "Mijn profiel & handtekening" link onder username in sidebar - geeft
   visuele affordance dat de username klikbaar is */
.user-name-clickable { cursor: pointer; transition: color .15s ease; }
.user-name-clickable:hover { text-decoration: underline; }
.user-profile-hint {
    font-size: .7rem;
    color: rgba(255,255,255,.55);
    cursor: pointer;
    padding: .25rem 0;
    margin: .15rem 0 .3rem;
    transition: color .15s ease;
}
.user-profile-hint:hover { color: rgba(255,255,255,.9); }
.modal h3 { margin-bottom: 1rem; color: var(--primary); }
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }
.form-group { display: flex; flex-direction: column; gap: .2rem; }
.form-group.full { grid-column: 1 / -1; }
.form-group label { font-size: .8rem; font-weight: 600; color: var(--muted-leesbaar); }
.form-group input, .form-group select, .form-group textarea { padding: .5rem; border: 1px solid var(--border); border-radius: 6px; font-size: .9rem; background: var(--input-bg); color: var(--input-text); }
.form-group textarea { resize: vertical; min-height: 60px; }
.modal-actions { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1rem; }

/* Progress bar */
.progress-bar { height: 8px; background: var(--border); border-radius: 4px; overflow: hidden; }
.progress-bar .fill { height: 100%; border-radius: 4px; transition: width .3s; }

/* Dashboard */
.dash-section { margin-bottom: 1.5rem; }
.dash-section h3 { font-size: .95rem; color: var(--primary); margin-bottom: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; }
/* Equal-height sections when placed side-by-side in a dash-row:
   let the section flex-column, and stretch its last body to fill. */
.dash-row .dash-section { display: flex; flex-direction: column; margin-bottom: 0; }
.dash-row .dash-section > h3 { flex-shrink: 0; }
.dash-row .dash-section > .dash-card,
.dash-row .dash-section > div:last-child { flex: 1; }
.dash-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.dash-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; }
/* Ronde 2: 3D-floating cards met subtiele top-light + multi-layer shadow.
   De gradient gaat iets donkerder naar onder (fafaf8) voor glas-reflectie-
   gevoel; border is heel lichtgrijs zodat de card op de (ook licht-beige)
   achtergrond toch leesbaar "afgescheiden" is. */
/* Basis .dash-card styling (globaal — ook gebruikt in beheer.js e.a.).
   Behoudt oude look: lichte shadow, 10px radius, var(--card) bg.
   Codex NO-GO fix 22-04-2026: de 3D-upgrade (gradient, heavy shadow,
   goud-getinte hover-border) staat HIERONDER gescoped onder
   .dash-grid-container zodat die ALLEEN op het dashboard-grid werkt
   en niet doorsijpelt naar .dash-card gebruik op beheer/andere pages. */
.dash-card {
    background: var(--card);
    border-radius: 10px;
    padding: 1.2rem;
    box-shadow: 0 1px 6px rgba(0,0,0,.06);
    transition: transform .2s ease, box-shadow .2s ease;
}
.dash-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0,0,0,.1);
}

/* Dashboard-grid 3D upgrade: scoped zodat het niet buiten het
   dashboard-grid werkt. */
.dash-grid-container .dash-card {
    background: var(--card-gradient);
    border: 1px solid rgba(0,0,0,.04);
    border-radius: 12px;
    box-shadow: var(--shadow-sm);
    transition: transform .25s cubic-bezier(.4,0,.2,1),
                box-shadow .25s cubic-bezier(.4,0,.2,1),
                border-color .25s cubic-bezier(.4,0,.2,1);
}
.dash-grid-container .dash-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
    border-color: rgba(133,117,78,.18);
}
.dash-grid-container .dash-card.no-hover:hover {
    transform: none;
    box-shadow: var(--shadow-sm);
    border-color: rgba(0,0,0,.04);
}

/* Welkom-hero: prominentere floating tile met goud-accent-rand bovenaan
   (ronde 2, feedback 22-04-2026). Gebruikt dezelfde shadow-tokens maar
   een diepere top-light en iets grotere radius voor "premium" gevoel. */
.dash-card-hero {
    background: var(--card-gradient);
    border: 1px solid rgba(0,0,0,.04);
    border-top: 3px solid var(--gold);
    border-radius: 14px;
    padding: 2rem 2.4rem;
    box-shadow: var(--shadow-md);
    transition: transform .25s cubic-bezier(.4,0,.2,1),
                box-shadow .25s cubic-bezier(.4,0,.2,1);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
}
.dash-card-hero:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
}
.dash-card-hero .hero-left { flex: 1 1 320px; min-width: 0; }
.dash-card-hero .hero-greet {
    font-size: 1.85rem;
    font-weight: 800;
    color: var(--primary);
    line-height: 1.15;
    margin-bottom: .35rem;
    letter-spacing: -.5px;
}
.dash-card-hero .hero-sub {
    font-size: .95rem;
    color: var(--text-secondary);
    line-height: 1.45;
    max-width: 60ch;
}
.dash-card-hero .hero-sub strong { color: var(--primary); font-weight: 700; }
.dash-card-hero .hero-badge {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem 1rem;
    border-radius: 999px;
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .2px;
    background: linear-gradient(180deg, rgba(255,255,255,.9) 0%, rgba(250,247,236,.95) 100%);
    border: 1px solid rgba(133,117,78,.3);
    color: #6b5f40;
    box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 4px 12px -4px rgba(133,117,78,.25);
}
.dash-card-hero .hero-badge.hero-badge-track {
    border-color: rgba(90,158,111,.35);
    color: #2d6a4f;
    background: linear-gradient(180deg, rgba(255,255,255,.9) 0%, rgba(232,245,236,.95) 100%);
    box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 4px 12px -4px rgba(90,158,111,.25);
}
.dash-card-hero .hero-badge.hero-badge-focus {
    border-color: rgba(201,168,76,.45);
    color: #8c5e1f;
    background: linear-gradient(180deg, rgba(255,255,255,.9) 0%, rgba(253,245,230,.95) 100%);
    box-shadow: 0 1px 2px rgba(0,0,0,.04), 0 4px 12px -4px rgba(201,168,76,.3);
}
.dash-card-hero .hero-badge-icon { font-size: 1rem; line-height: 1; }
[data-theme="dark"] .dash-card-hero .hero-badge {
    background: linear-gradient(180deg, #1e2d3a 0%, #152030 100%);
    color: #d4c08a;
}
@media (max-width: 700px) {
    .dash-card-hero { padding: 1.4rem 1.3rem; }
    .dash-card-hero .hero-greet { font-size: 1.4rem; }
    .dash-card-hero .hero-sub { font-size: .88rem; }
}

/* Subtiele scale+shadow bij hover op status-pills */
.dash-pill {
    transition: transform .2s cubic-bezier(.4,0,.2,1),
                box-shadow .2s cubic-bezier(.4,0,.2,1);
}
.dash-pill:hover {
    transform: scale(1.05);
    box-shadow: var(--shadow-xs);
}

/* Dashboard-section wrapper: blijft overflow:hidden (bv. voor charts
   en table-wraps die binnen moeten blijven). De 3D-depth komt van de
   dash-card binnenin; hover-lift via transform wordt niet afgeknipt. */
/* Zachte indicator-pills voor section-title counts. Vervangt de oude
   knalrode / oranje "badge" pills. Kleur = linker-accent, geen volle fill. */
.dash-pill {
    display: inline-block;
    padding: .1rem .55rem;
    border-radius: 10px;
    font-size: .72rem;
    font-weight: 700;
    margin-left: .5rem;
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--muted-leesbaar);
    min-width: 22px;
    text-align: center;
    letter-spacing: 0;
    text-transform: none;
}
.dash-pill-red    { background: var(--red-soft);    color:var(--red-tekst); border-color: rgba(193,123,110,.35); }
.dash-pill-orange { background: var(--orange-soft); color: var(--orange); border-color: rgba(201,168,76,.35); }
.dash-pill-green  { background: var(--green-soft);  color: var(--green); border-color: rgba(90,158,111,.35); }
.dash-card h4 { font-size: .8rem; color: var(--muted-leesbaar); text-transform: uppercase; letter-spacing: .5px; margin-bottom: .8rem; }
.dash-card canvas { max-height: 220px; }

/* Target progress bars */
.target-progress { display: flex; flex-direction: column; gap: .6rem; }
.target-row { display: flex; align-items: center; gap: .8rem; }
.target-label { width: 100px; font-size: .8rem; font-weight: 600; color: var(--text); text-align: right; flex-shrink: 0; }
.target-bar-wrap { flex: 1; height: 8px; background: var(--border); border-radius: 4px; overflow: hidden; position: relative; }
.target-bar { height: 8px; border-radius: 4px; transition: width .5s ease; display: flex; align-items: center; justify-content: flex-end; padding-right: 8px; }
.target-bar span { font-size: .75rem; font-weight: 700; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.3); }
.target-marker { position: absolute; top: 0; bottom: 0; width: 3px; background: var(--text); border-radius: 2px; z-index: 2; }
.target-values { width: 90px; font-size: .75rem; color: var(--muted-leesbaar); text-align: left; flex-shrink: 0; }
.target-values strong { color: var(--text); }
.target-msg { font-size: .7rem; color: var(--muted-leesbaar); font-style: italic; margin-left: .5rem; }

/* Breakdown grid */
.breakdown-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: .4rem; }
.breakdown-item { background: var(--table-hover); border-radius: 6px; padding: .5rem; text-align: center; }
.breakdown-item .num { font-size: 1.3rem; font-weight: 700; color: var(--primary); }
.breakdown-item .lbl { font-size: .65rem; color: var(--muted-leesbaar); text-transform: uppercase; letter-spacing: .3px; }

/* Hero stat */
.hero-stat { display: flex; align-items: center; gap: 1rem; padding: .5rem 0; }
.hero-stat .big { font-size: 2.5rem; font-weight: 800; line-height: 1; }
.hero-stat .detail { font-size: .85rem; color: var(--muted-leesbaar); }
.hero-stat .detail strong { color: var(--text); }

/* Commission */
.commission-wrap { background: linear-gradient(135deg, #0f3460, #1a1a2e); border-radius: 12px; padding: 1.5rem; color: #fff; }
.commission-wrap h3 { color: #fff; margin-bottom: 1rem; }
.commission-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: .8rem; margin-bottom: 1.2rem; }
.comm-item { background: rgba(255,255,255,.1); border-radius: 8px; padding: .8rem; text-align: center; }
.comm-item .num { font-size: 1.6rem; font-weight: 800; }
.comm-item .pts { font-size: .85rem; color: var(--orange); font-weight: 600; }
.comm-item .lbl { font-size: .7rem; opacity: .7; text-transform: uppercase; margin-top: .2rem; }
.comm-progress { margin: 1rem 0; }
.comm-progress-bar { height: 24px; background: rgba(255,255,255,.15); border-radius: 12px; overflow: hidden; position: relative; }
.comm-progress-fill { height: 100%; border-radius: 12px; transition: width .5s; display: flex; align-items: center; justify-content: center; font-size: .75rem; font-weight: 700; }
.comm-progress-marker { position: absolute; top: -6px; bottom: -6px; width: 3px; background: var(--orange); border-radius: 2px; }
.comm-milestones { display: flex; justify-content: space-between; margin-top: .3rem; font-size: .7rem; opacity: .6; }
.comm-summary { display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: center; margin-top: 1rem; }
.comm-summary .big-pts { font-size: 2.2rem; font-weight: 800; color: var(--orange); }
.comm-summary .status { font-size: .85rem; opacity: .8; }
.comm-needed { background: rgba(233,69,96,.2); border: 1px solid rgba(233,69,96,.4); border-radius: 8px; padding: .6rem 1rem; font-size: .85rem; }
.comm-achieved { background: rgba(39,174,96,.2); border: 1px solid rgba(39,174,96,.4); border-radius: 8px; padding: .6rem 1rem; font-size: .85rem; }

/* PDF Drop Zone */
.pdf-dropzone {
    background: var(--card);
    border: 2px dashed var(--border);
    border-radius: 10px;
    padding: 1.5rem;
    text-align: center;
    cursor: pointer;
    transition: border-color .2s, background .2s;
}
.pdf-dropzone:hover, .pdf-dropzone.dragover {
    border-color: var(--primary);
    background: var(--hover-bg);
}
.pdf-dropzone-inner { pointer-events: none; }
.pdf-dropzone-icon { font-size: 2rem; margin-bottom: .3rem; }
.pdf-dropzone-text { font-size: .95rem; color: var(--text); margin-bottom: .2rem; }
.pdf-dropzone-sub { font-size: .8rem; color: var(--muted-leesbaar); }

/* Compact document dropzone (inside detail popup) */
.doc-dropzone {
    background: var(--card);
    border: 2px dashed var(--border);
    border-radius: 8px;
    padding: .5rem .8rem;
    text-align: center;
    cursor: pointer;
    transition: border-color .2s, background .2s;
    margin-top: .5rem;
}
.doc-dropzone:hover, .doc-dropzone.dragover {
    border-color: var(--primary);
    background: var(--hover-bg);
}
.doc-dropzone-inner {
    pointer-events: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
}

/* Model badge in table */
.model-badge {
    display: inline-block;
    background: #e8f0fe;
    color: #155ab6;
    padding: .1rem .45rem;
    border-radius: 4px;
    font-size: .8rem;
    font-weight: 600;
    margin: .1rem .15rem;
    /* #1a73e8 op #e8f0fe haalde 3,93:1. Een stap donkerder houdt
       dezelfde blauwe badge maar wordt leesbaar. Gemeten: 5,31:1. */
}

/* Kia New Modal (wider) */
.modal.modal-wide { width: 720px; max-width: 95vw; }

/* Modal section titles */
.modal-section-title {
    font-size: .8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--primary);
    padding-bottom: .3rem;
    border-bottom: 2px solid var(--primary);
    margin-bottom: .6rem;
}

/* Opvolging CRM Styles */
.opv-badge {
    display: inline-block;
    background: rgba(0,0,0,.15);
    /* `inherit`, niet var(--text). Dit cijfer zit ALTIJD in een knop, en die
     * knop bepaalt zijn eigen vlakkleur — .opv-filter-btn blijft in het donkere
     * thema bijvoorbeeld lichtgrijs met zwarte tekst. Zet je hier de themakleur,
     * dan komt lichte tekst op dat lichte vlak: gemeten 1.04:1. De knop volgen
     * klopt in beide thema's. */
    color: inherit;
    border-radius: 10px;
    padding: 0 .4rem;
    font-size: .75rem;
    font-weight: 700;
    min-width: 20px;
    text-align: center;
    margin-left: .2rem;
}
.btn-primary .opv-badge { background: rgba(255,255,255,.3); }

/* Opvolging Timeline */
.opv-timeline {
    position: relative;
    padding-left: 20px;
    margin-top: .5rem;
}
.opv-timeline::before {
    content: '';
    position: absolute;
    left: 7px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--border);
}
.opv-timeline-item {
    position: relative;
    padding: .6rem .8rem;
    margin-bottom: .5rem;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.opv-timeline-item.opv-planned {
    background: #fffbf0;
    border-color: var(--orange);
    border-style: dashed;
}
.opv-timeline-dot {
    position: absolute;
    left: -20px;
    top: .9rem;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid #fff;
    box-shadow: 0 0 0 1px var(--border);
}
.opv-timeline-content {
    font-size: .88rem;
}

/* Pipeline Summary Bar */
.pipeline-section {
    background: var(--card);
    border-radius: 10px;
    padding: 1rem 1.2rem;
    margin: 1rem 0;
    box-shadow: 0 1px 4px rgba(0,0,0,.06);
}
.pipeline-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .6rem;
}
.pipeline-total {
    font-weight: 700;
    font-size: .95rem;
    color: var(--text);
}
.pipeline-overdue-alert {
    font-weight: 700;
    font-size: .9rem;
    color:var(--red-tekst);
    background: #fdeaea;
    padding: .25rem .7rem;
    border-radius: 6px;
}
.pipeline-bar {
    display: flex;
    height: 32px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--border);
    gap: 2px;
}
.pipeline-segment {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    transition: flex .3s;
}
.pipeline-segment span {
    /* Contrast-fix 22-04-2026: kleur ERF VAN parent-segment (.pipeline-green/
       blue/red), die al donkere tekst-kleuren definieren voor de pastel
       backgrounds. #fff op pastel was onleesbaar (faalt AA in beide modes). */
    color: inherit;
    font-weight: 700;
    font-size: .82rem;
}
.pipeline-green { background: #7dcea0; color: #1a5032; }
.pipeline-blue { background: #85c1e9; color: #1a3d5c; }
.pipeline-red { background: #f1948a; color: #6e2c22; }
/* Feedback 22-04-2026: Open en Opvolging zijn nu aparte segmenten (ipv
   samengevoegd als "Lopend"). Open = frisse blauw, Opvolging = amber om
   actie-urgentie te tonen zonder zo dwingend als rood te zijn. */
.pipeline-open { background: #85c1e9; color: #1a3d5c; }
.pipeline-opvolging { background: #f7d794; color: #6b5420; }
.pipeline-legend-open { background: #85c1e9; }
.pipeline-legend-opvolging { background: #f7d794; }
.pipeline-legend {
    display: flex;
    gap: 1.2rem;
    margin-top: .5rem;
    font-size: .8rem;
    color: var(--muted-leesbaar);
}
.pipeline-legend-item {
    display: flex;
    align-items: center;
    gap: .3rem;
}
.pipeline-legend-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
}

/* Opvolging Filter Buttons */
.opv-filters {
    display: flex;
    gap: .5rem;
    margin: .8rem 0;
    flex-wrap: wrap;
    align-items: center;
}
.opv-filter-btn {
    font-size: .85rem;
}
.opv-filter-green {
    background: var(--green) !important;
    color: #fff !important;
    border-color: var(--green) !important;
}
.opv-filter-red {
    background: var(--red) !important;
    color: #fff !important;
    border-color:var(--red-tekst) !important;
}
.opv-filter-warn {
    background: var(--red) !important;
    color: #fff !important;
    border-color:var(--red-tekst) !important;
}
.opv-badge-green {
    background: rgba(39,174,96,.2) !important;
    color: var(--green) !important;
}
/* In het donkere thema legt die doorschijnende wassing bijna niets over de
 * kaart, zodat de groene tekst op een donkere achtergrond uitkwam: 1.86:1.
 * Een vollere achtergrond met lichtere tekst leest wel. */
[data-theme="dark"] .opv-badge-green {
    background: #1a3324 !important;
    color: #8fd6a6 !important;
}
[data-theme="dark"] .opv-badge-red,
[data-theme="dark"] .opv-badge-warn {
    background: #3a1f1a !important;
    color: #e8a99e !important;
}
.opv-badge-red {
    background: rgba(231,76,60,.2) !important;
    color:var(--red-tekst) !important;
}
.opv-badge-warn {
    background: rgba(231,76,60,.2) !important;
    color:var(--red-tekst) !important;
}
.opv-filter-green .opv-badge, .opv-filter-red .opv-badge, .opv-filter-warn .opv-badge {
    background: rgba(255,255,255,.3) !important;
    color: #fff !important;
}

/* Status Badges */
.status-badge {
    display: inline-block;
    padding: .2rem .7rem;
    border-radius: 10px;
    font-size: .75rem;
    font-weight: 600;
    color: #fff;
    white-space: nowrap;
}
.status-badge-green { background: #7dcea0; color: #1a5032; }
.status-badge-red { background: #f1948a; color: #6e2c22; }
/* De donkere tekst op het amber vlak haalde 3,79:1. Een stap donkerder en
   het klopt, zonder dat het vlak verandert. Gemeten: 4,71:1. */
.status-badge-orange { background: #f0c27a; color: #66491a; }
.status-badge-blue { background: #85c1e9; color: #1a3d5c; }

/* SLA Indicators */
.sla-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    vertical-align: middle;
    margin-right: .3rem;
}
.sla-green { background: #7dcea0; }
.sla-orange { background: #f0c27a; }
.sla-red { background: #f1948a; }
.sla-neutral { background: var(--border); }
.sla-text-red {
    color:var(--red-tekst);
    font-size: .75rem;
    font-weight: 600;
}
.sla-text-orange {
    color: var(--orange);
    font-size: .75rem;
    font-weight: 600;
}

/* Opvolging Row Styles */
.opv-row {
    cursor: pointer;
    transition: background .15s;
}
.opv-row:hover {
    background: var(--table-hover);
}
.opv-row-overdue {
    border-left: 4px solid var(--red) !important;
}

/* Prospectie/Opvolging Toggle */
.opv-type-toggle { display:flex; gap:0; margin-bottom:1rem; }
.opv-type-btn { padding:.6rem 1.5rem; border:2px solid var(--primary); background:transparent; color:var(--primary); cursor:pointer; font-weight:600; transition:all .2s; font-size:.9rem; }
.opv-type-btn:first-child { border-radius:8px 0 0 8px; }
.opv-type-btn:last-child { border-radius:0 8px 8px 0; border-left:none; }
.opv-type-btn.active { background:var(--primary); color:#fff; }
.opv-row-overdue td:first-child {
    padding-left: calc(.6rem + 4px);
}

/* Form section titles */
.form-section-title {
    font-size: .85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--primary);
    padding: .5rem 0 .3rem;
    border-bottom: 2px solid var(--primary);
    margin: 1.2rem 0 .8rem;
}
.form-section-title:first-of-type { margin-top: .5rem; }

/* Multi-select brand component */
.ms-tags { display: flex; flex-wrap: wrap; gap: .3rem; margin-bottom: .4rem; min-height: 28px; }
.ms-tag {
    display: inline-flex; align-items: center; gap: .3rem;
    background: var(--primary); color: #fff;
    padding: .2rem .6rem; border-radius: 12px;
    font-size: .8rem; font-weight: 500;
}
.ms-tag-x {
    cursor: pointer; font-size: 1rem; line-height: 1;
    opacity: .7; transition: opacity .15s;
}
.ms-tag-x:hover { opacity: 1; }
.ms-search {
    width: 100%; padding: .5rem; border: 1px solid var(--border);
    border-radius: 6px; font-size: .9rem;
}
.ms-dropdown {
    display: none; position: absolute; top: 100%; left: 0; right: 0;
    background: var(--card); border: 1px solid var(--border);
    border-radius: 0 0 8px 8px; max-height: 200px; overflow-y: auto;
    z-index: 1000; box-shadow: 0 4px 12px rgba(0,0,0,.12);
}
.ms-option {
    padding: .45rem .8rem; cursor: pointer;
    font-size: .88rem; transition: background .1s;
}
.ms-option:hover { background: var(--hover-bg); }

/* ===== Admin Dashboard ===== */
.admin-dash { width: 100%; }

.adm-kpi {
    background: var(--card); border-radius: 12px; padding: 1.2rem 1rem;
    box-shadow: 0 1px 4px rgba(0,0,0,.06); text-align: center;
    border-top: 3px solid var(--accent); transition: transform .15s, box-shadow .15s;
}
.adm-kpi:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,.1); }
.adm-kpi-val { font-size: 2.2rem; font-weight: 800; color: var(--primary); line-height: 1; margin-bottom: .3rem; }
.adm-kpi-label { font-size: .8rem; font-weight: 600; color: var(--muted-leesbaar); text-transform: uppercase; letter-spacing: .5px; margin-bottom: .3rem; }
.adm-kpi-trend { font-size: .75rem; color: var(--muted-leesbaar); }

.adm-card {
    background: var(--card); border-radius: 12px; padding: 1.2rem 1.4rem;
    box-shadow: 0 1px 4px rgba(0,0,0,.06);
    transition: transform .2s ease, box-shadow .2s ease;
}
.adm-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0,0,0,.1);
}
.adm-card-title {
    font-size: .9rem; font-weight: 700; color: var(--primary); margin-bottom: 1rem;
    padding-bottom: .5rem; border-bottom: 1px solid var(--border);
    text-transform: uppercase; letter-spacing: .3px;
}

.adm-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.adm-table th { text-align: left; padding: .6rem .5rem; font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted-leesbaar); border-bottom: 2px solid var(--border); }
.adm-table td { padding: .6rem .5rem; border-bottom: 1px solid var(--border); }
.adm-table tbody tr:hover { background: rgba(133,117,78,.04); }
.adm-table tbody tr:last-child td { border-bottom: none; }

.adm-alert {
    background: var(--red-soft); border: 1px solid var(--red); border-radius: 8px;
    padding: .8rem 1rem; font-size: .8rem; color:var(--red-tekst);
    flex: 1; min-width: 200px;
}
.adm-alert-icon { margin-right: .4rem; font-size: 1rem; }

/* Phase 1: Deal rotting indicators */
.deal-rot { font-size: .7rem; line-height: 1; }
.deal-rot-fresh { color: #22c55e; }
.deal-rot-warm { color: #f59e0b; }
.deal-rot-cold { color: #ef4444; }
/* Een dossier dat doodgebloed is, mag stil zijn maar niet onleesbaar:
   #9ca3af haalde 2,54:1. Gemeten: 4,83:1. */
.deal-rot-dead { color: var(--muted-leesbaar); }

@media (max-width: 1200px) {
    .admin-dash > div[style*="grid-template-columns:repeat(5"] { grid-template-columns: repeat(3, 1fr) !important; }
    .admin-dash > div[style*="grid-template-columns:1fr 1fr"] { grid-template-columns: 1fr !important; }
}

/* ========== Dashboard Grid System ========== */
/* dash-grid-container is nu een 6-col grid (was flex-column) zodat
 * platforms (.dash-section-group) + headerless rows naast elkaar kunnen
 * staan obv hun platform-width class. Rows + groups krijgen default een
 * volle 6-col span; dash-platform-* spans overriden dat. */
.dash-grid-container {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 1rem;
    align-items: start;
}
.dash-grid-container > .dash-row,
.dash-grid-container > .dash-section-group,
.dash-grid-container > .dash-row-dropzone { grid-column: span 6; }

/* Platform-width overrides: bepaalt hoe breed het 3D-platform is
 * t.o.v. de 6-col grid. Wordt toegekend adhv de totale widget-span
 * in de rij (zie PLATFORM_SPAN_CLASS in dashboard.js). */
.dash-grid-container > .dash-platform-full      { grid-column: span 6; }
.dash-grid-container > .dash-platform-twothird  { grid-column: span 4; }
.dash-grid-container > .dash-platform-half      { grid-column: span 3; }
.dash-grid-container > .dash-platform-third     { grid-column: span 2; }

.dash-row { display: grid; grid-template-columns: repeat(6, 1fr); gap: 1rem; min-height: 0; align-items: stretch; }
.dash-row > .dashboard-section { display: flex; flex-direction: column; }
.dash-row > .dashboard-section > .section-content { flex: 1; display: flex; flex-direction: column; }
.dash-row > .dashboard-section > .section-content > .adm-card { flex: 1; display: flex; flex-direction: column; }
.dash-row > .dashboard-section > .section-content > .adm-card > .adm-card-title { flex-shrink: 0; }
.dash-row > .dashboard-section > .section-content > .adm-card > *:last-child { margin-top: auto; }
.dash-row > .dashboard-section > .section-content > div[style*="display:grid"] { flex: 1; align-content: center; }
.dash-col-full      { grid-column: span 6; }
.dash-col-twothird  { grid-column: span 4; }
.dash-col-half      { grid-column: span 3; }
.dash-col-third     { grid-column: span 2; }
/* Horizontaal schuifbaar in plaats van afkappen (05-08-2026).
 *
 * Dit stond op `overflow: hidden` zodat charts en platform-effecten binnen hun
 * rand blijven. Verticaal klopt dat, horizontaal niet: wat breder was dan de
 * sectie werd weggeknipt zonder schuifbalk, dus onzichtbaar EN onbereikbaar.
 *
 * Er bestonden al twee correcties hiervoor, maar allebei binnen een media-query
 * (eerst alleen telefoons, daarna ook tablets). Gemeten op een scherm van
 * 1440px bleven er nog drie secties afgeknipt — 353px breed met bredere inhoud.
 * Het probleem hangt niet aan de schermbreedte maar aan de verhouding tussen
 * sectie en inhoud, en die kan op elke breedte misgaan.
 *
 * Daarom hier, één keer, voor alle breedtes. Verticaal blijft hidden. */
.dashboard-section { min-width: 0; overflow-x: auto; overflow-y: hidden; }

/* Responsive override moved to bottom of file */

/* ========== Dashboard Edit Mode ========== */
.dash-edit-toolbar {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: 1rem;
    padding: .6rem 1rem;
    background: linear-gradient(135deg, #f8f9fa, #eef1f5);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 1px 4px rgba(0,0,0,.04);
}
.dash-edit-toolbar .btn { font-size: .8rem; padding: .35rem .9rem; }
.dash-edit-btn {
    cursor: pointer;
    background: none;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: .3rem .5rem;
    font-size: .85rem;
    color: #666;
    display: flex;
    align-items: center;
    gap: .3rem;
    transition: background .2s;
}
.dash-edit-btn:hover { background: #f0f0f0; }

/* Edit mode section styling */
.dashboard-section.editing {
    border: 2px dashed #b8cfe0;
    cursor: grab;
    position: relative;
    border-radius: 10px;
    transition: border-color .2s, box-shadow .2s;
    background: rgba(255,255,255,.6);
}
.dashboard-section.editing:hover {
    border-color: var(--gold);
    box-shadow: 0 2px 12px rgba(133,117,78,.12);
}
.dashboard-section.editing .section-handle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 10px;
    background: linear-gradient(135deg, #f5f3ef, #eae6df);
    border-radius: 8px 8px 0 0;
    font-size: .78rem;
    color: var(--text-secondary);
    cursor: grab;
    user-select: none;
    /* Feedback 22-04-2026: bij smalle widgets (1/3 of smaller) wrapt de
       handle naar een tweede regel zodat de width-selector en de
       merge-knop altijd bereikbaar blijven. */
    flex-wrap: wrap;
    gap: .4rem;
    row-gap: .3rem;
}
.dashboard-section.editing .section-handle .drag-icon {
    font-size: 1.1rem;
    line-height: 1;
    color: #999;
    margin-right: .4rem;
}
.dashboard-section.editing .section-handle .handle-left {
    display: flex;
    align-items: center;
    gap: .3rem;
    font-weight: 600;
}
.dashboard-section.dragging { opacity: 0.4; transform: scale(.98); }
.dashboard-section.drag-over {
    border-color: var(--gold);
    background: rgba(133, 117, 78, 0.06);
    box-shadow: 0 0 0 3px rgba(133,117,78,.1);
}

/* Handle right side (display dropdown + width buttons) */
.handle-right {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
    row-gap: .3rem;
}
/* In smalle widgets mag .handle-left zijn label truncaten zodat de knoppen
   rechts voorrang krijgen (de drag-icon blijft altijd zichtbaar). */
.dashboard-section.editing .section-handle .handle-left {
    min-width: 0;
    overflow: hidden;
}
.dashboard-section.editing .section-handle .handle-left > :not(.drag-icon) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Display type dropdown in edit mode */
.display-type-select {
    padding: 2px 6px;
    border: 1px solid var(--border);
    background: var(--input-bg);
    border-radius: 4px;
    font-size: .72rem;
    font-weight: 600;
    color: var(--text-secondary);
    cursor: pointer;
    outline: none;
    transition: border-color .15s;
    max-width: 150px;
    appearance: auto;
}
.display-type-select:hover {
    border-color: var(--gold);
}
.display-type-select:focus {
    border-color: var(--gold);
    box-shadow: 0 0 0 2px rgba(133,117,78,.15);
}

/* Width selector buttons in edit mode */
/* Feedback 22-04-2026: flex-wrap zodat ALLE width-knoppen (1/1, 2/3, 1/2,
   1/3) bereikbaar blijven in smalle widgets — anders valt 1/3 buiten beeld
   en kan je de widget niet meer terug breder maken. Geldt ook voor
   .layout-btns (de move/merge-knoppen). */
.width-selector { display: flex; gap: 2px; flex-wrap: wrap; row-gap: 2px; }
.dashboard-section.editing .section-handle .layout-btns {
    display: flex;
    gap: 2px;
    flex-wrap: wrap;
    row-gap: 2px;
}
.width-btn {
    padding: 2px 8px;
    border: 1px solid var(--border);
    background: var(--input-bg);
    border-radius: 4px;
    font-size: .7rem;
    cursor: pointer;
    color: var(--muted-leesbaar);
    transition: all .15s;
    font-weight: 600;
}
.width-btn:hover { background: #f0ede8; border-color: var(--gold); color: var(--gold); }
.width-btn.active {
    background: var(--gold);
    color: #fff;
    border-color: var(--gold);
}
/* In het donkere thema is --gold licht (#c4a862); witte tekst haalt daarop maar
 * 2.30:1 en de actieve knop was in de praktijk niet te lezen. De donkere
 * achtergrondkleur als tekst haalt 8.04:1. */
[data-theme="dark"] .width-btn.active {
    color: var(--bg);
}
/* Op smalle widgets (container-query) → compactere knoppen + select. */
.dashboard-section { container-type: inline-size; }
@container (max-width: 360px) {
    .width-btn {
        padding: 2px 5px;
        font-size: .62rem;
    }
    .dashboard-section.editing .section-handle {
        padding: 4px 6px;
        font-size: .7rem;
    }
    .dashboard-section.editing .section-handle .display-type-select {
        max-width: 100%;
        font-size: .65rem;
    }
}

/* Row drop zones (visible in edit mode) */
.dash-row-dropzone {
    height: 4px;
    border-radius: 4px;
    transition: all .2s;
    margin: 2px 0;
}
.dash-row-dropzone.drag-hover {
    height: 40px;
    background: rgba(133,117,78,.08);
    border: 2px dashed var(--gold);
    border-radius: 8px;
}

/* Section drop zone (for side-by-side placement) */
.dash-section-dropzone {
    width: 4px;
    min-height: 60px;
    border-radius: 4px;
    transition: all .2s;
    align-self: stretch;
}
.dash-section-dropzone.drag-hover {
    width: 40px;
    background: rgba(133,117,78,.08);
    border: 2px dashed var(--gold);
    border-radius: 8px;
}

/* Inner item drag handles */
.inner-drag-handle {
    display: none;
    cursor: grab;
    color: #bbb;
    font-size: .9rem;
    padding: 0 4px;
    user-select: none;
    flex-shrink: 0;
}
.inner-drag-handle:hover { color: var(--gold); }
.editing .inner-drag-handle { display: inline-flex; align-items: center; }
.inner-item { transition: transform .15s, opacity .15s; }
.inner-item.dragging { opacity: .4; }
.inner-item.drag-over { border-top: 2px solid var(--gold); }

/* ========== Remove section button ========== */
.dash-remove-btn {
    background: none;
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--muted-leesbaar);
    font-size: 1.1rem;
    line-height: 1;
    padding: 1px 6px;
    cursor: pointer;
    transition: all .15s;
    margin-left: .3rem;
}
.dash-remove-btn:hover {
    background: var(--red);
    color: #fff;
    border-color:var(--red-tekst);
}

/* ========== Add block button & dropdown ========== */
.dash-add-block-wrapper {
    position: relative;
    display: inline-block;
    width: 100%;
}
.dash-add-block-btn {
    background: var(--primary) !important;
    color: #fff !important;
    border-radius: 8px !important;
}
.dash-add-block-btn:hover {
    background: #0a2535 !important;
}
.dash-add-dropdown {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: 100%;
    margin-bottom: .5rem;
    background: var(--dropdown-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0,0,0,.12);
    z-index: 50;
    min-width: 220px;
    max-height: 300px;
    overflow-y: auto;
    padding: .3rem 0;
}
.dash-add-item {
    padding: .5rem 1rem;
    font-size: .85rem;
    cursor: pointer;
    transition: background .15s;
}
.dash-add-item:hover {
    background: rgba(133,117,78,.08);
    color: var(--primary);
}

/* ========== Responsive Design ========== */

/* Large screens - limit max width */
.dash-grid-container {
    max-width: 1600px;
    margin: 0 auto;
}
.adm-card {
    max-width: 100%;
}

/* Tablets */
@media (max-width: 1024px) {
    .dash-row {
        grid-template-columns: repeat(6, 1fr) !important;
    }
    .dash-col-third {
        grid-column: span 3 !important;
    }
    .dash-col-twothird {
        grid-column: span 6 !important;
    }
    /* Platforms vallen op tablets terug naar volle breedte zodat de
     * content ademruimte houdt. */
    .dash-grid-container > .dash-platform-twothird,
    .dash-grid-container > .dash-platform-half,
    .dash-grid-container > .dash-platform-third {
        grid-column: span 6 !important;
    }

    /* Vangnet tegen weggeknipte inhoud (05-08-2026).
     *
     * .dashboard-section staat op overflow:hidden zodat charts binnen hun rand
     * blijven. Er bestond al een correctie die daar overflow-x:auto van maakt,
     * maar die zat vast op max-width:768px — dus alleen telefoons. Op een iPad
     * in staande stand (768, 810, 820, 834, 1024 px) gold hij niet.
     *
     * Gemeten op 820px: vijf dashboardsecties hadden 436px inhoud in een vak
     * van 229px, met overflow:hidden. Die inhoud was onzichtbaar EN
     * onbereikbaar, want er verscheen geen schuifbalk. Dat is erger dan lelijk:
     * de werkvloer werkt op tablet, en wat je niet kan bereiken bestaat niet.
     *
     * Verticaal blijft hidden zodat het platform-effect intact blijft. */
    .dashboard-section {
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        max-width: 100%;
    }
}

/* Tablet in staande stand: één kolom per rij. Twee kolommen naast elkaar laten
   op 600px bruikbare breedte geeft vakken van ~230px, en daar past geen enkele
   dashboardkaart fatsoenlijk in. Liever volle breedte en scrollen met de duim.
   Boven 900px (tablet in liggende stand, laptops) blijft de kolomindeling. */
@media (max-width: 900px) {
    .dash-col-half, .dash-col-third, .dash-col-twothird {
        grid-column: span 6 !important;
    }
}

/* Small tablets / large phones */
@media (max-width: 768px) {
    .dash-row {
        grid-template-columns: 1fr !important;
    }
    .dash-col-half, .dash-col-third, .dash-col-twothird, .dash-col-full {
        grid-column: span 1 !important;
    }
    .sidebar {
        display: none;
    }
    .sidebar.open {
        display: flex;
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        /* Boven de topbalk (1100). Die kreeg op 10-8 een z-index om de
         * meldingenlijst te redden, en schilderde daardoor over dit menu:
         * gemeten gaf een tik op het logo de hamburger, en het waas ontbrak. */
        z-index: var(--laag-menu, 1300);
        width: 220px;
        box-shadow: 4px 0 20px rgba(0,0,0,.3);
    }
    .sidebar-overlay {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(0,0,0,.4);
        z-index: var(--laag-menu-waas, 1250);
    }
    .sidebar-overlay.open {
        display: block;
    }
    .main {
        margin-left: 0 !important;
    }
    .topbar {
        padding: .5rem !important;
        flex-wrap: wrap !important;
        gap: .4rem !important;
    }
    .topbar > div {
        flex-wrap: wrap !important;
        gap: .3rem !important;
    }
    .topbar h2 {
        font-size: 1rem !important;
    }
    .hamburger-btn {
        display: flex !important;
        flex-shrink: 0 !important;
    }
    .adm-card-title {
        font-size: .8rem !important;
    }
    .content {
        padding: .8rem 1rem !important;
    }
    /* Mobile-fix 28-04-2026: hero-card moest compacter, en section-group
       padding mocht niet 1.6rem blijven want dat duwt content uit beeld. */
    .dash-section-group {
        padding: 1rem .9rem 1.1rem !important;
    }
    .dash-card-hero {
        padding: 1rem 1.1rem !important;
        min-height: auto !important;
    }
    .dash-card-hero .hero-greet {
        font-size: 1.25rem !important;
    }
    .dash-card-hero .hero-sub {
        font-size: .82rem !important;
    }
    .dash-grid-container {
        gap: 1rem !important;
    }
    /* "Indeling"-toggle is desktop-only, neemt mobile-ruimte zonder reden */
    #dash-edit-toggle {
        display: none !important;
    }
    /* Maand-/jaar-selector compacter op mobile (knoppen kleiner, gap krimpt).
       De maand- en de jaarhelft zitten elk in een eigen blokje (ze worden los
       van elkaar getoond), dus die krijgen dezelfde krimp. */
    #month-year-selector,
    #maand-kiezer,
    #jaar-kiezer {
        font-size: .72rem !important;
        gap: .15rem !important;
        flex-wrap: nowrap;
    }
    #month-year-selector button {
        padding: .15rem .3rem !important;
        font-size: .7rem !important;
    }
    #month-year-selector span {
        min-width: auto !important;
        font-size: .75rem !important;
    }
    /* Topbar: ruimte voor maand+jaar; topbar mag wrappen, rechter-div ook */
    .topbar {
        justify-content: flex-start !important;
    }
    .topbar > div {
        flex-wrap: wrap !important;
        max-width: 100%;
        gap: .3rem !important;
    }
    /* "Rapport downloaden"-knop volledig en op eigen rij */
    .dash-grid-container > [style*="Rapport downloaden"],
    .dash-grid-container > div:has(> button[onclick*="downloadMaandrapport"]) {
        text-align: center !important;
    }
}

/* Phones */
@media (max-width: 480px) {
    .adm-card {
        padding: .6rem !important;
    }
    .target-row .target-label {
        width: 60px !important;
        font-size: .7rem !important;
    }
    .target-row .target-values {
        min-width: 70px !important;
        font-size: .7rem !important;
    }
    .topbar h2 {
        font-size: .9rem !important;
    }
    .kpi-grid {
        grid-template-columns: 1fr 1fr !important;
    }
}

/* Hamburger menu button - hidden by default, shown on small screens */
.hamburger-btn {
    display: none;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
    color: var(--primary);
    padding: .2rem .5rem;
    margin-right: .5rem;
}

/* Stock Voertuigen - Dropzone */
.stock-dropzone {
    border: 2px dashed var(--border);
    border-radius: 10px;
    padding: 1.2rem;
    text-align: center;
    cursor: pointer;
    transition: all .2s;
    margin-bottom: 1rem;
    background: var(--card);
}
.stock-dropzone:hover {
    border-color: var(--accent);
    background: var(--hover-bg);
}
.stock-dropzone-active {
    border-color: var(--accent) !important;
    background: var(--orange-soft) !important;
    box-shadow: 0 0 0 3px rgba(133,117,78,.15);
}

/* Stock status badges */
.stock-status-badge {
    display: inline-block;
    padding: .15rem .5rem;
    border-radius: 12px;
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
}
.stock-status-instock { background: var(--green-soft); color: var(--green); }
.stock-status-verkocht { background: var(--blue-soft); color: var(--blue); }
.stock-status-gereserveerd { background: var(--orange-soft); color: var(--orange); }
.stock-status-intransit { background: #f0f0f0; color: var(--muted-leesbaar); }

/* Stock table */
.stock-table { width: 100%; }
.stock-table th { font-size: .8rem; text-transform: uppercase; letter-spacing: .3px; color: var(--muted-leesbaar); }
.stock-table td { font-size: .85rem; }
.stock-table tr:hover { background: var(--table-hover); }

/* Stock spinner */
.stock-spinner {
    width: 28px;
    height: 28px;
    border: 3px solid var(--border);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: stock-spin 0.8s linear infinite;
    margin: 0 auto .5rem;
}
@keyframes stock-spin { to { transform: rotate(360deg); } }

/* Export button */
.btn-export {
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 4px 12px;
    font-size: .85rem;
    cursor: pointer;
    transition: all .15s;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}
.btn-export:hover {
    background: var(--primary);
    color: #fff;
    border-color: var(--primary);
}

/* Lead Score Badges */
.lead-score-badge {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .2rem .6rem;
    border-radius: 12px;
    font-size: .8rem;
    font-weight: 700;
    cursor: pointer;
    transition: transform .15s, box-shadow .15s;
    white-space: nowrap;
}
.lead-score-badge:hover {
    transform: scale(1.08);
    box-shadow: 0 2px 8px rgba(0,0,0,.15);
}
.lead-score-hot {
    background: #e8f5e9;
    color: #2e7d32;
    border: 1px solid #a5d6a7;
}
.lead-score-warm {
    background: #fff3e0;
    color: #e65100;
    border: 1px solid #ffcc80;
}
.lead-score-cold {
    background: #fce4ec;
    color: #c62828;
    border: 1px solid #ef9a9a;
}

/* ========== Dark Mode Toggle ========== */
.dark-mode-toggle {
    background: none;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: .3rem .5rem;
    font-size: 1.1rem;
    cursor: pointer;
    transition: background .2s, border-color .2s;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dark-mode-toggle:hover {
    background: var(--hover-bg);
    border-color: var(--accent);
}

/* ========== Dark Mode Overrides ========== */
/* Contrast-fix 22-04-2026: regel van user — als de achtergrond licht is,
   gebruik donkere tekst. In dark-mode wordt --primary lichtgrijs (#e8e6e3),
   dus btn-primary met witte tekst werd onleesbaar. Losstaand: .btn-danger
   en .btn-success hadden ook witte tekst op een zacht-gekleurde pastel bg
   (salmon/mint) wat onvoldoende AA-contrast was.
   Vervangen door: gouden/pastel bg + midnight-donkere tekst. */
[data-theme="dark"] .btn-primary {
    background: var(--accent);
    color: #0a1421;
}
[data-theme="dark"] .btn-primary:hover {
    background: #d9bd78;
    color: #0a1421;
}
[data-theme="dark"] .btn-danger {
    background: var(--red);
    color: #0a1421;
}
[data-theme="dark"] .btn-success {
    background: var(--green);
    color: #0a1421;
}
[data-theme="dark"] .login-box button {
    background: var(--accent);
    color: #0a1421;
}
[data-theme="dark"] .login-box button:hover { background: #d9bd78; color: #0a1421; }

/* Andere plekken met licht-bg + wit-tekst-patroon die ook in dark mode
   omgezet moeten worden naar donkere tekst op accent (feedback 22-04-2026). */
[data-theme="dark"] .opv-type-btn.active {
    background: var(--accent);
    color: #0a1421;
}
[data-theme="dark"] .ms-tag {
    background: var(--accent);
    color: #0a1421;
}
[data-theme="dark"] .dash-add-block-btn {
    background: var(--accent) !important;
    color: #0a1421 !important;
}
[data-theme="dark"] .btn-export:hover {
    background: var(--accent);
    color: #0a1421;
    border-color: var(--accent);
}
/* dash-remove-btn:hover behoudt witte tekst — de --red pastel is donker
   genoeg (#d4877a) om met wit te combineren (ratio ~3:1), acceptabel voor
   large-text / icon-only buttons. */

/* ---- KPI-tegel witte-gradient override (feedback 22-04-2026) ----
   Inline styles in dashboard.js gebruiken `background:linear-gradient(145deg,
   #ffffff, #f5f5f0)` en `color:var(--midnight)` voor de KPI-tegels. Dat werkt prima
   in light-mode, maar in dark-mode blijven die als helder-witte eilanden
   staan op de donkere achtergrond (en voelt inconsistent met de rest).
   We rulen het via [style*=...]-attribute-selector + !important zodat we
   ~15 inline patronen in een keer dark-themen zonder elke JS-renderer aan
   te passen. Later kunnen we dit nog refactoren naar een .dash-kpi-tegel
   class, maar dit werkt nu consistent. */
[data-theme="dark"] [style*="linear-gradient(145deg, #ffffff"] {
    background: var(--surface-raised) !important;
    background-image: none !important;
    border: 1px solid var(--surface-hairline) !important;
    box-shadow: var(--shadow-sm) !important;
    color: var(--text-primary) !important;
}
[data-theme="dark"] [style*="linear-gradient(145deg, #ffffff"]:hover {
    background: var(--surface-raised-hover) !important;
    box-shadow: var(--shadow-md) !important;
    border-color: var(--surface-border-strong) !important;
}
/* Donkere inline-kleur `#05141E` op KPI-getallen moet licht worden in dark. */
[data-theme="dark"] [style*="color:#05141E"],
[data-theme="dark"] [style*="color: #05141E"] {
    color: var(--text-primary) !important;
}

/* ---- Section-groups als 3D-platform (feedback 22-04-2026) ----
   Elke sectie (header + row) zit in een <section.dash-section-group>
   wrapper die we stijlen als één verhoogd vlak. De individuele
   .dash-cards binnenin worden subtieler (geen eigen heavy shadow meer)
   zodat er geen visuele dubbele-3D is.

   Body krijgt daarnaast 2 subtiele radial-gradients als ambient
   belichting — warm goud van boven + koele blauw van onder. */
[data-theme="dark"] body {
    background:
        radial-gradient(ellipse 1400px 900px at 50% -10%, rgba(196,168,98,.05) 0%, transparent 55%),
        radial-gradient(ellipse 1200px 800px at 50% 110%, rgba(125,175,201,.035) 0%, transparent 55%),
        var(--midnight-900);
}
[data-theme="dark"] .dash-grid-container {
    gap: 2.2rem;
}
[data-theme="dark"] .dash-row {
    gap: 1.2rem;
}
/* Section-group: het 3D-platform zelf. Iets lichter dan de body zodat
   het leest als "raised surface", met multi-layer shadow die het boven
   het canvas tilt. Header + row zitten samen IN deze container. */
[data-theme="dark"] .dash-section-group {
    background: linear-gradient(180deg, rgba(26,38,55,.65) 0%, rgba(20,30,45,.55) 100%);
    border: 1px solid rgba(196,168,98,.18);
    border-radius: var(--radius-xl);
    padding: 1.6rem 1.8rem 1.8rem;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.04),
        0 2px 6px rgba(0,0,0,.25),
        0 12px 28px rgba(0,0,0,.3),
        0 32px 64px rgba(0,0,0,.22);
    transition: border-color .3s cubic-bezier(.4,0,.2,1),
                box-shadow .3s cubic-bezier(.4,0,.2,1);
}
[data-theme="dark"] .dash-section-group:hover {
    border-color: rgba(196,168,98,.3);
}
/* De section-header zit nu binnen de group — geen extra margin nodig. */
[data-theme="dark"] .dash-section-group .dash-section-header {
    margin-bottom: 1.2rem;
    padding: 0;
}
/* De dash-row binnen een section-group heeft geen eigen margin nodig. */
[data-theme="dark"] .dash-section-group .dash-row {
    margin: 0;
}

/* ---- Multi-row platforms (feat 22-04-2026) ----
   Een platform kan nu meerdere .dash-row's bevatten (bv. 1/1 boven
   [1/2, 1/2]). Sub-rijen krijgen een zacht scheidings-lintje + extra
   vertical gap zodat ze duidelijk als aparte rijen binnen hetzelfde
   platform leesbaar zijn. */
.dash-section-group-multi .dash-row + .dash-row {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px dashed rgba(0,0,0,.08);
}
[data-theme="dark"] .dash-section-group-multi .dash-row + .dash-row {
    border-top-color: rgba(196,168,98,.18);
}
.dash-row-merged { position: relative; }
/* Individuele cards BINNEN een group: subtieler, geen heavy floating-
   shadow want het platform geeft al diepte. Lichte inset-highlight +
   compactere shadow. */
[data-theme="dark"] .dash-section-group .dash-card {
    border: 1px solid rgba(196,168,98,.15);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.04),
        0 1px 3px rgba(0,0,0,.2),
        0 4px 8px rgba(0,0,0,.15);
}
[data-theme="dark"] .dash-section-group .dash-card:hover {
    border-color: rgba(196,168,98,.32);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.07),
        0 4px 8px rgba(0,0,0,.3),
        0 12px 24px rgba(0,0,0,.25);
}
/* Welkom-hero zit NIET in een section-group (headerless row) — eigen
   drop-shadow zodat hij de dominante "landing" tile blijft. */
[data-theme="dark"] .dash-card-hero {
    box-shadow:
        inset 0 1px 0 rgba(196,168,98,.15),
        0 4px 8px rgba(0,0,0,.3),
        0 20px 40px rgba(0,0,0,.4),
        0 48px 80px rgba(0,0,0,.25);
}

/* Ranking 'jij' row highlight. Per thema verschillende bg+tekst-combi zodat
   het voldoende contrast heeft in beide modes. (Was inline hardcoded
   #eef3ff bg wat in dark-mode onleesbaar was.) */
.row-is-me {
    background: #eef3ff;
    color: #0a1421;
}
[data-theme="dark"] .row-is-me {
    background: rgba(196,168,98,.18);
    color: var(--text-primary);
    box-shadow: inset 2px 0 0 var(--gold);
}
[data-theme="dark"] .table-toolbar select,
[data-theme="dark"] .table-toolbar input {
    background: var(--input-bg);
    color: var(--input-text);
}
[data-theme="dark"] .opv-timeline-item.opv-planned {
    background: #332b14;
    border-color: var(--orange);
}
[data-theme="dark"] .pipeline-overdue-alert {
    background: var(--red-soft);
}
[data-theme="dark"] .dash-edit-toolbar {
    background: linear-gradient(135deg, #1a2633, #152030);
}
[data-theme="dark"] .dashboard-section.editing {
    background: rgba(26,38,51,.6);
}
[data-theme="dark"] .dashboard-section.editing .section-handle {
    background: linear-gradient(135deg, #1e2d3a, #253545);
}
[data-theme="dark"] .dash-edit-btn:hover { background: var(--hover-bg); }
[data-theme="dark"] .width-btn:hover { background: var(--hover-bg); }

/* Contrast-fixes (03-08-2026) — deze knoppen/badges hadden nog licht-thema
   kleuren (#666, #777, #8c5e1f) of helemaal geen kleur, terwijl de app sinds
   april dark-only is. Gemeten met WCAG-contrastberekening op de echte
   samengestelde achtergrond:
     .btn-export      1.13 : 1  (zwarte tekst op donkere kaart — onleesbaar)
     .aandacht-badge  2.36 : 1
     .dash-edit-btn   3.01 : 1
     .width-btn       3.14 : 1
   Vereist is 4.5 : 1 voor normale tekst. Onderstaande waarden halen dat. */
[data-theme="dark"] .btn-export { color: var(--text); }
[data-theme="dark"] .dash-edit-btn { color: var(--text-secondary); }
[data-theme="dark"] .width-btn { color: var(--text-secondary); }
[data-theme="dark"] .aandacht-badge { color: var(--orange); }
[data-theme="dark"] .model-badge {
    background: var(--blue-soft);
    color: var(--blue);
}
[data-theme="dark"] .badge-stock { background: var(--blue-soft); color: var(--blue); }
[data-theme="dark"] .badge-verkocht { background: var(--green-soft); color: var(--green); }
[data-theme="dark"] .badge-demo { background: var(--orange-soft); color: var(--orange); }

/* Contrast-fixes, tweede ronde (05-08-2026).
   De ronde van 03-08 pakte vier elementen aan; er stonden er nog zeventien met
   hetzelfde probleem. Live gemeten in de browser op het draaiende systeem:
     .aandacht-afdeling-count   1.23 : 1   (het aantal naast een afdeling)
   Dat cijfer was in de praktijk onzichtbaar: #333 op een donkerblauwe kaart.

   Twee patronen zaten erachter.

   1. Twaalf regels zetten color:#333 of #555 zonder tegenhanger voor het
      donkere thema. Ze staan nu op var(--text-primary) / var(--text-secondary),
      wat in beide thema's klopt. Dat is beter dan er nog een override bij
      zetten: een variabele kan niet vergeten worden.

   2. Vijf regels combineerden een pastelachtergrond met een vaste
      lichte-thema-tekstkleur: background:var(--red-soft) met color:#8f4a3f.
      In donker is --red-soft juist bijna zwart (#331a15), dus stond er donkere
      tekst op een donkere ondergrond. Ze halen hun voorgrond nu uit de
      bijbehorende var(--red) / var(--orange) / var(--green), die in donker
      licht zijn.

   Regel voor wie hier verder werkt: een *-soft achtergrond wordt NOOIT met een
   hardcoded hex gecombineerd. De voorgrond komt uit de bijbehorende var(--*). */

/* Form section headers */
.form-section-header {
    grid-column: 1 / -1;
    font-weight: 700;
    font-size: .95rem;
    color: var(--primary);
    border-bottom: 2px solid var(--accent);
    padding-bottom: .3rem;
    margin-top: 1rem;
    margin-bottom: .5rem;
}

.form-section-header:first-of-type {
    margin-top: 0;
}

/* Form validation styling */
.field-required label span { color:var(--red-tekst); }

/* ========== Dark Mode Text Contrast Fixes ========== */
/* Fix inline-styled text that uses hardcoded colors */
[data-theme="dark"] [style*="color:#05141E"],
[data-theme="dark"] [style*="color: #05141E"] {
    color: var(--text) !important;
}
[data-theme="dark"] [style*="color:#1a2a3a"],
[data-theme="dark"] [style*="color: #1a2a3a"] {
    color: var(--text) !important;
}
[data-theme="dark"] [style*="color:#333"],
[data-theme="dark"] [style*="color: #333"] {
    color: var(--text) !important;
}
[data-theme="dark"] [style*="color:#000"],
[data-theme="dark"] [style*="color: #000"] {
    color: var(--text) !important;
}

/* Fix dark backgrounds with dark text in dark mode.
 *
 * LET OP — de meldingstinten (#fdecea, #e8f5e9, #fff3cd, #fff8e1,
 * #fef9e7, #ffebee, #e3f2fd, ...) stonden hier vroeger ook. Die zijn
 * verhuisd naar het blok "MELDINGSNIVEAUS" onderaan dit bestand, omdat
 * ze in BEIDE thema's moeten kloppen en niet alleen in het donkere.
 * Zet ze hier niet terug: dan botsen ze opnieuw met elkaar.
 */
[data-theme="dark"] [style*="background:#fafafa"],
[data-theme="dark"] [style*="background: #fafafa"] {
    background: var(--card) !important;
}
/* WIT (en alleen wit) omzetten naar de kaartkleur.
 *
 * OORZAAK VAN DE ONLEESBARE MELDINGEN (opgelost 2026-08-05):
 * hier stond [style*="background:#fff"] zonder afsluiting. "#fff" is een
 * deelreeks van "#fff3cd", "#fff8e1", "#fff3e0", ... dus deze regel
 * kaapte élk geel meldingsblok en gaf het de donkere kaartkleur, terwijl
 * een andere regel de tekst juist donker maakte -> 1,01 : 1.
 * De afsluitende ";" (of het einde van het style-attribuut) maakt de
 * match exact, zodat alleen écht wit hier nog onder valt.
 */
[data-theme="dark"] [style*="background:#fff;"],
[data-theme="dark"] [style*="background: #fff;"],
[data-theme="dark"] [style$="background:#fff"],
[data-theme="dark"] [style$="background: #fff"],
[data-theme="dark"] [style*="background:#ffffff"],
[data-theme="dark"] [style*="background: #ffffff"] {
    background: var(--card) !important;
}
[data-theme="dark"] [style*="background:#f8f9fa"],
[data-theme="dark"] [style*="background: #f8f9fa"] {
    background: var(--table-header-bg) !important;
}

/* Oude, hard ingebakken accentkleuren uit de JS-templates.
 * Binnen een meldingsblok erven ze de voorgrondkleur van dat blok
 * (--melding-fg wordt daar gezet, zie het MELDINGSNIVEAUS-blok onderaan);
 * daarbuiten vallen ze terug op --legacy-*-fg, die per thema gezet is.
 * Zo blijft bv. "Manuele levering - geen klantportaal" leesbaar op de
 * amber achtergrond in plaats van erin te verdwijnen. */
[style*="color:#856404"],
[style*="color:#8a6d1f"],
[style*="color:#8a5c0f"],
[style*="color:#7a4d00"],
[style*="color:#6b4d05"],
[style*="color:#6a4a0a"],
[style*="color:#9a7d3a"],
[style*="color:#b8860b"],
[style*="color:#e65100"],
[style*="color: #856404"],
[style*="color: #e65100"] {
    color: var(--melding-fg, var(--legacy-amber-fg)) !important;
}
[style*="color:#c0392b"],
[style*="color:#c62828"],
[style*="color:#b71c1c"],
[style*="color: #c0392b"] {
    color: var(--melding-fg, var(--legacy-rood-fg)) !important;
}
/* Vast ingebakken grijstinten voor bijzin-tekst. BUITEN een meldingsblok
 * blijven ze exact wat ze waren (de fallback is de originele waarde);
 * BINNEN een meldingsblok worden ze de zachte ernst-kleur. Het grijs
 * #aaa op de amber achtergrond haalde in het lichte thema maar 2,14 : 1
 * — nagemeten op de levering-detailpagina. */
[style*="color:#aaa"], [style*="color: #aaa"] { color: var(--melding-fg-zacht, #aaa) !important; }
[style*="color:#ccc"], [style*="color: #ccc"] { color: var(--melding-fg-zacht, #ccc) !important; }
[style*="color:#888"], [style*="color: #888"] { color: var(--melding-fg-zacht, #888) !important; }
[style*="color:#999"], [style*="color: #999"] { color: var(--melding-fg-zacht, #999) !important; }
[style*="color:#666"], [style*="color: #666"] { color: var(--melding-fg-zacht, #666) !important; }
[style*="color:#8C9091"], [style*="color:#8c9091"] { color: var(--melding-fg-zacht, #8C9091) !important; }

/* Een knop met alleen een rand en geen vlak erfde zwarte tekst en kwam in het
 * donkere thema op een donkere kaart terecht: 1.22:1.
 *
 * Bewust ALLEEN knoppen zonder eigen vlakkleur. Een eerdere, bredere versie
 * (`button:not([class*="btn-"])`) raakte ook .width-btn.active — die heeft juist
 * wél een gouden vlak en een eigen, nagemeten tekstkleur, en die werd
 * overschreven. Breed is hier gevaarlijker dan smal. */
[data-theme="dark"] button[style*="background:none"],
[data-theme="dark"] button[style*="background: none"] {
    color: var(--text);
}

/* Status badges readable in dark mode */
[data-theme="dark"] .status-badge-green { background: #1a5032; color: #7dcea0; }
[data-theme="dark"] .status-badge-red { background: #6e2c22; color: #f1948a; }
[data-theme="dark"] .status-badge-orange { background: #7d5a1e; color: #f0c27a; }
[data-theme="dark"] .status-badge-blue { background: #1a3d5c; color: #85c1e9; }

/* Pipeline segments text in dark mode */
/* Ook de TEKSTkleur omdraaien, niet alleen de achtergrond. Stond die niet
 * mee, dan bleef de donkere tekst uit het lichte thema staan — precies de
 * kleur die hier de achtergrond wordt. Gemeten: 1.00:1, het cijfer in het
 * segment was onzichtbaar. */
[data-theme="dark"] .pipeline-green { background: #1a5032; color: #7dcea0; }
[data-theme="dark"] .pipeline-blue { background: #1a3d5c; color: #85c1e9; }
[data-theme="dark"] .pipeline-red { background: #6e2c22; color: #f1948a; }
[data-theme="dark"] .pipeline-open { background: #1a3d5c; color: #85c1e9; }
[data-theme="dark"] .pipeline-opvolging { background: #5a4618; color: #f7d794; }
[data-theme="dark"] .pipeline-legend-open { background: #85c1e9; }
[data-theme="dark"] .pipeline-legend-opvolging { background: #f7d794; }

/* Witte tekst op een gouden vlak. In het donkere thema is --gold licht
 * (#c4a862) en haalt wit erop 2.30:1; de donkere achtergrondkleur haalt 8.04:1.
 * Geldt zowel voor knoppen als voor de statuslabels in Leveringen. */
[data-theme="dark"] [style*="background:var(--gold)"],
[data-theme="dark"] [style*="background: var(--gold)"] {
    color: var(--bg) !important;
}

/* Fix hardcoded border colors */
[data-theme="dark"] [style*="border:1px solid #e0e0e0"],
[data-theme="dark"] [style*="border: 1px solid #e0e0e0"] {
    border-color: var(--border) !important;
}
[data-theme="dark"] [style*="border:1px solid #ccc"],
[data-theme="dark"] [style*="border: 1px solid #ccc"],
[data-theme="dark"] [style*="border:2px dashed #ccc"] {
    border-color: var(--border) !important;
}

/* Fix inline selects/inputs */
[data-theme="dark"] select,
[data-theme="dark"] input[type="text"],
[data-theme="dark"] input[type="date"],
[data-theme="dark"] input[type="number"],
[data-theme="dark"] input[type="datetime-local"],
[data-theme="dark"] textarea {
    background: var(--input-bg);
    color: var(--input-text);
    border-color: var(--border);
}

/* Berichten panel dark mode */
[data-theme="dark"] [style*="background:#f3e8ff"] {
    background: #2a2438 !important;
}

/* Commission wrap styling */
[data-theme="dark"] .comm-needed { background: rgba(212,135,122,.15); border-color: rgba(212,135,122,.4); }
[data-theme="dark"] .comm-achieved { background: rgba(110,196,133,.15); border-color: rgba(110,196,133,.4); }

/* ========== Card Styling ========== */
.card-bg { background: var(--card); }
/* Ronde 2: .dash-card krijgt eigen lichte border (rgba(0,0,0,.04)) via
   zijn basis-definitie. .kpi-card/.table-wrap/.pipeline-section blijven
   de oude --border (zelfde als vóór ronde 2). */
.kpi-card, .table-wrap, .pipeline-section {
    border: 1px solid var(--border);
}
[data-theme="dark"] .kpi-card,
[data-theme="dark"] .table-wrap,
[data-theme="dark"] .pipeline-section {
    border-color: var(--border);
    box-shadow: 0 1px 6px rgba(0,0,0,.15);
}
[data-theme="dark"] .dash-grid-container .dash-card {
    background: var(--card-gradient);
    border-color: rgba(255,255,255,.05);
    box-shadow: var(--shadow-sm);
}
[data-theme="dark"] .dash-grid-container .dash-card:hover {
    border-color: rgba(196,168,98,.25);
    box-shadow: var(--shadow-md);
}
[data-theme="dark"] .modal {
    border: 1px solid var(--border);
    box-shadow: 0 8px 40px rgba(0,0,0,.5);
}

/* ========== Floating Chat Widget ========== */
#chat-bubble:hover {
    transform: scale(1.08);
}
#chat-bubble.has-unread {
    /* Drie keer, niet eeuwig. Het aantal ongelezen berichten staat als
       cijfer in de badge; de puls is een tik op de schouder, geen alarm
       dat de hele dag afgaat. */
    animation: chat-bubble-pulse 1.8s ease-in-out 3;
}
@keyframes chat-bubble-pulse {
    0%, 100% { box-shadow: 0 4px 16px rgba(0,0,0,.2), 0 0 0 0 rgba(231,76,60,.55); }
    50% { box-shadow: 0 4px 16px rgba(0,0,0,.2), 0 0 0 14px rgba(231,76,60,0); }
}
#chat-bubble.has-unread #chat-bubble-icon {
    /* Wiebelen geschrapt (22-8-2026). Het cijfer in de badge zegt al
       hoeveel er wachten; bewegen voegt daar niets aan toe en het staat
       op elk scherm de hele dag in beeld. */
    display: inline-block;
    transform-origin: center;
}
@keyframes chat-bubble-wiggle {
    0%, 60%, 100% { transform: rotate(0deg); }
    10% { transform: rotate(-14deg); }
    20% { transform: rotate(14deg); }
    30% { transform: rotate(-10deg); }
    40% { transform: rotate(10deg); }
    50% { transform: rotate(0deg); }
}
#chat-bubble-badge {
    animation: chat-badge-pop .5s ease-out;
}
@keyframes chat-badge-pop {
    0% { transform: scale(0); }
    60% { transform: scale(1.25); }
    100% { transform: scale(1); }
}
[data-theme="dark"] #chat-panel {
    box-shadow: 0 8px 32px rgba(0,0,0,.5);
}

/* Chat bubble: emojis embedded in a text message rendered 2x larger */
.chat-bubble-text .chat-emoji-big {
    font-size: 2em;
    line-height: 1;
    vertical-align: middle;
    display: inline-block;
}

/* ========== Chat Emoji Picker (emoji-picker-element) ========== */
.salessync-emoji-picker {
    /* Fit in the 360px-wide chat panel */
    width: 100% !important;
    height: 300px !important;
    /* Light-mode look by default; override via [data-theme="dark"] below */
    --background: var(--card);
    --border-color: var(--border);
    --button-active-background: var(--hover-bg);
    --button-hover-background: var(--hover-bg);
    --indicator-color: #85754E;
    --input-border-color: var(--border);
    --input-background-color: var(--card);
    --input-font-color: var(--text);
    /* Ook tekst, dus ook de leesbare variant. Zie --muted-leesbaar. */
    --input-placeholder-color: var(--muted-leesbaar);
    --category-emoji-padding: 0.2rem;
    --category-font-color: var(--muted-leesbaar);
    --num-columns: 8;
    --emoji-size: 1.3rem;
}
[data-theme="dark"] .salessync-emoji-picker {
    /* emoji-picker-element has a built-in dark theme via attribute */
}

/* ========== Chat Toast (center-screen) ========== */
.chat-toast {
    background: var(--card);
    border: 2px solid var(--gold);
    border-radius: 12px;
    padding: 1rem 1.25rem;
    min-width: 380px;
    max-width: 480px;
    box-shadow: 0 16px 48px rgba(0,0,0,.3), 0 0 0 4px rgba(133,117,78,.12);
    cursor: pointer;
    pointer-events: auto;
    position: relative;
    animation: chat-toast-in .4s cubic-bezier(.22,1.25,.4,1), chat-toast-pulse 1.2s ease-in-out .4s 2;
}
@keyframes chat-toast-in {
    from { transform: scale(.7); opacity: 0; }
    to   { transform: scale(1); opacity: 1; }
}
@keyframes chat-toast-pulse {
    0%, 100% { box-shadow: 0 16px 48px rgba(0,0,0,.3), 0 0 0 4px rgba(133,117,78,.12); }
    50%      { box-shadow: 0 16px 48px rgba(0,0,0,.3), 0 0 0 10px rgba(133,117,78,.22); }
}
.chat-toast.closing {
    animation: chat-toast-out .3s ease-in forwards;
}
@keyframes chat-toast-out {
    to { transform: scale(.85); opacity: 0; }
}
.chat-toast-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .4rem;
    padding-bottom: .4rem;
    border-bottom: 1px solid var(--border);
}
.chat-toast-name {
    font-weight: 700;
    font-size: 1rem;
    color: var(--text);
}
.chat-toast-close {
    background: none;
    border: none;
    color: var(--muted-leesbaar);
    cursor: pointer;
    font-size: 1.3rem;
    padding: 0 .35rem;
    line-height: 1;
}
.chat-toast-close:hover {
    color: var(--text);
}
.chat-toast-body {
    font-size: .95rem;
    color: var(--text);
    line-height: 1.4;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    margin-bottom: .5rem;
}
.chat-toast-hint {
    font-size: .7rem;
    color: var(--muted-leesbaar);
    text-align: right;
    font-style: italic;
}


/* ============================================================
   Aandachtspunten v3 — unified melder widget
   ============================================================ */
.aandacht-widget {
    width: 100%;
    margin: 0 0 1.5rem 0;
    background: var(--card, #fff);
    border: 1px solid var(--border, #e0e0e0);
    border-radius: 10px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
    overflow: hidden;
    transition: background 0.2s, border-color 0.2s;
}
/* Aandacht-widget: subtiele linker-rand-indicator in plaats van een
   roze/rode fill over de volle widget. */
.aandacht-widget.has-items {
    background: var(--card, #fff);
    border-color: var(--border, #e0e0e0);
    border-left: 3px solid var(--red, #c17b6e);
}
[data-theme="dark"] .aandacht-widget.has-items {
    background: var(--card);
    border-color: var(--border);
    border-left-color:var(--red-tekst);
}

.aandacht-loading,
.aandacht-error,
.aandacht-empty {
    padding: 1rem 1.2rem;
    font-size: 0.9rem;
    color: var(--muted, #666);
}

.aandacht-empty {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: linear-gradient(to right, #e8f5e9, transparent 60%);
    border-left: 3px solid var(--green);
    color: #2e7d32;
    font-weight: 500;
}
.aandacht-empty-icon {
    font-size: 1.1rem;
    color: var(--green);
}

.aandacht-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.8rem 1.2rem;
    background: linear-gradient(to bottom, #fafafa, #f5f5f5);
    border-bottom: 1px solid var(--border, #e0e0e0);
}
.aandacht-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--text-primary);
}
.aandacht-title-icon {
    color: #b4571b;
    font-size: 1.1rem;
}
.aandacht-badge {
    background: var(--orange-soft, #fdf5e6);
    color: #8c5e1f;
    border: 1px solid rgba(201,168,76,.35);
    padding: 0.1rem 0.55rem;
    border-radius: 12px;
    font-size: 0.75rem;
    font-weight: 700;
    min-width: 24px;
    text-align: center;
}
.aandacht-refresh {
    background: transparent;
    border: none;
    color: var(--muted, #888);
    cursor: pointer;
    font-size: 1.1rem;
    padding: 0.2rem 0.4rem;
    border-radius: 4px;
    transition: all 0.15s;
}
.aandacht-refresh:hover {
    background: rgba(0, 0, 0, 0.05);
    color: var(--text-primary);
}

.aandacht-section {
    padding: 0.5rem 0.8rem 0.8rem;
}
.aandacht-section.admin-section {
    background: #fafafa;
    border-top: 1px solid var(--border, #e0e0e0);
}

.aandacht-section-sub {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.4rem 0.6rem;
    font-size: 0.75rem;
}
.aandacht-section-title {
    font-weight: 600;
    color: var(--text-primary);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.aandacht-pill {
    padding: 0.15rem 0.6rem;
    border-radius: 10px;
    font-weight: 700;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.aandacht-pill.oranje { background: var(--orange-soft, #fdf5e6); color: var(--orange); border: 1px solid rgba(201,168,76,.35); }
.aandacht-pill.rood   { background: var(--red-soft, #faf0ee); color:var(--red-tekst); border: 1px solid rgba(193,123,110,.35); }
/* DE ZWAARSTE PIL STOND ER ALS DE ZWAKSTE BIJ (schermrapport 10-8-2026)
   .aandacht-pill.admin bestond nergens in deze CSS: alleen de basisregel en
   .oranje / .rood stonden er. De escalatiepil — die zegt dat de zaakvoerder
   meekijkt — rendeerde dus zonder achtergrond en zonder rand, terwijl ze de
   zwaarste boodschap van de drie draagt. */
.aandacht-pill.admin  { background: var(--red-soft, #faf0ee); color: var(--red-tekst); border: 1px solid rgba(193,123,110,.55); font-weight: 800; }

.aandacht-section-empty {
    padding: 0.6rem 0.8rem;
    font-size: 0.85rem;
    color: var(--muted, #888);
    font-style: italic;
}

.aandacht-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.aandacht-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.8rem;
    padding: 0.7rem 0.9rem;
    background: #fff;
    border: 1px solid var(--border, #e0e0e0);
    border-left-width: 4px;
    border-radius: 6px;
    transition: all 0.12s;
}
.aandacht-item:hover {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
    transform: translateY(-1px);
}
.aandacht-item.oranje { border-left-color: var(--orange); }
.aandacht-item.rood   { border-left-color: var(--red); }
.aandacht-item.admin  {
    border-left-color: #6a1b9a;
    background: #f9f6fc;
    cursor: pointer;
}
/* Escalatie = item dat zowel voor werker relevant is als een admin-trigger heeft.
   Paarse rand + zacht roze achtergrond om urgentie te signaleren zonder te schreeuwen. */
.aandacht-item.escalatie {
    border-left-color: #6a1b9a;
    background: linear-gradient(90deg, #f9f0f4 0%, #fff 30%);
}
[data-theme="dark"] .aandacht-item.escalatie {
    background: linear-gradient(90deg, #2a1a24 0%, #15202b 30%);
}
.aandacht-item-left { flex: 1; min-width: 0; }
.aandacht-item-label {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--text-primary);
    margin-bottom: 0.15rem;
}
.aandacht-item-desc {
    font-size: 0.82rem;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.aandacht-item-meta {
    display: flex;
    gap: 0.6rem;
    margin-top: 0.35rem;
    font-size: 0.72rem;
    flex-wrap: wrap;
}
.aandacht-age {
    color: var(--muted-leesbaar);
    font-weight: 500;
}
.aandacht-verzet {
    background: #f3e5f5;
    color: #6a1b9a;
    padding: 0.05rem 0.45rem;
    border-radius: 8px;
    font-weight: 600;
}
.aandacht-nudge {
    background: #fff3e0;
    color: #c77e1c;
    padding: 0.05rem 0.45rem;
    border-radius: 8px;
    font-weight: 600;
}
.aandacht-owner {
    color: var(--text-secondary);
    font-weight: 500;
}
.aandacht-bron {
    color: #888;
    font-style: italic;
    font-size: 0.7rem;
}
[data-theme="dark"] .aandacht-bron { color: #999; }
/* LEGACY (deprecated) — vervangen door .aandacht-escalatie-reden blok.
   Behouden zonder kleur voor backwards-compat mocht er nog output door slippen. */
.aandacht-reden {
    color: var(--muted, #666);
    font-size: 0.72rem;
}

/* "Waarom geëscaleerd" — neutraal sub-blok onder de titel.
   Geen achtergrondkleur: rustige look, gestippelde scheidingslijn bovenaan,
   label in small-caps grijs, bullets in standaard tekstkleur.
   (Feedback 20-04-2026: rustige pastel, geen gekleurde rij-achtergronden.) */
.aandacht-escalatie-reden {
    margin-top: 0.45rem;
    padding-top: 0.4rem;
    border-top: 1px dashed var(--border, #d8d8d8);
}
.aandacht-escalatie-label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--muted-leesbaar);
    margin-bottom: 0.2rem;
    text-transform: uppercase;
}
.aandacht-escalatie-list {
    margin: 0;
    padding-left: 1.1rem;
    font-size: 0.82rem;
    color: var(--text, #333);
}
.aandacht-escalatie-list li {
    margin: 0.1rem 0;
    list-style: disc;
}
[data-theme="dark"] .aandacht-escalatie-reden {
    border-top-color: #3a3a3a;
}
[data-theme="dark"] .aandacht-escalatie-label {
    color: var(--muted-leesbaar);
}
[data-theme="dark"] .aandacht-escalatie-list {
    /* ⚠️ EEN RANDKLEUR IS GEEN LETTERKLEUR.
       Hier stond var(--border-color). In het donkere thema is dat
       rgba(196,168,98,.14) — veertien procent goud, bedoeld als lijntje. Als
       tekstkleur geeft dat 1,29:1 contrast (gemeten op de draaiende app; de
       norm is 4,5:1).

       Wat er onleesbaar door werd: juist de zin die uitlegt WAAROM iets
       geëscaleerd is. Bij vijftien escalaties was de enige regel die je
       vertelt wat er aan de hand is, de regel die je niet kon lezen. */
    color: var(--muted-leesbaar);
}
.aandacht-item-right {
    display: flex;
    gap: 0.4rem;
    flex-shrink: 0;
}

.aandacht-group {
    background: #f8f9fb;
    border: 1px solid var(--border, #e0e0e0);
    border-radius: 8px;
    padding: 0.5rem;
    margin-bottom: 0.5rem;
}
.aandacht-group-header {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.6rem 0.5rem;
    font-size: 0.85rem;
    border-bottom: 1px dashed var(--border, #ddd);
    margin-bottom: 0.5rem;
}
.aandacht-group-klant {
    font-weight: 600;
    color: var(--text-primary);
}
.aandacht-group-count {
    font-size: 0.75rem;
    color: var(--muted, #888);
    margin-right: auto;
}
.aandacht-group-items {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.aandacht-history-entry {
    padding: 0.6rem 0.8rem;
    background: #fafafa;
    border-left: 3px solid #bbb;
    border-radius: 4px;
    margin-bottom: 0.5rem;
    font-size: 0.85rem;
}
.aandacht-history-entry.nudge { border-left-color: #c77e1c; background: #fff9f1; }
.aandacht-history-entry.note  { border-left-color: #3b82f6; background: #eff6ff; }
.aandacht-history-date {
    font-size: 0.75rem;
    color: var(--muted, #888);
    margin-bottom: 0.25rem;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.aandacht-history-verklaring {
    color: var(--text-primary);
    line-height: 1.4;
}
.aandacht-history-meta {
    margin-top: 0.3rem;
    font-size: 0.75rem;
    color: var(--muted, #666);
}

/* Dark mode compatibility */
[data-theme="dark"] .aandacht-widget {
    background: #1a2532;
    border-color: #2d3b47;
}
[data-theme="dark"] .aandacht-header {
    background: linear-gradient(to bottom, #15202b, #0f1822);
    border-bottom-color: #2d3b47;
}
[data-theme="dark"] .aandacht-title { color: #e5e7eb; }
/* ⚠️ GEEN border-color-VERKORTING HIER.
   Hier stond `border-color: #2d3b47`. Dat is een verkorting die ALLE VIER de
   randen zet, en hij staat later in het bestand dan de accenten op regel
   2568-2578. Gevolg: de linkerrand van elk aandachtspunt werd grijsblauw,
   ongeacht de ernst — gemeten rgb(45,59,71) op alle niveaus.

   In de enige modus waarin SalesSync draait zag dus élk aandachtspunt er
   identiek uit. Dat is precies de huisregel "de linkerrand is de indicator",
   stilletjes uitgezet. Vandaar: alleen de drie andere randen. */
[data-theme="dark"] .aandacht-item {
    background: var(--card);
    border-top-color: var(--border);
    border-right-color: var(--border);
    border-bottom-color: var(--border);
}
[data-theme="dark"] .aandacht-item-label { color: var(--text); }
[data-theme="dark"] .aandacht-item-desc { color: var(--muted-leesbaar); }
[data-theme="dark"] .aandacht-section.admin-section { background: #131c25; }
[data-theme="dark"] .aandacht-group { background: #131c25; border-color: #2d3b47; }
[data-theme="dark"] .aandacht-history-entry { background: #131c25; }
[data-theme="dark"] .aandacht-empty { background: linear-gradient(to right, #1e3a2c, transparent); color: #7dd3a6; }

/* Afdeling-blok (groepering per departement in expanded view) */
.aandacht-body { padding: 0.3rem 0.8rem 0.9rem; }
.aandacht-afdeling {
    margin-top: 0.7rem;
    background: rgba(255,255,255,0.6);
    border: 1px solid rgba(0,0,0,0.05);
    border-radius: 8px;
    overflow: hidden;
}
.aandacht-afdeling-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.4rem 0.8rem;
    background: rgba(0,0,0,0.03);
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.6px;
    color: var(--text-secondary);
}
.aandacht-afdeling-count {
    background: rgba(0,0,0,0.08);
    color: var(--text-primary);
    padding: 0.1rem 0.55rem;
    border-radius: 10px;
    font-size: 0.7rem;
}
.aandacht-afdeling-items {
    padding: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
[data-theme="dark"] .aandacht-afdeling {
    background: rgba(255,255,255,0.03);
    border-color: rgba(255,255,255,0.08);
}
[data-theme="dark"] .aandacht-afdeling-head { background: rgba(255,255,255,0.05); color: #cbd5e0; }

/* Admin-nudge banner binnen een aandachtspunt-card */
.aandacht-nudge-banner {
    display: flex;
    gap: 0.6rem;
    margin-top: 0.6rem;
    padding: 0.5rem 0.75rem;
    background: #fff8ec;
    border: 1px solid #f5d98a;
    border-left: 3px solid #c77e1c;
    border-radius: 6px;
    font-size: 0.82rem;
}
.aandacht-nudge-icon {
    color: #c77e1c;
    font-size: 1.1rem;
    flex-shrink: 0;
}
.aandacht-nudge-head {
    color: #8a5c0f;
    margin-bottom: 0.15rem;
}
.aandacht-nudge-msg {
    color: #6a4a0a;
    line-height: 1.4;
    white-space: pre-wrap;
}
[data-theme="dark"] .aandacht-nudge-banner {
    background: #2a240f;
    border-color: #4d3f1a;
    border-left-color: #c77e1c;
}
[data-theme="dark"] .aandacht-nudge-head { color: #e4b960; }
[data-theme="dark"] .aandacht-nudge-msg { color: #d0b078; }

/* Extra accent op cards met actieve nudge */
.aandacht-item.has-nudge {
    box-shadow: 0 0 0 2px rgba(199, 126, 28, 0.25);
}

/* Row-highlight na afhandelen-navigatie */
.aandacht-row-highlight {
    background: #fff3e0 !important;
    box-shadow: inset 3px 0 0 #d84315;
    animation: aandacht-row-pulse 1.2s ease-out;
    transition: background 0.4s;
}
@keyframes aandacht-row-pulse {
    0%   { background: #ffe0b2; }
    100% { background: #fff3e0; }
}
[data-theme="dark"] .aandacht-row-highlight {
    background: #3a2817 !important;
    box-shadow: inset 3px 0 0 #ff9955;
}

/* Mobile */
@media (max-width: 700px) {
    .aandacht-item { flex-direction: column; align-items: flex-start; }
    .aandacht-item-right { width: 100%; justify-content: flex-end; }
    .aandacht-item-desc { white-space: normal; }
}

/* ================================================================
   DARK DESIGN V2 (feat/dashboard-dark-design, 22-04-2026)
   ================================================================
   Nieuwe visuele taal gebaseerd op een "Claude Design"-pakket:
   donkere midnight-achtergrond, goud-accenten, frosted-glass cards.
   Self-hosted fonts (Inter + JetBrains Mono) via @font-face.

   Scope:
   - Design tokens worden uitsluitend overschreven binnen
     [data-theme="dark"] zodat light-mode onaangeroerd blijft.
   - Nieuwe componenten (section-header, story-caption, check-badge,
     streak-badge, pace-marker) zijn volledig nieuw en staan onder
     dark-scope.
   - Bestaande .dash-card styling buiten .dash-grid-container blijft
     onaangeroerd (scoping regel uit ronde 2 Codex-fix).
   ================================================================ */

/* ---- Self-hosted fonts (latin + latin-ext, weights 400-800) ---- */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/inter-latin-400-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/static/fonts/inter-latin-500-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/static/fonts/inter-latin-600-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/static/fonts/inter-latin-700-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url('/static/fonts/inter-latin-800-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/* Inter latin-ext (diacritics) */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/inter-latin-ext-400-normal.woff2') format('woff2');
    unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/static/fonts/inter-latin-ext-600-normal.woff2') format('woff2');
    unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/static/fonts/inter-latin-ext-700-normal.woff2') format('woff2');
    unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
/* JetBrains Mono */
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/static/fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/static/fonts/jetbrains-mono-latin-500-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/static/fonts/jetbrains-mono-latin-600-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/static/fonts/jetbrains-mono-latin-700-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* ---- Design tokens (dark only). Light theme blijft ongewijzigd. ---- */
[data-theme="dark"] {
    /* Base palette */
    --midnight-950: #050a12;
    --midnight-900: #0a1421;
    --midnight-850: #0f1b2e;
    --midnight-800: #14253e;
    --midnight-700: #1c3150;
    --midnight-600: #2a4267;
    --midnight-hairline: rgba(196,168,98,.12);

    /* Accent + status */
    --gold-500: #c4a862;
    --gold-400: #d9bd78;
    --gold-dim: rgba(196,168,98,.18);
    --gold-glow: rgba(196,168,98,.35);

    --green-done: #6ec485;
    --green-dim: rgba(110,196,133,.15);
    --green-glow: rgba(110,196,133,.35);

    --blue-calm: #7dafc9;
    --blue-dim: rgba(125,175,201,.15);
    --blue-glow: rgba(125,175,201,.3);

    --amber-warn: #d4a847;
    --amber-dim: rgba(212,168,71,.15);
    --amber-glow: rgba(212,168,71,.3);

    /* 05-08-2026: van #c17b6e naar #dd9488. Rood was de enige statuskleur
       die zijn eigen pastelachtergrond niet haalde: tekst in var(--red) op
       var(--red-soft) gaf 3,81:1, terwijl groen 5,44 en oranje 5,31 haalden.
       De eis is 4,5:1. Zelfde tint, iets lichter, nu 5,22:1 — in lijn met
       de andere twee. */
    --red-bad: #dd9488;
    --red-dim: rgba(193,123,110,.15);
    --red-glow: rgba(193,123,110,.3);

    /* Text */
    --text-primary: #e8ecf3;
    --text-secondary: #a0aec3;
    --text-tertiary: #6b7a95;
    --text-on-gold: #0a1421;

    /* Surfaces */
    --surface-raised: rgba(28,49,80,.55);
    --surface-raised-hover: rgba(28,49,80,.7);
    --surface-hairline: rgba(196,168,98,.15);
    --surface-border-strong: rgba(196,168,98,.3);

    /* Shadows (dark) — overschrijven oude --shadow-* zodat al bestaande
       .dash-card / .dash-card-hero regels automatisch de nieuwe diepte
       meenemen. */
    --shadow-xs: 0 1px 2px rgba(0,0,0,.3);
    --shadow-sm: 0 2px 8px rgba(0,0,0,.3), 0 1px 0 rgba(255,255,255,.03) inset;
    --shadow-md: 0 8px 24px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.04) inset;
    --shadow-lg: 0 16px 48px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.05) inset;
    --shadow-glow-gold: 0 0 24px var(--gold-glow);

    /* Radii + hairlines */
    --radius-sm: 8px;
    --radius-md: 12px;
    --radius-lg: 16px;
    --radius-xl: 20px;
    --hairline: 1px solid var(--surface-hairline);
    --hairline-strong: 1px solid var(--surface-border-strong);

    /* Typography families (variable self-hosted) */
    --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --font-mono: 'JetBrains Mono', 'SF Mono', 'Consolas', monospace;
    --font-display: 'Inter', system-ui, sans-serif;

    /* Backward-compat aliases — oude tokens wijzen nu naar nieuwe palette
       zodat reeds-gescreende screens automatisch meekleuren.
       NB: we overschrijven niet --primary (sidebar-header gebruikt die). */
    --bg: var(--midnight-900);
    --bg-main: var(--midnight-900);
    --sidebar: var(--midnight-950);
    --card: var(--midnight-850);
    --text: var(--text-primary);
    --border: rgba(196,168,98,.14);
    --border-color: rgba(196,168,98,.14);
    --green: var(--green-done);
    --green-soft: var(--green-dim);
    --orange: var(--amber-warn);
    --orange-soft: var(--amber-dim);
    --red: var(--red-bad);
    --red-soft: var(--red-dim);
    --blue: var(--blue-calm);
    --blue-soft: var(--blue-dim);
    --gold: var(--gold-500);
    --card-gradient: linear-gradient(180deg, rgba(20,37,62,.75) 0%, rgba(15,27,46,.85) 100%);
    --table-header-bg: var(--midnight-850);
    --table-hover: var(--midnight-800);
}

/* ---- Body + global typography (dark only) ---- */
[data-theme="dark"] body {
    font-family: var(--font-body);
    font-feature-settings: 'cv11', 'ss01';
    letter-spacing: -0.01em;
    color: var(--text-primary);
    background: var(--midnight-900);
}

/* ---- Reduced motion override ---- */
@media (prefers-reduced-motion: reduce) {
    html:not(.beweging-aan) [data-theme="dark"] .dash-grid-container .dash-card,
    html:not(.beweging-aan) [data-theme="dark"] .dash-card-hero,
    html:not(.beweging-aan) [data-theme="dark"] .dash-kpi-hero-v2,
    html:not(.beweging-aan) [data-theme="dark"] .dash-check-badge,
    html:not(.beweging-aan) [data-theme="dark"] .dash-progress-fill {
        transition: none !important;
        animation: none !important;
    }
}

/* ---- Section-header (01, 02, ...) ---- */
[data-theme="dark"] .dash-section-header {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    margin: 1.4rem 0 .5rem 0;
    padding: 0 .25rem;
}
[data-theme="dark"] .dash-section-header:first-child {
    margin-top: 0;
}
[data-theme="dark"] .dash-section-header .section-number {
    font-family: var(--font-mono);
    font-weight: 500;
    font-size: .7rem;
    color: var(--gold-500);
    text-transform: uppercase;
    letter-spacing: .15em;
    padding-top: .4rem;
    min-width: 1.5rem;
}
[data-theme="dark"] .dash-section-header .section-title {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--text-primary);
    line-height: 1.2;
}
[data-theme="dark"] .dash-section-header .section-sub {
    font-size: .85rem;
    color: var(--text-secondary);
    margin-top: .15rem;
    line-height: 1.4;
}

/* ---- Frosted-glass KPI-card (dark) ----
   Scoped onder .dash-grid-container zodat .dash-card elders (beheer.js,
   tabs, etc.) de oude styling behouden (Codex NO-GO ronde 2). */
[data-theme="dark"] .dash-grid-container .dash-card {
    background: var(--surface-raised);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: var(--hairline);
    border-radius: var(--radius-lg);
    padding: 1.4rem 1.6rem;
    box-shadow: var(--shadow-sm);
    /* Blauw-artifact fix 22-04-2026:
       overflow:hidden + background-clip:padding-box voorkomt dat
       border-gradient / inner backdrop-filter over de border-radius
       heen getekend wordt (de user-geziene "uitgesneden hoek"). */
    overflow: hidden;
    background-clip: padding-box;
    position: relative;
    transition: transform .3s cubic-bezier(.4,0,.2,1),
                box-shadow .3s cubic-bezier(.4,0,.2,1),
                border-color .3s cubic-bezier(.4,0,.2,1);
}
[data-theme="dark"] .dash-grid-container .dash-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: conic-gradient(from 220deg, transparent 0%, var(--gold-glow) 30%, transparent 60%);
    opacity: 0;
    transition: opacity .4s ease;
    pointer-events: none;
    z-index: 0;
}
[data-theme="dark"] .dash-grid-container .dash-card > * {
    position: relative;
    z-index: 1;
}
[data-theme="dark"] .dash-grid-container .dash-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: var(--surface-border-strong);
    background: var(--surface-raised-hover);
}
[data-theme="dark"] .dash-grid-container .dash-card:hover::before {
    opacity: 1;
}
[data-theme="dark"] .dash-grid-container .dash-card.no-hover:hover {
    transform: none;
    box-shadow: var(--shadow-sm);
    border-color: var(--surface-hairline);
    background: var(--surface-raised);
}
[data-theme="dark"] .dash-grid-container .dash-card.no-hover::before {
    display: none;
}
/* Status-variants (linker-accent via ::before-glow): zet op de card
   zelf om de conic-gradient kleur te veranderen. */
[data-theme="dark"] .dash-grid-container .dash-card.status-green::before {
    background: conic-gradient(from 220deg, transparent 0%, var(--green-glow) 30%, transparent 60%);
}
[data-theme="dark"] .dash-grid-container .dash-card.status-amber::before {
    background: conic-gradient(from 220deg, transparent 0%, var(--amber-glow) 30%, transparent 60%);
}
[data-theme="dark"] .dash-grid-container .dash-card.status-red::before {
    background: conic-gradient(from 220deg, transparent 0%, var(--red-glow) 30%, transparent 60%);
}
[data-theme="dark"] .dash-grid-container .dash-card.status-blue::before {
    background: conic-gradient(from 220deg, transparent 0%, var(--blue-glow) 30%, transparent 60%);
}

/* Hover-glow op tabel-rijen met status-class (opvolging-tabel-view e.a.).
   Feedback 22-04-2026: "het hoover effect moet op alles wat bijvoorbeeld
   een rode of groene kleur krijgt". Rijen krijgen een zachte status-glow
   als achtergrond bij hover, inplaats van de standaard table-hover bg. */
[data-theme="dark"] .dash-grid-container tr.status-red:hover td {
    background: var(--red-dim);
    box-shadow: inset 3px 0 0 var(--red-bad);
}
[data-theme="dark"] .dash-grid-container tr.status-amber:hover td {
    background: var(--amber-dim);
    box-shadow: inset 3px 0 0 var(--amber-warn);
}
[data-theme="dark"] .dash-grid-container tr.status-green:hover td {
    background: var(--green-dim);
    box-shadow: inset 3px 0 0 var(--green-done);
}
[data-theme="dark"] .dash-grid-container tr.status-red td,
[data-theme="dark"] .dash-grid-container tr.status-amber td,
[data-theme="dark"] .dash-grid-container tr.status-green td {
    transition: background .25s cubic-bezier(.4,0,.2,1), box-shadow .25s cubic-bezier(.4,0,.2,1);
}

/* ---- Welkom-hero v2 (dark) ---- */
[data-theme="dark"] .dash-card-hero {
    background: var(--surface-raised);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: var(--hairline);
    border-top: 3px solid var(--gold-500);
    border-radius: var(--radius-xl);
    padding: 2rem 2.4rem;
    box-shadow: var(--shadow-md);
    overflow: hidden;
    background-clip: padding-box;
}
[data-theme="dark"] .dash-card-hero .hero-greet {
    font-family: var(--font-display);
    font-size: 2.1rem;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: -0.02em;
    margin-bottom: .4rem;
}
[data-theme="dark"] .dash-card-hero .hero-sub {
    color: var(--text-secondary);
    font-size: .95rem;
}
[data-theme="dark"] .dash-card-hero .hero-sub strong {
    color: var(--gold-400);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* ---- Streak-badge (welkom-hero rechts) ---- */
[data-theme="dark"] .hero-streak-badge {
    flex-shrink: 0;
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .15rem;
    padding: .65rem 1rem;
    border-radius: var(--radius-md);
    background: rgba(110,196,133,.08);
    border: 1px solid var(--green-done);
    box-shadow: 0 0 12px var(--green-glow);
    color: var(--text-primary);
    font-family: var(--font-body);
}
[data-theme="dark"] .hero-streak-badge .streak-line {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .88rem;
    font-weight: 600;
}
[data-theme="dark"] .hero-streak-badge .streak-icon {
    font-size: 1rem;
    line-height: 1;
}
[data-theme="dark"] .hero-streak-badge .streak-count {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    color: var(--green-done);
}
[data-theme="dark"] .hero-streak-badge .streak-since {
    font-family: var(--font-mono);
    font-size: .62rem;
    letter-spacing: .15em;
    color: var(--text-tertiary);
    text-transform: uppercase;
}

/* ---- Num display (grote KPI-cijfers) ---- */
[data-theme="dark"] .num-display {
    font-family: var(--font-mono);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    font-size: clamp(2rem, 4vw, 3.5rem);
    color: var(--text-primary);
    line-height: 1;
}

/* ---- Story-caption (onder KPI-cijfer) ---- */
[data-theme="dark"] .story-caption {
    font-size: .78rem;
    color: var(--text-secondary);
    border-left: 2px solid var(--gold-dim);
    padding-left: .8rem;
    margin-top: .6rem;
    line-height: 1.45;
}
[data-theme="dark"] .story-caption.status-green { border-left-color: var(--green-done); }
[data-theme="dark"] .story-caption.status-amber { border-left-color: var(--amber-warn); }
[data-theme="dark"] .story-caption.status-red   { border-left-color: var(--red-bad); }
[data-theme="dark"] .story-caption.status-gold  { border-left-color: var(--gold-500); }

/* ---- Status-pill (top-right op KPI-card) ---- */
[data-theme="dark"] .dash-status-pill {
    position: absolute;
    top: .9rem;
    right: .9rem;
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .25rem .65rem;
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: .7rem;
    font-weight: 500;
    letter-spacing: .05em;
    z-index: 2;
}
[data-theme="dark"] .dash-status-pill.pill-green {
    background: var(--green-dim);
    border: 1px solid var(--green-done);
    color: var(--green-done);
    box-shadow: 0 0 10px var(--green-glow);
}
[data-theme="dark"] .dash-status-pill.pill-amber {
    background: var(--amber-dim);
    border: 1px solid var(--amber-warn);
    color: var(--amber-warn);
    box-shadow: 0 0 10px var(--amber-glow);
}
[data-theme="dark"] .dash-status-pill.pill-red {
    background: var(--red-dim);
    border: 1px solid var(--red-bad);
    color: var(--red-bad);
    box-shadow: 0 0 10px var(--red-glow);
}
[data-theme="dark"] .dash-status-pill.pill-blue {
    background: var(--blue-dim);
    border: 1px solid var(--blue-calm);
    color: var(--blue-calm);
    box-shadow: 0 0 10px var(--blue-glow);
}
[data-theme="dark"] .dash-status-pill.pill-gold {
    background: var(--gold-dim);
    border: 1px solid var(--gold-500);
    color: var(--gold-500);
    box-shadow: 0 0 10px var(--gold-glow);
}

/* ---- Check-badge (target >= 100%) ---- */
[data-theme="dark"] .dash-check-badge {
    position: absolute;
    top: .75rem;
    right: .75rem;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--green-dim);
    border: 1px solid var(--green-done);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--green-done);
    font-size: .85rem;
    font-weight: 700;
    z-index: 2;
    box-shadow: 0 0 10px var(--green-glow);
    animation: dash-pop-in .4s cubic-bezier(.34,1.56,.64,1);
}
@keyframes dash-pop-in {
    0%   { transform: scale(0); }
    60%  { transform: scale(1.2); }
    100% { transform: scale(1); }
}

/* Progress-bar-overrides voor dark theme + unified .dash-progress zijn verplaatst
 * naar het voortgangsbalken-blok onderaan (zoek op "Voortgangsbalken (light theme base)"). */

/* ---- Voortgangsbalken (light theme base) ---- */
/* Feedback 22-04-2026: voortgangsbalken moeten mooier + geanimeerder. Eén
 * uniforme .dash-progress die zowel light als dark werkt, met:
 *  - Gradient-fill (niet vlak)
 *  - Inner shadow op de rail voor diepte
 *  - Glossy highlight bovenop de fill
 *  - Shimmer-animatie die continu over de fill loopt
 *  - Rustige fill-in animatie bij mount (van 0 naar --progress)
 * CSS-variabele --progress is de doelbreedte (0-100). */
.dash-progress {
    position: relative;
    height: 12px;
    background: linear-gradient(180deg, rgba(0,0,0,.06) 0%, rgba(0,0,0,.03) 100%);
    border-radius: 999px;
    overflow: hidden;
    box-shadow: inset 0 1px 2px rgba(0,0,0,.08), inset 0 -1px 0 rgba(255,255,255,.5);
}
.dash-progress-fill {
    position: relative;
    height: 100%;
    width: var(--progress, 0%);
    border-radius: 999px;
    background: linear-gradient(135deg, #5b9dd6 0%, #85754E 100%);
    box-shadow: 0 0 10px rgba(133,117,78,.25), inset 0 1px 0 rgba(255,255,255,.4);
    overflow: hidden;
    transition: width 1.1s cubic-bezier(.22,1,.36,1);
    animation: dash-progress-grow 1.1s cubic-bezier(.22,1,.36,1) both;
}
.dash-progress-fill::before {
    /* Glossy sheen: subtiele lichtstreep bovenop de fill */
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(180deg, rgba(255,255,255,.35) 0%, rgba(255,255,255,0) 55%);
    pointer-events: none;
}
.dash-progress-fill::after {
    /* Shimmer-streep die continu over de fill beweegt */
    content: '';
    position: absolute;
    top: 0;
    left: -40%;
    width: 40%;
    height: 100%;
    background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.55) 50%, rgba(255,255,255,0) 100%);
    /* GESCHRAPT (22-8-2026): een glansstreep die eeuwig over vier balken
       op het dashboard glijdt draagt geen informatie en trekt de blik weg
       van de cijfers ernaast. */
    animation: none;
    pointer-events: none;
}
.dash-progress-fill.status-green {
    background: linear-gradient(135deg, #6bc68c 0%, #2f9254 100%);
    box-shadow: 0 0 10px rgba(47,146,84,.3), inset 0 1px 0 rgba(255,255,255,.4);
}
.dash-progress-fill.status-amber {
    background: linear-gradient(135deg, #f0c778 0%, #d89b3a 100%);
    box-shadow: 0 0 10px rgba(216,155,58,.3), inset 0 1px 0 rgba(255,255,255,.4);
}
.dash-progress-fill.status-red {
    background: linear-gradient(135deg, #e09087 0%, #b5463a 100%);
    box-shadow: 0 0 10px rgba(181,70,58,.3), inset 0 1px 0 rgba(255,255,255,.4);
}
.dash-progress-fill.status-blue {
    background: linear-gradient(135deg, #7cb9e8 0%, #3a77b8 100%);
    box-shadow: 0 0 10px rgba(58,119,184,.3), inset 0 1px 0 rgba(255,255,255,.4);
}
.dash-progress-fill.status-gold {
    background: linear-gradient(135deg, #e0c470 0%, #85754E 100%);
    box-shadow: 0 0 12px rgba(133,117,78,.35), inset 0 1px 0 rgba(255,255,255,.4);
}
.dash-progress-pace {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: rgba(0,0,0,.25);
    pointer-events: none;
    z-index: 2;
}
@keyframes dash-progress-grow {
    from { width: 0%; }
    to   { width: var(--progress, 0%); }
}
@keyframes dash-progress-shimmer {
    0%   { left: -40%; }
    60%  { left: 120%; }
    100% { left: 120%; }
}
@media (prefers-reduced-motion: reduce) {
    html:not(.beweging-aan) .dash-progress-fill { animation: none !important; transition: none; }
    html:not(.beweging-aan) .dash-progress-fill::after { animation: none !important; display: none; }
}

/* Dark-theme overrides: bestaande .dash-progress block hierboven (regel ~2778)
 * is nu vervangen door deze unified versie — onderstaande zet de rail-kleur
 * en laat fills intakt. */
[data-theme="dark"] .dash-progress {
    background: linear-gradient(180deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,.25) 100%);
    box-shadow: inset 0 1px 2px rgba(0,0,0,.4), inset 0 -1px 0 rgba(255,255,255,.04);
}
[data-theme="dark"] .dash-progress-pace {
    background: var(--gold-500);
    box-shadow: 0 0 6px var(--gold-glow);
}

/* ---- Scope-badge (Persoonlijk / Groep) op target-widgets ---- */
/* Feedback 22-04-2026: COI (en alle target-widgets) moeten in de titel
 * duidelijk tonen of het een PERSOONLIJK aandeel is of het GROEP-totaal. */
.target-scope-badge {
    display: inline-block;
    font-size: .62rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: .15rem .5rem;
    border-radius: 999px;
    margin-left: .5rem;
    vertical-align: middle;
    line-height: 1.2;
}
.target-scope-badge.scope-persoonlijk {
    background: rgba(58,119,184,.12);
    color: #2c5d8f;
    border: 1px solid rgba(58,119,184,.25);
}
.target-scope-badge.scope-groep {
    background: rgba(133,117,78,.12);
    color: #6c5e3a;
    border: 1px solid rgba(133,117,78,.3);
}
[data-theme="dark"] .target-scope-badge.scope-persoonlijk {
    background: rgba(124,185,232,.16);
    color: #a7cde8;
    border-color: rgba(124,185,232,.32);
}
[data-theme="dark"] .target-scope-badge.scope-groep {
    background: rgba(196,168,98,.18);
    color: var(--gold-400);
    border-color: rgba(196,168,98,.4);
}

/* ---- Sidebar + content-achtergrond ---- */
[data-theme="dark"] .sidebar {
    background: var(--midnight-950);
    border-right: 1px solid var(--surface-hairline);
}
[data-theme="dark"] .sidebar nav a:hover,
[data-theme="dark"] .sidebar nav a.active {
    background: rgba(196,168,98,.12);
    border-left-color: var(--gold-500);
    color: var(--text-primary);
}
[data-theme="dark"] .content-area,
[data-theme="dark"] main.content {
    background: var(--midnight-900);
    color: var(--text-primary);
}

/* ---- Forms/tables stay readable on dark ---- */
[data-theme="dark"] input,
[data-theme="dark"] select,
[data-theme="dark"] textarea {
    background: var(--midnight-800);
    color: var(--text-primary);
    border-color: var(--surface-hairline);
}

/* Mobile tweaks: hero padding blijft compact */
@media (max-width: 700px) {
    [data-theme="dark"] .dash-card-hero { padding: 1.4rem 1.3rem; flex-direction: column; align-items: flex-start; }
    [data-theme="dark"] .dash-card-hero .hero-greet { font-size: 1.5rem; }
    [data-theme="dark"] .hero-streak-badge { align-self: flex-start; }
    /* Bug-fix 28-04-2026: bij flex-direction:column werd `flex: 1 1 320px`
       op .hero-left geïnterpreteerd als HEIGHT-basis (320px hoog), waardoor
       de welkom-card op gsm ~500px hoog werd met grote lege ruimte. Forceer
       auto-height op mobile zodat alleen de eigenlijke content-hoogte telt. */
    [data-theme="dark"] .dash-card-hero .hero-left {
        flex: 0 0 auto !important;
        flex-basis: auto !important;
        width: 100%;
    }
    .dash-card-hero .hero-left {
        flex: 0 0 auto !important;
        flex-basis: auto !important;
        width: 100%;
    }
}

/* ======================================================================
 * Mobile responsive fixes — feedback gsm 28-04-2026
 * 1. Globale input-styling voor dark theme (vele inputs misten var()-kleuren
 *    waardoor donkere tekst op donkere achtergrond stond op CRM/forms)
 * 2. Klant360-search dropdown mobile: full-width modaal-stijl onder topbar
 * 3. Viewport: gebruik 100dvh ipv 100vh om Chrome iOS browser-bar quirk
 *    te omzeilen waarbij topbar buiten beeld kwam tijdens scroll-into-view
 * ====================================================================== */

/* (1) Globale input-styling — dark theme moet alle text-inputs lichte tekst
   geven op donkere bg, ook buiten .form-group. */
[data-theme="dark"] input[type="text"],
[data-theme="dark"] input[type="email"],
[data-theme="dark"] input[type="tel"],
[data-theme="dark"] input[type="number"],
[data-theme="dark"] input[type="search"],
[data-theme="dark"] input[type="date"],
[data-theme="dark"] input[type="datetime-local"],
[data-theme="dark"] input[type="time"],
[data-theme="dark"] input[type="password"],
[data-theme="dark"] input[type="url"],
[data-theme="dark"] input:not([type]),
[data-theme="dark"] select,
[data-theme="dark"] textarea {
    background: var(--input-bg, #1e2d3a);
    color: var(--input-text, #e8e6e3);
    border: 1px solid var(--border, rgba(196,168,98,.18));
    border-radius: 6px;
}
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder {
    color: var(--muted, #9ca3af);
    opacity: 0.85;
}
[data-theme="dark"] input:focus,
[data-theme="dark"] select:focus,
[data-theme="dark"] textarea:focus {
    outline: none;
    border-color: var(--gold-500, #c4a862);
    box-shadow: 0 0 0 2px rgba(196,168,98,.18);
}

/* (2) Klant360-search dropdown — op mobile full-width modaal onderaan,
   anders schiet de 320px-dropdown buiten viewport links. */
@media (max-width: 768px) {
    #klant360-search-input {
        width: 70vw !important;
        max-width: 220px !important;
    }
    #klant360-search-results {
        position: fixed !important;
        left: .5rem !important;
        right: .5rem !important;
        top: 3.5rem !important;
        width: auto !important;
        max-width: 100vw !important;
    }
}

/* (3) Viewport-quirk fix Chrome iOS: gebruik dynamic viewport units waar
   beschikbaar. Op DESKTOP behouden we de oude flex-layout (sidebar +
   main + interne content-scroll). Op mobile (4b hieronder) overrulen
   we dit zodat body native scrollt. */
@supports (height: 100dvh) {
    @media (min-width: 769px) {
        #app {
            min-height: 100dvh;
        }
        .main {
            min-height: 100dvh;
        }
    }
}

/* (4) ss-tabs responsive — op mobile horizontaal scrollbaar maken zodat
   bv. KIA New / NVD / KIA Used niet over elkaar vallen of buiten viewport. */
@media (max-width: 768px) {
    .ss-tabs {
        display: flex !important;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        max-width: 100%;
        scrollbar-width: thin;
        white-space: nowrap;
    }
    .ss-tab {
        flex-shrink: 0;
        padding: .45rem .8rem !important;
        font-size: .82rem !important;
    }
    /* Verberg scrollbar visueel maar laat scroll werken */
    .ss-tabs::-webkit-scrollbar {
        height: 3px;
    }
    .ss-tabs::-webkit-scrollbar-track {
        background: transparent;
    }
    .ss-tabs::-webkit-scrollbar-thumb {
        background: var(--accent, #c4a862);
        border-radius: 2px;
    }
}

/* (4b) HORIZONTAL OVERFLOW PREVENTION — root oorzaak van pinch-zoom-noodzaak.
   Geen enkel element mag breder zijn dan viewport.
   Voor tables + grote grids → overflow-x:auto wrapper. */
html, body {
    overflow-x: hidden;
    max-width: 100vw;
}
#app, .main, .content {
    max-width: 100vw;
    box-sizing: border-box;
}
@media (max-width: 768px) {
    /* MARGIN ipv padding: body krijgt 1rem margin links/rechts. Margin is
       buiten de box dus kan niet door child-styling worden overschreven.
       Body width wordt expliciet calc(100vw - 2rem) zodat content
       gegarandeerd binnen die marges blijft. Outline (transparant) als
       extra anti-overflow lijn. */
    html {
        overflow-x: hidden !important;
        background: var(--bg, #0a1421);
    }
    body {
        margin-left: 1rem !important;
        margin-right: 1rem !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
        width: calc(100vw - 2rem) !important;
        max-width: calc(100vw - 2rem) !important;
        box-sizing: border-box !important;
        overflow-x: hidden !important;
    }
    .content {
        padding-left: 0 !important;
        padding-right: 0 !important;
        max-width: 100%;
        box-sizing: border-box;
        overflow-x: hidden;
    }
    .dash-grid-container {
        max-width: 100%;
        padding-right: 0;
        margin-right: 0;
    }
    .dash-section-group, .dash-card-hero, [data-section-id] {
        max-width: 100% !important;
        margin-right: 0 !important;
        box-sizing: border-box !important;
    }
    /* .dashboard-section staat op overflow:hidden (regel ~949) zodat charts
     * en 3D-platforms netjes binnen hun rand blijven. Op een telefoon
     * betekende dat: alles wat breder was dan de sectie werd gewoon
     * WEGGEKNIPT — de laatste kolommen van een 12-koloms raster waren
     * onzichtbaar én onbereikbaar. Op mobile daarom horizontaal
     * scrollbaar maken i.p.v. afkappen; verticaal blijft hidden zodat het
     * platform-effect intact blijft. De pagina zelf scrollt niet mee:
     * html/body staan hierboven al op overflow-x:hidden. */
    .dashboard-section {
        overflow-x: auto !important;
        overflow-y: hidden !important;
        -webkit-overflow-scrolling: touch;
        max-width: 100%;
    }
    .dashboard-section > .section-content {
        min-width: 0;
    }
    /* Chatvenster stond 5 tot 20 px buiten beeld: #chat-widget hangt op
     * right:20px en #chat-panel is daarbinnen 360px breed, samen 380px.
     * Op een toestel van 360-375px viel de linkerrand dus buiten het
     * scherm. Breedte begrenzen op wat er werkelijk is (20px offset aan
     * de rechterkant + 12px ademruimte links). Ook de hoogte begrenzen,
     * anders steekt het paneel op een laag scherm boven de viewport uit. */
    #chat-panel {
        width: min(360px, calc(100vw - 32px)) !important;
        max-width: calc(100vw - 32px) !important;
        height: min(520px, calc(100vh - 120px)) !important;
    }
    /* Op mobile: body scrollt vertikaal, niet .content (interne scroll
       verbergt native iOS scroll-indicator + breekt scroll-rubberband).
       Sidebar is op mobile een fixed-overlay dus #app/.main hoeven niet
       100dvh fixed te zijn — laat ze auto-groeien met content. */
    html, body {
        height: auto;
        overflow-y: auto;
    }
    #app {
        flex-direction: column;
        min-height: 100dvh;
        height: auto;
    }
    .main {
        overflow: visible !important;
        height: auto !important;
        min-height: auto !important;
        flex: none !important;
        max-width: 100vw;
    }
    .content {
        overflow: visible !important;
        flex: none !important;
        height: auto !important;
    }
    /* Alle tables krijgen scrollable wrapper-gedrag */
    .ss-table, .stock-table, .leveringen-table, table:not(.no-mobile-scroll) {
        max-width: 100%;
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        white-space: nowrap;
    }
    /* Chat-toast: 380px min-width was groter dan viewport → krimpen */
    .chat-toast {
        min-width: auto !important;
        max-width: calc(100vw - 2rem) !important;
        width: calc(100vw - 2rem) !important;
        margin: 0 1rem !important;
    }
    /* Modals: nooit breder dan viewport, content krijgt eigen scroll */
    #generic-modal-overlay > div,
    #modal-overlay .modal {
        max-width: calc(100vw - 1rem) !important;
        margin: .5rem !important;
    }
    /* Form-grids op mobile altijd 1-kolom (anders 2-kolom met te smalle inputs) */
    .form-grid {
        grid-template-columns: 1fr !important;
    }
    /* dropdowns/popups die absoluut gepositioneerd zijn: bound binnen viewport */
    .kbo-dropdown, #kbo-bedrijf-dropdown {
        max-width: calc(100vw - 1rem) !important;
    }
    /* Inputs die geen width hebben: full-width op mobile */
    input, select, textarea {
        max-width: 100%;
    }
    /* Verberg horizontal-scrollbars die er toch nog zouden zijn */
    body {
        scroll-behavior: smooth;
    }
    /* Brede inline-rasters op mobile: meeschalen of scrollen, nooit afkappen.
     *
     * WAT HIER VROEGER MISLIEP (opgelost 2026-08-05)
     * ----------------------------------------------
     * Deze vangregel somde de mogelijke schrijfwijzen letterlijk op:
     *     "grid-template-columns:repeat(3,1fr)"    (nergens spaties)
     *     "grid-template-columns: repeat(3, 1fr)"  (overal spaties)
     * De JS schrijft echter de MENGVORM, zonder spatie na de dubbelepunt
     * maar mét spatie na de komma:
     *     dashboard.js:3720  grid-template-columns:repeat(6, 1fr)
     *     dashboard.js:3844  grid-template-columns:repeat(12, 1fr)
     *     dashboard.js:4040  grid-template-columns:repeat(5, 1fr)
     * Die ene spatie zorgde ervoor dat geen enkele opsomming matchte.
     * Bovendien stonden alleen 3 en 4 kolommen in de lijst, terwijl de
     * JS er 5, 6, 7 en 12 genereert (beheer.js:1712 maakt er 7).
     * De rasters bleven dus op volle breedte staan en werden afgekapt
     * door .dashboard-section { overflow: hidden } (regel ~949).
     *
     * DE OPLOSSING — twee delen
     * -------------------------
     * 1) De match stopt nu NA DE KOMMA: "...repeat(6,". Alles wat daarna
     *    varieert (spatie of niet, "1fr" of iets anders) doet er niet meer
     *    toe. Eén selector dekt dus zowel repeat(6,1fr) als repeat(6, 1fr).
     *    Dat was precies wat er misging.
     * 2) De aantallen 5 t/m 12 zijn toegevoegd — die ontbraken volledig.
     *
     * Waarom niet één generieke repeat(auto-fit, ...)-regel? Omdat auto-fit
     * ook MEER kolommen kan maken dan er stonden: een 2-koloms formulier
     * zou op een breed scherm ineens 3 of 4 kolommen krijgen. En bij de
     * PDI-kalender (beheer.js:1712, 7 kolommen = 7 weekdagen) betekent het
     * aantal kolommen ECHT iets — die mag je niet hervormen. Daarom:
     *   - 3 en 4 kolommen  = losse tegels  -> hervallen naar 2 (of 1)
     *   - 5 t/m 12 kolommen = betekenisvol -> kolommen behouden, maar het
     *     raster krijgt zijn eigen horizontale scroll, zodat het binnen
     *     zijn eigen kader schuift i.p.v. afgekapt te worden.
     * De pagina zelf scrollt nooit mee: html/body staan op overflow-x
     * hidden met max-width 100vw (zie blok "(4b)" hierboven). */
    [style*="grid-template-columns:repeat(3,"],
    [style*="grid-template-columns: repeat(3,"],
    [style*="grid-template-columns:repeat(4,"],
    [style*="grid-template-columns: repeat(4,"],
    [style*="grid-template-columns:1fr 1fr 1fr"],
    [style*="grid-template-columns: 1fr 1fr 1fr"] {
        grid-template-columns: 1fr 1fr !important;
    }
    /* Betekenisvolle kolommen (maanden, weekdagen, modellen, postcodes):
     * niet hervormen, wel scrollbaar maken binnen het eigen kader. */
    [style*="grid-template-columns:repeat(5,"],
    [style*="grid-template-columns: repeat(5,"],
    [style*="grid-template-columns:repeat(6,"],
    [style*="grid-template-columns: repeat(6,"],
    [style*="grid-template-columns:repeat(7,"],
    [style*="grid-template-columns: repeat(7,"],
    [style*="grid-template-columns:repeat(8,"],
    [style*="grid-template-columns: repeat(8,"],
    [style*="grid-template-columns:repeat(9,"],
    [style*="grid-template-columns: repeat(9,"],
    [style*="grid-template-columns:repeat(10,"],
    [style*="grid-template-columns: repeat(10,"],
    [style*="grid-template-columns:repeat(11,"],
    [style*="grid-template-columns: repeat(11,"],
    [style*="grid-template-columns:repeat(12,"],
    [style*="grid-template-columns: repeat(12,"] {
        max-width: 100%;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 2px;
    }
}
@media (max-width: 480px) {
    [style*="grid-template-columns:repeat(3,"],
    [style*="grid-template-columns: repeat(3,"],
    [style*="grid-template-columns:repeat(4,"],
    [style*="grid-template-columns: repeat(4,"],
    [style*="grid-template-columns:1fr 1fr 1fr"],
    [style*="grid-template-columns: 1fr 1fr 1fr"] {
        grid-template-columns: 1fr !important;
    }
    /* Compact KPI-cards op zeer kleine schermen — kleinere padding/font */
    .adm-kpi, .admin-dash .adm-kpi, .admin-dash > div > div {
        padding: .5rem !important;
    }
    .admin-dash .adm-kpi-val,
    .admin-dash > div [style*="font-size:1.5rem"],
    .admin-dash > div [style*="font-size: 2"] {
        font-size: 1.4rem !important;
    }
}

/* (5) Generieke fallback: inline-style background:#fff/#f0f4ff/#f3f4f6 in
   dark theme overschrijven. Zo zijn nieuwe forms/popups die nog niet
   geconverteerd zijn naar var() ook leesbaar. Doet GEEN override op
   warning/info-boxes (#fff8e1, #fff3cd) zodat die hun gele tint behouden. */
[data-theme="dark"] [style*="background:#fff;"]:not(.no-dark-override),
[data-theme="dark"] [style*="background: #fff;"]:not(.no-dark-override),
[data-theme="dark"] [style*="background:#ffffff"]:not(.no-dark-override),
[data-theme="dark"] [style*="background:#f0f4ff"]:not(.no-dark-override),
[data-theme="dark"] [style*="background:#f3f4f6"]:not(.no-dark-override),
[data-theme="dark"] [style*="background:#f8f9fa"]:not(.no-dark-override),
[data-theme="dark"] [style*="background:white"]:not(.no-dark-override) {
    background: var(--card, #1a2332) !important;
    color: var(--text, #e2e8f0) !important;
}
/* ======================================================================
 * MELDINGSNIVEAUS — informatie / waarschuwing / ernstig / ok
 * ======================================================================
 *
 * WAT HIER VROEGER MISLIEP (opgelost 2026-08-05)
 * ----------------------------------------------
 * Een geel waarschuwingsblok uit de JS ziet er zo uit:
 *     <div style="background:#fff3cd;border:1px solid #ffc107;...">
 * Daar vochten drie regels om:
 *   1) [data-theme="dark"] [style*="background:#fff3cd"]  -> bg #332b14
 *   2) [data-theme="dark"] [style*="background:#fff"]     -> bg var(--card)
 *      ("#fff" is een DEELREEKS van "#fff3cd", dus deze matchte mee)
 *   3) [data-theme="dark"] [style*="background:#fff3cd"]  -> color #1a1a1a
 * Alle drie hadden exact dezelfde specificiteit (0,2,0) en alle drie
 * gebruikten !important, dus won simpelweg de LAATSTE per eigenschap:
 * de achtergrond werd de donkere kaartkleur (regel 2 stond na regel 1)
 * en de tekst werd bijna-zwart (regel 3 stond na alles). Resultaat:
 * #1a1a1a op #0f1b2e = 1,01 : 1 — onzichtbaar. Regel 3 was zelf al een
 * pleister op regel 2: hij ging ervan uit dat de gele tint bleef staan.
 *
 * DE OPLOSSING
 * ------------
 * a) Regel 2 is exact gemaakt (zie "WIT (en alleen wit)" hierboven), zodat
 *    hij geen meldingstinten meer kaapt.
 * b) Regel 1 en 3 zijn hier samengevoegd tot ÉÉN regel per ernstniveau
 *    die achtergrond én tekst én rand samen zet. Ze kunnen elkaar dus
 *    niet meer half overschrijven.
 * c) De kleuren komen uit --melding-*-variabelen (zie :root en
 *    [data-theme="dark"] bovenaan). Eén plek aanpassen = overal aangepast.
 * d) Elke regel zet ook --melding-fg. Kind-elementen met een oude
 *    hard-gecodeerde kleur (color:#856404, color:#e65100, ...) pikken die
 *    op en blijven dus leesbaar binnen het blok.
 *
 * !important is hier onvermijdelijk: de kleuren staan als inline style op
 * het element zelf, en een inline style wint van elke stylesheet-regel
 * zonder !important. Het is dus geen pleister over een ander probleem —
 * de botsing zelf is hierboven bij de oorzaak opgelost.
 *
 * KLEUR VOLGT ERNST
 * -----------------
 *   informatie   = blauw   — "even weten"
 *   waarschuwing = amber   — "kijk hier naar"
 *   ernstig      = rood    — "dit blokkeert / dit gaat mis"
 *   ok           = groen   — bevestiging
 * Alles in de pastel huisstijl; geen harde signaalkleuren.
 *
 * Dit geldt voor MELDINGSBLOKKEN, niet voor tabelrijen. Gekleurde
 * rij-achtergronden in lijsten blijven verboden (afspraak eigenaar).
 * ====================================================================== */

/* --- informatie (blauw) ---
 * licht: #1f4d68 op #edf4fa = 8,16 : 1
 * donker: #a9d0ea op #14283a = 9,25 : 1 */
[style*="background:#e3f2fd"],
[style*="background: #e3f2fd"],
[style*="background:#e1f5fe"],
[style*="background: #e1f5fe"] {
    --melding-fg: var(--melding-info-fg);
    --melding-fg-zacht: var(--melding-info-fg-zacht);
    --muted: var(--melding-info-fg-zacht);
    --text-muted: var(--melding-info-fg-zacht);
    --text-secondary: var(--melding-info-fg-zacht);
    background: var(--melding-info-bg) !important;
    color: var(--melding-info-fg) !important;
    border-color: var(--melding-info-rand) !important;
}

/* --- waarschuwing (amber) ---
 * licht: #6b4c10 op #fdf5e6 = 7,27 : 1
 * donker: #ecd08a op #322913 = 9,54 : 1 */
[style*="background:#fff3cd"],
[style*="background: #fff3cd"],
[style*="background:#fff8e1"],
[style*="background: #fff8e1"],
[style*="background:#fef9e7"],
[style*="background: #fef9e7"],
[style*="background:#fff3e0"],
[style*="background: #fff3e0"],
[style*="background:#fff4d6"],
[style*="background: #fff4d6"],
[style*="background:#fff8ec"],
[style*="background: #fff8ec"] {
    --melding-fg: var(--melding-waarschuwing-fg);
    --melding-fg-zacht: var(--melding-waarschuwing-fg-zacht);
    --muted: var(--melding-waarschuwing-fg-zacht);
    --text-muted: var(--melding-waarschuwing-fg-zacht);
    --text-secondary: var(--melding-waarschuwing-fg-zacht);
    background: var(--melding-waarschuwing-bg) !important;
    color: var(--melding-waarschuwing-fg) !important;
    border-color: var(--melding-waarschuwing-rand) !important;
}

/* --- ernstig (rood) ---
 * licht: #7d3325 op #faf0ee = 7,91 : 1
 * donker: #f2b3a6 op #38211c = 8,40 : 1 */
[style*="background:#ffebee"],
[style*="background: #ffebee"],
[style*="background:#fdecea"],
[style*="background: #fdecea"],
[style*="background:#fbe9e7"],
[style*="background: #fbe9e7"] {
    --melding-fg: var(--melding-ernstig-fg);
    --melding-fg-zacht: var(--melding-ernstig-fg-zacht);
    --muted: var(--melding-ernstig-fg-zacht);
    --text-muted: var(--melding-ernstig-fg-zacht);
    --text-secondary: var(--melding-ernstig-fg-zacht);
    background: var(--melding-ernstig-bg) !important;
    color: var(--melding-ernstig-fg) !important;
    border-color: var(--melding-ernstig-rand) !important;
}

/* --- ok / bevestiging (groen) ---
 * licht: #23603d op #e8f5ec = 6,65 : 1
 * donker: #96d9ab op #17301f = 8,66 : 1 */
[style*="background:#e8f5e9"],
[style*="background: #e8f5e9"],
[style*="background:#e6f4ea"],
[style*="background: #e6f4ea"] {
    --melding-fg: var(--melding-ok-fg);
    --melding-fg-zacht: var(--melding-ok-fg-zacht);
    --muted: var(--melding-ok-fg-zacht);
    --text-muted: var(--melding-ok-fg-zacht);
    --text-secondary: var(--melding-ok-fg-zacht);
    background: var(--melding-ok-bg) !important;
    color: var(--melding-ok-fg) !important;
    border-color: var(--melding-ok-rand) !important;
}

/* De gekleurde linkerrand die sommige blokken los meegeven
 * (border-left:4px solid #c62828 e.d.) mag blijven, maar volgt de ernst
 * zodat rand en vulling niet uit elkaar lopen. */
[style*="background:#ffebee"][style*="border-left"],
[style*="background:#fdecea"][style*="border-left"] {
    border-left-color: var(--melding-ernstig-rand) !important;
}
[style*="background:#fff3cd"][style*="border-left"],
[style*="background:#fff8e1"][style*="border-left"],
[style*="background:#fff3e0"][style*="border-left"],
[style*="background:#fff8ec"][style*="border-left"],
[style*="background:#fff4d6"][style*="border-left"] {
    border-left-color: var(--melding-waarschuwing-rand) !important;
}

/* ======================================================================
 * Jaar Overzicht (.jo-table / .jo-section) — gehoist uit sales.js
 * werkt in alle drie views (team overzicht, per verkoper, individueel).
 * Light + dark aware via CSS-vars per table.
 * ====================================================================== */
.jo-table {
    --jo-thead-bg: #05141E;
    --jo-thead-fg: #ffffff;
    --jo-row-alt: rgba(15,52,96,.03);
    --jo-ytd-bg: rgba(15,52,96,.05);
    --jo-current-bg: rgba(15,52,96,.08);
    --jo-current-bg-thead: rgba(255,255,255,.15);
    --jo-accent-line: #05141E;
    width: 100%;
    border-collapse: collapse;
    font-size: .85rem;
    background: var(--card);
    border-radius: 10px;
    /* GEEN overflow:hidden HIER (11-8-2026, bevinding A1)
       ---------------------------------------------------
       Dat stond er voor de afgeronde hoeken, maar het maakte van de TABEL de
       dichtstbijzijnde scroll-omgeving - en die scrollt nooit. De sticky eerste
       kolom (.jo-label-col hieronder) plakte daardoor aan een kader dat stilstond
       en schoof mee naar buiten beeld. Klassieke sticky-killer.

       Gemeten op 820x1180 (iPad staand): "KIA New" stond voor het scrollen op
       x=263..370 en erna op x=81..188 - 75px links van het kader, weggeknipt.
       A/B in een geisoleerde repro: met overflow:hidden x=-325, zonder x=43,
       terug met -325. Een property aan en uit.

       De afgeronde hoeken zitten nu op .jo-table-wrap, die toch al de echte
       scroller is. Op <=768px werkte het wel, want daar maakt de mobiele regel
       van de tabel zelf een scroller. */
    box-shadow: 0 1px 6px rgba(0,0,0,.08);
}

/* De wrapper rond .jo-table: dit is de scroller, en dus ook de plek voor de
   afgeronde hoeken. Zie de uitleg hierboven. */
.jo-table-wrap {
    overflow-x: auto;
    border-radius: 10px;
}
[data-theme="dark"] .jo-table {
    --jo-thead-bg: #0a1421;
    --jo-thead-fg: #e8e6e3;
    --jo-row-alt: rgba(255,255,255,.03);
    --jo-ytd-bg: rgba(196,168,98,.08);
    --jo-current-bg: rgba(196,168,98,.1);
    --jo-current-bg-thead: rgba(196,168,98,.18);
    --jo-accent-line: var(--accent, #c4a862);
    box-shadow: 0 1px 6px rgba(0,0,0,.35);
}
.jo-table th, .jo-table td {
    padding: .5rem .6rem;
    text-align: center;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}
.jo-table th {
    background: var(--jo-thead-bg);
    color: var(--jo-thead-fg);
    font-weight: 600;
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .5px;
}
.jo-label-col {
    text-align: left !important;
    min-width: 80px;
    font-weight: 600;
    color: var(--text);
    position: sticky;
    left: 0;
    background: var(--card);
    z-index: 1;
}
.jo-table thead .jo-label-col {
    background: var(--jo-thead-bg);
    color: var(--jo-thead-fg);
}
.jo-current { background: var(--jo-current-bg) !important; }
.jo-table thead .jo-current {
    background: var(--jo-current-bg-thead) !important;
    color: var(--jo-thead-fg);
}
.jo-ytd {
    background: var(--jo-ytd-bg) !important;
    font-weight: 700;
    border-left: 2px solid var(--jo-accent-line);
}
.jo-table thead .jo-ytd {
    background: rgba(255,255,255,.08) !important;
    border-left: 2px solid rgba(255,255,255,.3);
}
[data-theme="dark"] .jo-table thead .jo-ytd {
    background: rgba(196,168,98,.15) !important;
    border-left: 2px solid rgba(196,168,98,.4);
}
.jo-bold { font-weight: 700; }
.jo-green { color: #16a34a; font-weight: 600; }
.jo-orange { color: #ea580c; font-weight: 600; }
.jo-red { color: #dc2626; font-weight: 600; }
[data-theme="dark"] .jo-green { color: #6ec485; }
[data-theme="dark"] .jo-orange { color: #f2b061; }
[data-theme="dark"] .jo-red { color: #e08a82; }
.jo-row-main td { font-weight: 500; }
.jo-row-sub td { font-size: .8rem; color: var(--muted-leesbaar); }
.jo-row-totaal td {
    font-weight: 700;
    border-top: 2px solid var(--jo-accent-line);
    background: var(--jo-row-alt);
}
.jo-row-totaal .jo-label-col { background: var(--jo-row-alt); }
.jo-separator td { height: 4px; padding: 0; background: var(--border); }
.jo-row-kpi td { font-style: italic; color: var(--muted-leesbaar); }
.jo-section {
    background: var(--card);
    border-radius: 10px;
    padding: 1.2rem;
    margin-bottom: 1.5rem;
    box-shadow: 0 1px 4px rgba(0,0,0,.06);
}
.jo-section h3 {
    margin: 0 0 1rem 0;
    color: var(--text);
    font-size: 1rem;
}
[data-theme="dark"] .jo-section {
    box-shadow: 0 1px 6px rgba(0,0,0,.3);
}
[data-theme="dark"] .jo-section h3 {
    color: var(--accent, #c4a862);
}

/* ======================================================================
 * KPI-tegel met 3D glossy look + duidelijk gekleurde hover
 * feat 22-04-2026: gebruikt door sales_type, lead_type, financieel,
 * overname_detail. Vervangt de hardcoded inline linear-gradient(#fff)
 * die niet werkte in dark mode (tiles bleven wit). Gebruikt CSS-vars en
 * theme-aware hover-states zodat de tegel in beide themes goed oogt.
 * ====================================================================== */
.dash-kpi-tile {
    position: relative;
    text-align: center;
    padding: 1.2rem 1.8rem;
    min-width: 105px;
    border-radius: 10px;
    background: linear-gradient(145deg, var(--card) 0%, color-mix(in srgb, var(--card) 92%, var(--accent, #85754E) 8%) 100%);
    border: 1px solid var(--border);
    box-shadow:
        0 2px 8px rgba(0,0,0,.06),
        inset 0 1px 0 rgba(255,255,255,.55);
    transition: transform .2s cubic-bezier(.22,1,.36,1), box-shadow .25s, background .25s, border-color .25s;
    cursor: pointer;
    overflow: hidden;
}
/* Shine-sheen effect op hover, zoals bij de pp-tile. */
.dash-kpi-tile::after {
    content: '';
    position: absolute;
    top: 0;
    left: -75%;
    width: 60%;
    height: 100%;
    background: linear-gradient(120deg, transparent 0%, rgba(255,255,255,.3) 50%, transparent 100%);
    transform: skewX(-20deg);
    transition: left .55s cubic-bezier(.22,1,.36,1);
    pointer-events: none;
    z-index: 1;
}
.dash-kpi-tile:hover {
    transform: translateY(-2px);
    background: linear-gradient(145deg, #85754E 0%, #6c5e3a 100%);
    border-color: var(--accent, #a08c5a);
    box-shadow:
        0 10px 22px rgba(108,94,58,.3),
        0 0 0 3px rgba(168,147,102,.2),
        inset 0 1px 0 rgba(255,255,255,.25);
}
.dash-kpi-tile:hover::after {
    left: 120%;
}
.dash-kpi-tile > * { position: relative; z-index: 2; }
.dash-kpi-tile .kpi-num {
    font-size: 2rem;
    font-weight: 800;
    color: var(--text);
    line-height: 1;
    transition: color .2s;
}
.dash-kpi-tile .kpi-lbl {
    font-size: .75rem;
    color: var(--muted-leesbaar);
    text-transform: uppercase;
    margin-top: .3rem;
    transition: color .2s;
}
.dash-kpi-tile .kpi-pct {
    font-size: .7rem;
    color: var(--accent, #85754E);
    font-weight: 700;
    margin-top: .2rem;
    transition: color .2s;
}
.dash-kpi-tile .kpi-icon {
    font-size: 1.2rem;
    margin-bottom: .3rem;
    line-height: 1;
}
.dash-kpi-tile:hover .kpi-num,
.dash-kpi-tile:hover .kpi-lbl,
.dash-kpi-tile:hover .kpi-pct,
.dash-kpi-tile:hover .kpi-icon {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.2);
}
[data-theme="dark"] .dash-kpi-tile {
    background: linear-gradient(145deg, rgba(26,45,66,.6) 0%, rgba(16,28,43,.85) 100%);
    border-color: rgba(196,168,98,.18);
    box-shadow:
        0 4px 12px rgba(0,0,0,.45),
        inset 0 1px 0 rgba(196,168,98,.1);
}
[data-theme="dark"] .dash-kpi-tile:hover {
    background: linear-gradient(145deg, #a08c5a 0%, #6c5e3a 100%);
    border-color: var(--accent, #c4a862);
    box-shadow:
        0 12px 28px rgba(0,0,0,.55),
        0 0 0 3px rgba(196,168,98,.25),
        inset 0 1px 0 rgba(255,255,255,.15);
}

/* Horizontaal info-rijtje (financieel widget). */
.dash-kpi-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .6rem .8rem;
    border-radius: 8px;
    background: linear-gradient(145deg, var(--card) 0%, color-mix(in srgb, var(--card) 94%, var(--accent, #85754E) 6%) 100%);
    border: 1px solid var(--border);
    box-shadow: 0 1px 4px rgba(0,0,0,.04);
    transition: transform .15s ease, background .2s, border-color .2s, box-shadow .2s;
    cursor: default;
    overflow: hidden;
}
.dash-kpi-row:hover {
    transform: translateX(3px);
    background: linear-gradient(145deg, color-mix(in srgb, var(--card) 85%, var(--accent, #85754E) 15%) 0%, var(--card) 100%);
    border-color: var(--accent, #a08c5a);
    box-shadow: 0 3px 10px rgba(108,94,58,.18);
}
[data-theme="dark"] .dash-kpi-row {
    background: linear-gradient(145deg, rgba(26,45,66,.55) 0%, rgba(16,28,43,.8) 100%);
    border-color: rgba(196,168,98,.15);
}
[data-theme="dark"] .dash-kpi-row:hover {
    background: linear-gradient(145deg, rgba(196,168,98,.18) 0%, rgba(133,117,78,.25) 100%);
    border-color: var(--accent, #c4a862);
    box-shadow: 0 4px 14px rgba(0,0,0,.4);
}
.dash-kpi-row .kpi-row-accent {
    width: 4px;
    height: 28px;
    border-radius: 2px;
    flex-shrink: 0;
}
.dash-kpi-row .kpi-row-lbl {
    flex: 1;
    font-size: .82rem;
    color: var(--muted-leesbaar);
    transition: color .2s;
}
.dash-kpi-row .kpi-row-val {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--text);
    transition: color .2s;
}
.dash-kpi-row:hover .kpi-row-lbl,
.dash-kpi-row:hover .kpi-row-val {
    color: var(--text);
}
[data-theme="dark"] .dash-kpi-row:hover .kpi-row-lbl,
[data-theme="dark"] .dash-kpi-row:hover .kpi-row-val {
    color: #fff;
}

/* Aandachtspunten banner + chips — theme-aware */
.aand-banner {
    background: var(--orange-soft, #fdf5e6);
    border: 1px solid color-mix(in srgb, var(--orange, #d4a574) 35%, transparent);
    border-radius: 8px;
    padding: 1rem 1.2rem;
}
.aand-title {
    font-weight: 600;
    font-size: .85rem;
    color: color-mix(in srgb, var(--orange, #9a7d3a) 85%, var(--text) 15%);
    margin-bottom: .6rem;
}
.aand-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
}
.aand-chip {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: .5rem .8rem;
    font-size: .8rem;
    color: var(--text);
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.aand-chip:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 6px rgba(0,0,0,.08);
    border-color: var(--accent, #a08c5a);
}
.aand-chip-static {
    cursor: default;
}
.aand-chip-static:hover {
    transform: none;
    box-shadow: none;
    border-color: var(--border);
}
[data-theme="dark"] .aand-banner {
    background: linear-gradient(145deg, rgba(196,168,98,.12) 0%, rgba(133,117,78,.18) 100%);
    border-color: rgba(196,168,98,.3);
}
[data-theme="dark"] .aand-title {
    color: var(--accent, #c4a862);
}
[data-theme="dark"] .aand-chip {
    background: rgba(16,28,43,.7);
    border-color: rgba(196,168,98,.2);
    color: var(--text);
}
[data-theme="dark"] .aand-chip:hover {
    background: rgba(196,168,98,.15);
    border-color: var(--accent, #c4a862);
}

/* ======================================================================
 * Period Badge (MTD / YTD) — feat 22-04-2026
 * Altijd zichtbare badge bovenaan elke target-widget zodat je in één
 * oogopslag ziet om welke periode het gaat, ongeacht het display-type
 * (voortgangsbalk, donut, gauge, kpi-getal, tabel, radar).
 * ====================================================================== */
.period-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: .65rem;
    font-weight: 800;
    letter-spacing: .08em;
    text-transform: uppercase;
    vertical-align: middle;
    margin-right: .5rem;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 1px 2px rgba(0,0,0,.08);
    line-height: 1.3;
}
.period-mtd {
    background: linear-gradient(135deg, #6a9fc7 0%, #3a7bb0 100%);
    color: #fff;
    border: 1px solid rgba(58,123,176,.6);
}
.period-ytd {
    background: linear-gradient(135deg, #85754E 0%, #6c5e3a 100%);
    color: #fff;
    border: 1px solid rgba(108,94,58,.6);
}
[data-theme="dark"] .period-mtd {
    background: linear-gradient(135deg, #4a8fc7 0%, #2c5f8a 100%);
    border-color: rgba(133,194,233,.35);
    box-shadow: inset 0 1px 0 rgba(133,194,233,.2), 0 2px 4px rgba(0,0,0,.3);
}
[data-theme="dark"] .period-ytd {
    background: linear-gradient(135deg, #a08c5a 0%, #6c5e3a 100%);
    border-color: rgba(230,198,122,.35);
    box-shadow: inset 0 1px 0 rgba(230,198,122,.2), 0 2px 4px rgba(0,0,0,.3);
}

/* ======================================================================
 * Persoonlijke Pipeline Opvolging (.pp-card / .pp-tile / .pp-bar)
 * feat 22-04-2026: verkoper-widget voor eigen offertes.
 * 3D glossy look + mount animatie + pulse op overdue + shimmer bar.
 * ====================================================================== */
.pp-card {
    position: relative;
    background: linear-gradient(145deg, var(--card) 0%, color-mix(in srgb, var(--card) 88%, var(--accent, #85754E) 12%) 100%);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.2rem 1.3rem 1rem;
    box-shadow:
        0 12px 28px rgba(0,0,0,.08),
        0 2px 6px rgba(0,0,0,.06),
        inset 0 1px 0 rgba(255,255,255,.6);
    transform: translateZ(0);
    transition: transform .3s cubic-bezier(.22,1,.36,1), box-shadow .3s cubic-bezier(.22,1,.36,1);
    overflow: hidden;
    animation: pp-card-rise .55s cubic-bezier(.22,1,.36,1) both;
}
.pp-card::before {
    /* glossy top-sheen */
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 45%;
    background: linear-gradient(180deg, rgba(255,255,255,.35) 0%, rgba(255,255,255,0) 100%);
    pointer-events: none;
    border-radius: 14px 14px 0 0;
}
.pp-card:hover {
    transform: translateY(-3px);
    box-shadow:
        0 18px 36px rgba(0,0,0,.12),
        0 4px 10px rgba(0,0,0,.08),
        inset 0 1px 0 rgba(255,255,255,.7),
        0 0 0 1px rgba(133,117,78,.2);
}
.pp-card .adm-card-title {
    position: relative;
    z-index: 1;
    margin: 0 0 1rem 0;
    font-size: .8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--text);
}
.pp-card .adm-card-title::after {
    content: '';
    display: block;
    width: 40px;
    height: 2px;
    margin-top: .45rem;
    background: linear-gradient(90deg, var(--accent, #85754E), transparent);
    border-radius: 2px;
}

.pp-tiles {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: .8rem;
    margin-bottom: 1rem;
}
/* Feedback 22-04-2026: variant met 4 tegels (Open/Opvolging/Hit/Overdue). */
.pp-tiles.pp-tiles-4 {
    grid-template-columns: repeat(4, 1fr);
}
/* Wanneer het widget smal staat (container-query based), wrap naar 2x2.
   Container-queries zijn breed genoeg ondersteund (2023+). Fallback: op
   kleine schermbreedte ook 2x2 zetten. */
.pp-card { container-type: inline-size; }
@container (max-width: 360px) {
    .pp-tiles.pp-tiles-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
    .pp-tiles.pp-tiles-4 { grid-template-columns: repeat(2, 1fr); }
}
.pp-tile {
    position: relative;
    text-align: center;
    padding: .55rem .4rem;
    border-radius: 10px;
    background: linear-gradient(180deg, rgba(255,255,255,.5) 0%, rgba(255,255,255,.15) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.55),
        inset 0 -1px 0 rgba(0,0,0,.04),
        0 1px 3px rgba(0,0,0,.05);
    transition: transform .2s cubic-bezier(.22,1,.36,1), box-shadow .25s, background .25s, border-color .25s;
    cursor: default;
    border: 1px solid transparent;
    overflow: hidden;
}
/* Subtiele "sheen" die op hover overgaat. Initieel verborgen (off-screen). */
.pp-tile::after {
    content: '';
    position: absolute;
    top: 0;
    left: -75%;
    width: 60%;
    height: 100%;
    background: linear-gradient(120deg,
        transparent 0%,
        rgba(255,255,255,.35) 50%,
        transparent 100%);
    transform: skewX(-20deg);
    transition: left .55s cubic-bezier(.22,1,.36,1);
    pointer-events: none;
    z-index: 1;
}
.pp-tile[onclick] { cursor: pointer; }
.pp-tile[onclick]:hover {
    transform: translateY(-1px);
}
.pp-tile[onclick]:hover::after {
    left: 120%;
}

/* Colored tiles — elk met hun eigen getinte ruststand + stevige hover-tint
   (verzadigde accentkleur i.p.v. doorschijnend wit). Op hover krijgt de
   tegel ook een gekleurde rand/glow zodat het onmiskenbaar interactief is. */
.pp-tile-open  .pp-num { color: #3a7bb0; position: relative; z-index: 2; }
.pp-tile-opv   .pp-num { color: #6c5e3a; position: relative; z-index: 2; }
.pp-tile-green .pp-num { color: #3f7a55; position: relative; z-index: 2; }
.pp-tile-red   .pp-num { color: #a85e4f; position: relative; z-index: 2; }
.pp-tile .pp-lbl { position: relative; z-index: 2; }

.pp-tile-open {
    background: linear-gradient(180deg, rgba(123,180,230,.22) 0%, rgba(74,143,199,.10) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.55),
        inset 0 -1px 0 rgba(58,123,176,.15),
        0 1px 3px rgba(0,0,0,.05);
}
.pp-tile-open[onclick]:hover {
    background: linear-gradient(180deg, #7bb4e6 0%, #4a8fc7 100%);
    border-color: #3a7bb0;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.45),
        0 6px 14px rgba(58,123,176,.35),
        0 0 0 3px rgba(123,180,230,.25);
}
.pp-tile-open[onclick]:hover .pp-num,
.pp-tile-open[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.18);
}

.pp-tile-opv {
    background: linear-gradient(180deg, rgba(168,147,102,.25) 0%, rgba(108,94,58,.10) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.55),
        inset 0 -1px 0 rgba(108,94,58,.15),
        0 1px 3px rgba(0,0,0,.05);
}
.pp-tile-opv[onclick]:hover {
    background: linear-gradient(180deg, #a89366 0%, #6c5e3a 100%);
    border-color: var(--gold);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.45),
        0 6px 14px rgba(108,94,58,.35),
        0 0 0 3px rgba(168,147,102,.25);
}
.pp-tile-opv[onclick]:hover .pp-num,
.pp-tile-opv[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.18);
}

.pp-tile-green {
    background: linear-gradient(180deg, rgba(114,185,138,.22) 0%, rgba(74,137,96,.10) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.55),
        inset 0 -1px 0 rgba(63,122,85,.15),
        0 1px 3px rgba(0,0,0,.05);
}
.pp-tile-green[onclick]:hover {
    background: linear-gradient(180deg, #72b98a 0%, #4a8960 100%);
    border-color: #3f7a55;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.45),
        0 6px 14px rgba(63,122,85,.35),
        0 0 0 3px rgba(114,185,138,.25);
}
.pp-tile-green[onclick]:hover .pp-num,
.pp-tile-green[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.18);
}

.pp-tile-red {
    background: linear-gradient(180deg, rgba(216,153,139,.22) 0%, rgba(168,94,79,.10) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.55),
        inset 0 -1px 0 rgba(168,94,79,.15),
        0 1px 3px rgba(0,0,0,.05);
}
.pp-tile-red[onclick]:hover {
    background: linear-gradient(180deg, #d8998b 0%, #a85e4f 100%);
    border-color: #a85e4f;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.45),
        0 6px 14px rgba(168,94,79,.35),
        0 0 0 3px rgba(216,153,139,.25);
}
.pp-tile-red[onclick]:hover .pp-num,
.pp-tile-red[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.18);
}
.pp-num {
    font-size: 1.9rem;
    font-weight: 800;
    line-height: 1;
    text-shadow: 0 1px 0 rgba(255,255,255,.4);
    animation: pp-num-pop .55s cubic-bezier(.34,1.56,.64,1) both;
    animation-delay: .12s;
}
.pp-lbl {
    margin-top: .3rem;
    font-size: .65rem;
    font-weight: 700;
    color: var(--muted-leesbaar);
    text-transform: uppercase;
    letter-spacing: .05em;
}

.pp-bar {
    position: relative;
    display: flex;
    height: 22px;
    border-radius: 11px;
    overflow: hidden;
    margin-bottom: .7rem;
    background: rgba(0,0,0,.05);
    box-shadow:
        inset 0 2px 4px rgba(0,0,0,.12),
        inset 0 -1px 0 rgba(255,255,255,.4);
    z-index: 1;
}
.pp-bar::after {
    /* shimmer sheen moving across the whole bar */
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: -40%;
    width: 40%;
    background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,.35) 50%, transparent 100%);
    /* GESCHRAPT (22-8-2026): bij nul offertes gleed hier eindeloos een
       streep over een lege balk. */
    animation: none;
    pointer-events: none;
    z-index: 2;
}
.pp-seg {
    position: relative;
    height: 100%;
    transition: filter .2s, transform .2s;
    cursor: pointer;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.35), inset 0 -1px 0 rgba(0,0,0,.08);
    animation: pp-seg-grow .9s cubic-bezier(.22,1,.36,1) both;
}
.pp-seg:hover { filter: brightness(1.08); }
.pp-seg.pp-open  { background: linear-gradient(180deg,#7bb4e6 0%,#4a8fc7 100%); }
.pp-seg.pp-opv   { background: linear-gradient(180deg,#a89366 0%,#6c5e3a 100%); }
.pp-seg.pp-gew   { background: linear-gradient(180deg,#72b98a 0%,#4a8960 100%); }
.pp-seg.pp-ver   { background: linear-gradient(180deg,#d8998b 0%,#a85e4f 100%); }
.pp-seg.pp-empty { background: linear-gradient(180deg,#ddd 0%,#bbb 100%); cursor: default; }

.pp-legend {
    position: relative;
    z-index: 1;
    display: flex;
    gap: 1rem;
    font-size: .72rem;
    flex-wrap: wrap;
    margin-bottom: .6rem;
    color: var(--text);
}
.pp-legend span {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    transition: opacity .15s;
}
.pp-legend span:hover { opacity: .75; }
.pp-dot {
    display: inline-block;
    width: 10px;
    height: 10px;
    border-radius: 3px;
    margin-right: .35rem;
    box-shadow: 0 1px 2px rgba(0,0,0,.15), inset 0 1px 0 rgba(255,255,255,.3);
}
.pp-dot.pp-open { background: linear-gradient(180deg,#7bb4e6,#4a8fc7); }
.pp-dot.pp-opv  { background: linear-gradient(180deg,#a89366,#6c5e3a); }
.pp-dot.pp-gew  { background: linear-gradient(180deg,#72b98a,#4a8960); }
.pp-dot.pp-ver  { background: linear-gradient(180deg,#d8998b,#a85e4f); }

.pp-footer {
    position: relative;
    z-index: 1;
    font-size: .75rem;
    color: var(--muted-leesbaar);
}
.pp-footer strong { color: var(--text); font-weight: 700; }

/* Dark-theme tuning: glossier card, accented gold rim */
[data-theme="dark"] .pp-card {
    background: linear-gradient(145deg, rgba(26,45,66,.65) 0%, rgba(16,28,43,.9) 100%);
    border-color: rgba(196,168,98,.18);
    box-shadow:
        0 14px 32px rgba(0,0,0,.55),
        0 3px 10px rgba(0,0,0,.35),
        inset 0 1px 0 rgba(196,168,98,.12);
}
[data-theme="dark"] .pp-card::before {
    background: linear-gradient(180deg, rgba(196,168,98,.14) 0%, rgba(196,168,98,0) 100%);
}
[data-theme="dark"] .pp-card:hover {
    box-shadow:
        0 22px 44px rgba(0,0,0,.6),
        0 5px 14px rgba(0,0,0,.45),
        0 0 0 1px rgba(196,168,98,.35),
        inset 0 1px 0 rgba(196,168,98,.18);
}
[data-theme="dark"] .pp-card .adm-card-title {
    color: var(--accent, #c4a862);
}
[data-theme="dark"] .pp-tile {
    background: linear-gradient(180deg, rgba(255,255,255,.05) 0%, rgba(255,255,255,.02) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.08),
        inset 0 -1px 0 rgba(0,0,0,.2),
        0 2px 6px rgba(0,0,0,.3);
}
[data-theme="dark"] .pp-num {
    text-shadow: 0 1px 2px rgba(0,0,0,.5);
}
[data-theme="dark"] .pp-bar {
    background: rgba(0,0,0,.45);
    box-shadow:
        inset 0 2px 6px rgba(0,0,0,.6),
        inset 0 -1px 0 rgba(196,168,98,.1);
}
[data-theme="dark"] .pp-bar::after {
    background: linear-gradient(90deg, transparent 0%, rgba(196,168,98,.28) 50%, transparent 100%);
}
[data-theme="dark"] .pp-seg.pp-open  { background: linear-gradient(180deg,#6ba5d9 0%,#3a7ab3 100%); }
[data-theme="dark"] .pp-seg.pp-opv   { background: linear-gradient(180deg,#c4a862 0%,#85754E 100%); }
[data-theme="dark"] .pp-seg.pp-gew   { background: linear-gradient(180deg,#6ec485 0%,#45875a 100%); }
[data-theme="dark"] .pp-seg.pp-ver   { background: linear-gradient(180deg,#e08a82 0%,#a35246 100%); }
[data-theme="dark"] .pp-seg.pp-empty { background: linear-gradient(180deg,rgba(255,255,255,.08),rgba(255,255,255,.03)); }
[data-theme="dark"] .pp-legend { color: #c9cdd2; }
[data-theme="dark"] .pp-footer strong { color: var(--accent, #c4a862); }

/* Colored tiles in dark mode: dempen de basis-tint, hover krijgt een sterkere
   glow. Cijfers pastel zodat contrast op donkere achtergrond blijft kloppen. */
[data-theme="dark"] .pp-tile-open  .pp-num { color: #85c1e9; }
[data-theme="dark"] .pp-tile-opv   .pp-num { color: #e6c67a; }
[data-theme="dark"] .pp-tile-green .pp-num { color: #7dcea0; }
[data-theme="dark"] .pp-tile-red   .pp-num { color: #f1948a; }

[data-theme="dark"] .pp-tile-open {
    background: linear-gradient(180deg, rgba(74,143,199,.20) 0%, rgba(26,61,92,.35) 100%);
}
[data-theme="dark"] .pp-tile-open[onclick]:hover {
    background: linear-gradient(180deg, #5b9dd6 0%, #2f6b9a 100%);
    border-color: #85c1e9;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.18),
        0 8px 18px rgba(0,0,0,.5),
        0 0 0 3px rgba(133,194,233,.18);
}
[data-theme="dark"] .pp-tile-open[onclick]:hover .pp-num,
[data-theme="dark"] .pp-tile-open[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.4);
}
[data-theme="dark"] .pp-tile-opv {
    background: linear-gradient(180deg, rgba(168,147,102,.20) 0%, rgba(90,75,40,.35) 100%);
}
[data-theme="dark"] .pp-tile-opv[onclick]:hover {
    background: linear-gradient(180deg, #b49868 0%, #75643a 100%);
    border-color: #e6c67a;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.18),
        0 8px 18px rgba(0,0,0,.5),
        0 0 0 3px rgba(230,198,122,.18);
}
[data-theme="dark"] .pp-tile-opv[onclick]:hover .pp-num,
[data-theme="dark"] .pp-tile-opv[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.4);
}
[data-theme="dark"] .pp-tile-green {
    background: linear-gradient(180deg, rgba(74,137,96,.20) 0%, rgba(26,80,50,.35) 100%);
}
[data-theme="dark"] .pp-tile-green[onclick]:hover {
    background: linear-gradient(180deg, #5fa677 0%, #336b48 100%);
    border-color: #7dcea0;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.18),
        0 8px 18px rgba(0,0,0,.5),
        0 0 0 3px rgba(125,206,160,.18);
}
[data-theme="dark"] .pp-tile-green[onclick]:hover .pp-num,
[data-theme="dark"] .pp-tile-green[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.4);
}
[data-theme="dark"] .pp-tile-red {
    background: linear-gradient(180deg, rgba(168,94,79,.20) 0%, rgba(110,44,34,.35) 100%);
}
[data-theme="dark"] .pp-tile-red[onclick]:hover {
    background: linear-gradient(180deg, #c27a6c 0%, #8a4a3e 100%);
    border-color: #f1948a;
    box-shadow:
        inset 0 1px 0 rgba(255,255,255,.18),
        0 8px 18px rgba(0,0,0,.5),
        0 0 0 3px rgba(241,148,138,.18);
}
[data-theme="dark"] .pp-tile-red[onclick]:hover .pp-num,
[data-theme="dark"] .pp-tile-red[onclick]:hover .pp-lbl {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0,0,0,.4);
}

@keyframes pp-card-rise {
    from { opacity: 0; transform: translateY(14px) scale(.98); }
    to   { opacity: 1; transform: translateY(0)   scale(1); }
}
@keyframes pp-num-pop {
    0%   { opacity: 0; transform: scale(.6); }
    70%  { opacity: 1; transform: scale(1.1); }
    100% { opacity: 1; transform: scale(1); }
}
@keyframes pp-seg-grow {
    from { flex-grow: 0 !important; opacity: .2; }
    to   { opacity: 1; }
}
@keyframes pp-bar-shimmer {
    0%   { left: -40%; }
    70%  { left: 110%; }
    100% { left: 110%; }
}
@media (prefers-reduced-motion: reduce) {
    html:not(.beweging-aan) .pp-card,
    html:not(.beweging-aan) .pp-num,
    html:not(.beweging-aan) .pp-seg { animation: none !important; }
    html:not(.beweging-aan) .pp-bar::after { animation: none !important; display: none; }
    html:not(.beweging-aan) .pp-card:hover { transform: none; }
    html:not(.beweging-aan) .pp-tile[onclick]:hover { transform: none; }
}

/* ============================================================
   Meldingsbel + notificatiepaneel (topbar) - teruggezet 2026-08.
   Alle kleuren via var() zodat het in de geforceerde dark mode
   leesbaar blijft. Vervangt de hardgecodeerde #fff/#333-kleuren
   uit de oude JS-template.
   ============================================================ */
.notif-bell {
    position: relative; display: none; align-items: center; justify-content: center;
    width: 34px; height: 34px; border-radius: 8px; cursor: pointer; flex-shrink: 0;
}
.notif-bell:hover { background: var(--hover-bg); }
.notif-bell:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.notif-bell-icon { font-size: 1.25rem; line-height: 1; }

.notif-badge {
    position: absolute; top: -2px; right: -2px;
    min-width: 18px; height: 18px; line-height: 18px; padding: 0 4px;
    border-radius: 9px; background: var(--accent);
    /* Wit op goud haalt 2,30:1 -- op het getalletje dat zegt hoeveel werk er
     * ligt. Donkere tekst op datzelfde goud haalt 8,04:1. */
    color: #0a1421;
    font-size: .68rem; font-weight: 700; text-align: center;
    border: 2px solid var(--card);
}
.notif-badge.is-urgent { background: var(--red); }

.notif-dropdown {
    position: absolute; right: 0; top: 2.6rem;
    width: 380px; max-width: 92vw; max-height: 460px; overflow-y: auto;
    background: var(--dropdown-bg); color: var(--text);
    border: 1px solid var(--border); border-radius: 10px;
    box-shadow: var(--shadow-md); z-index: 1200; cursor: default; text-align: left;
}
.notif-head {
    display: flex; justify-content: space-between; align-items: center;
    padding: .6rem .8rem; border-bottom: 1px solid var(--border);
    position: sticky; top: 0; background: var(--dropdown-bg); z-index: 2;
}
.notif-head strong { font-size: .88rem; color: var(--text); }
.notif-mark-all {
    background: none; border: 1px solid var(--border); color: var(--text-secondary);
    border-radius: 6px; font-size: .7rem; padding: .22rem .5rem; cursor: pointer;
}
.notif-mark-all:hover { background: var(--hover-bg); }
.notif-tabs {
    display: flex; gap: .3rem; padding: .45rem .8rem;
    border-bottom: 1px solid var(--border);
    position: sticky; top: 41px; background: var(--dropdown-bg); z-index: 2;
}
.notif-tab {
    flex: 1; background: none; border: 1px solid var(--border); border-radius: 6px;
    padding: .25rem .4rem; font-size: .72rem; color: var(--text-secondary); cursor: pointer;
}
.notif-tab.is-active { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
.notif-empty { padding: 1.6rem .8rem; text-align: center; color: var(--muted-leesbaar); font-size: .85rem; }

.notif-item {
    display: flex; gap: .55rem; align-items: flex-start;
    padding: .6rem .8rem; border-bottom: 1px solid var(--border);
    border-left: 3px solid transparent; cursor: pointer;
}
.notif-item:hover { background: var(--hover-bg); }
.notif-item.is-unread { background: var(--hover-bg); }
.notif-item.is-read { opacity: .62; }
.notif-item.type-warning { border-left-color: var(--orange); }
.notif-item.type-urgent  { border-left-color:var(--red-tekst); }
.notif-item-icon { font-size: .95rem; flex-shrink: 0; line-height: 1.3; }
.notif-item-body { flex: 1; min-width: 0; }
.notif-item-title {
    font-size: .82rem; color: var(--text); line-height: 1.25;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.notif-item.is-unread .notif-item-title { font-weight: 600; }
.notif-item-msg {
    font-size: .75rem; color: var(--text-secondary); margin-top: .12rem;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.notif-item-meta {
    display: flex; justify-content: space-between; gap: .5rem;
    font-size: .68rem; color: var(--muted-leesbaar); margin-top: .25rem;
}
.notif-item-cat { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notif-item-dot {
    width: 8px; height: 8px; border-radius: 50%; background: var(--accent);
    flex-shrink: 0; margin-top: .35rem;
}

@media (max-width: 768px) {
    /* Op gsm hangt het paneel als vaste kaart onder de topbar i.p.v.
       rechts uit te lijnen (anders valt hij half buiten beeld). */
    .notif-dropdown {
        position: fixed; left: .5rem; right: .5rem; top: 4.2rem;
        width: auto; max-width: none; max-height: 70vh;
    }
}


/* ---------------------------------------------------------------------------
   DE ESCALATIELADDER (06-08-2026)

   De eigenaar: "op niveau 3 moeten de 2 lagere niveaus expliciet weten dat de
   admin meekijkt en er gevolgen zijn." Dat is de hele bedoeling van een
   getrapte verwittiging — als niemand het ziet, is het geen ladder.

   Bewust GEEN gevulde rij-achtergrond en geen fel rood: dat is de afspraak
   voor dit systeem. Een linkerrand en een rustige tint volstaan; de tekst zelf
   doet het werk.
   --------------------------------------------------------------------------- */
.aandacht-ladder {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-size: .7rem;
    font-weight: 600;
    padding: .1rem .5rem;
    border-radius: 10px;
    white-space: nowrap;
}
.aandacht-ladder.ladder-2 {
    background: var(--blue-soft);
    color: var(--blue);
    border: 1px solid var(--blue);
}
.aandacht-ladder.ladder-3 {
    background: var(--orange-soft);
    color: var(--orange);
    border: 1px solid var(--orange);
}

/* Wie voor wie invalt (06-08-2026). Blauw, want dit is informatie en geen
   waarschuwing: er is niets mis, er staat alleen werk van een collega bij. */
.aandacht-invaller {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-size: .7rem;
    font-weight: 600;
    padding: .1rem .5rem;
    border-radius: 10px;
    white-space: nowrap;
    background: var(--blue-soft);
    color: var(--blue);
    border: 1px solid var(--blue);
}

/* ==========================================================================
   DEMO-KETEN (wagenpark, alleen nieuwe Kia's)
   De linkerrand is de indicator; geen gekleurde rij-achtergronden.
   ========================================================================== */
.demo-keten {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: .9rem 1rem;
    margin-bottom: 1rem;
    background: var(--card);
}
.demo-keten-kop {
    font-weight: 600;
    margin-bottom: .6rem;
}
.demo-keten-uitleg {
    font-size: .82rem;
    color: var(--muted-leesbaar);
    margin: 0 0 .7rem;
    line-height: 1.45;
}
.demo-stappen {
    list-style: none;
    margin: 0;
    padding: 0;
}
.demo-stap {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .45rem .6rem;
    border-left: 3px solid var(--border);
    margin-bottom: .25rem;
    font-size: .87rem;
}
.demo-stap.demo-af      { border-left-color: var(--green); }
.demo-stap.demo-open    { border-left-color: var(--orange); }
.demo-stap.demo-later   { opacity: .62; }
.demo-bol {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: .72rem;
    font-weight: 700;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--muted-leesbaar);
}
.demo-stap.demo-af .demo-bol {
    background: var(--green);
    border-color: var(--green);
    color: var(--bg);
}
.demo-label   { flex: 0 0 auto; font-weight: 500; }
.demo-detail  { flex: 1 1 auto; color: var(--muted-leesbaar); font-size: .8rem; }
.demo-knop    { flex: 0 0 auto; margin-left: auto; }
.demo-aanbeurt { font-style: italic; }
.demo-ja      { color: var(--green); font-weight: 600; }
.demo-nee     { color: var(--muted-leesbaar); font-weight: 600; }
.demo-terug   { opacity: .55; padding: .1rem .45rem; }
.demo-terug:hover { opacity: 1; }

/* De terugkerende aflezing van de teller. Geen ketenstap — die zet je één
   keer af — maar een vraag die blijft terugkomen zolang de demo rijdt.
   Zelfde vorm als een stap, eigen scheiding erboven. Staat de stand te lang
   stil, dan kleurt de LINKERRAND mee; geen gekleurd vlak, zoals overal in
   dit scherm. */
.demo-teller {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .5rem .6rem .1rem;
    margin-top: .55rem;
    border-top: 1px solid var(--border);
    border-left: 3px solid transparent;
    font-size: .87rem;
}
.demo-teller.demo-teller-oud { border-left-color: var(--orange); }

@media (max-width: 700px) {
    .demo-stap { flex-wrap: wrap; }
    .demo-detail { flex-basis: 100%; margin-left: 1.9rem; }
    .demo-knop { margin-left: 1.9rem; }
    .demo-teller { flex-wrap: wrap; }
    .demo-teller .demo-detail { margin-left: 0; }
    .demo-teller .demo-knop { margin-left: 0; }
}

/* ==========================================================================
   AGENDA — twee lagen: werk met een deadline, en afspraken met een uur.
   Ze staan in aparte blokken; door elkaar zetten zou betekenen dat werk
   zonder uur op basis van niets bovenaan of onderaan belandt.
   ========================================================================== */
.agenda-balk {
    display: flex;
    flex-wrap: wrap;
    gap: .8rem;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 1rem;
}
.agenda-navigatie, .agenda-filters {
    display: flex;
    gap: .5rem;
    align-items: center;
    flex-wrap: wrap;
}
.agenda-venster {
    font-weight: 600;
    margin-left: .4rem;
}
.agenda-select {
    padding: .35rem .5rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--card);
    color: var(--text);
    font-size: .85rem;
}
.agenda-vink {
    font-size: .85rem;
    color: var(--muted-leesbaar);
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    cursor: pointer;
}
.agenda-laden, .agenda-fout {
    color: var(--muted-leesbaar);
    padding: 1rem;
}

.agenda-dag {
    border: 1px solid var(--border);
    border-left: 3px solid var(--border);
    border-radius: 8px;
    padding: .7rem .9rem;
    margin-bottom: .6rem;
    background: var(--card);
}
.agenda-dag.agenda-vandaag { border-left-color: var(--blue); }
.agenda-dag.agenda-weekend { background: var(--hover-bg); }
.agenda-dag.agenda-leeg    { opacity: .55; padding: .45rem .9rem; }
.agenda-dagkop {
    font-weight: 600;
    margin-bottom: .5rem;
    text-transform: capitalize;
}
.agenda-vandaag-vlag {
    font-size: .7rem;
    font-weight: 700;
    color: var(--blue);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-left: .3rem;
}
.agenda-blokkop {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted-leesbaar);
    margin: .3rem 0 .25rem;
}
.agenda-werkblok { margin-bottom: .5rem; }

.agenda-werk, .agenda-afspraak {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .35rem .5rem;
    border-left: 2px solid var(--border);
    font-size: .87rem;
    margin-bottom: .2rem;
}
.agenda-werk { cursor: pointer; }
.agenda-werk:hover { background: var(--hover-bg); }
.agenda-werk.agenda-te-laat { border-left-color:var(--red-tekst); }
.agenda-werk-soort {
    flex: 0 0 auto;
    min-width: 8.5rem;
    font-weight: 500;
}
.agenda-werk-tekst { flex: 1 1 auto; color: var(--muted-leesbaar); }
.agenda-te-laat-vlag {
    flex: 0 0 auto;
    font-size: .7rem;
    font-weight: 700;
    color:var(--red-tekst);
    text-transform: uppercase;
}

.agenda-afspraak { border-left-color: var(--blue); }
.agenda-soort-levering { border-left-color: var(--green); }
.agenda-soort-testrit  { border-left-color: var(--orange); }
.agenda-uur {
    flex: 0 0 auto;
    min-width: 3.2rem;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}
.agenda-titel { flex: 0 0 auto; font-weight: 500; }
.agenda-wie   { flex: 1 1 auto; color: var(--muted-leesbaar); font-size: .82rem; }
.agenda-knoppen { flex: 0 0 auto; margin-left: auto; display: flex; gap: .3rem; }
.agenda-niets { color: var(--muted-leesbaar); font-size: .82rem; font-style: italic; }

@media (max-width: 700px) {
    .agenda-werk, .agenda-afspraak { flex-wrap: wrap; }
    .agenda-werk-soort { min-width: 0; }
    .agenda-knoppen { margin-left: 0; width: 100%; }
}

/* ==========================================================================
   STATUSBADGES IN HET WAGENPARK
   Stonden als harde hexcodes in de JavaScript, uit het Material-palet. Wit op
   geel (#ffeb3b) haalde 2.12:1. Nu per thema, met nagemeten contrast.
   ========================================================================== */
.sv-badge {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 12px;
    font-size: .75rem;
    font-weight: 600;
    white-space: nowrap;
}
.sv-badge-stock     { background: var(--green-soft);  color: #2f6b45; }
.sv-badge-demo      { background: var(--blue-soft);   color: #2c5f80; }
.sv-badge-verkocht  { background: var(--orange-soft); color: #7a5c14; }
.sv-badge-besteld   { background: var(--orange-soft); color: #7a5c14; }
.sv-badge-klaar     { background: var(--green-soft);  color: #2f6b45; }
.sv-badge-werk      { background: var(--blue-soft);   color: #2c5f80; }
.sv-badge-geleverd  { background: var(--hover-bg);    color: var(--muted-leesbaar); }
.sv-badge-neutraal  { background: var(--hover-bg);    color: var(--muted-leesbaar); }

[data-theme="dark"] .sv-badge-stock     { background: #1a3324; color: #8fd6a6; }
[data-theme="dark"] .sv-badge-demo      { background: #152a3d; color: #93c6e3; }
[data-theme="dark"] .sv-badge-verkocht  { background: #3a2f12; color: #e0c078; }
[data-theme="dark"] .sv-badge-besteld   { background: #3a2f12; color: #e0c078; }
[data-theme="dark"] .sv-badge-klaar     { background: #1a3324; color: #8fd6a6; }
[data-theme="dark"] .sv-badge-werk      { background: #152a3d; color: #93c6e3; }
[data-theme="dark"] .sv-badge-geleverd  { background: #1c2a3d; color: #a8b6c6; }
[data-theme="dark"] .sv-badge-neutraal  { background: #1c2a3d; color: #a8b6c6; }

/* ==========================================================================
   EIGEN VENSTERS EN MELDINGEN
   Vervangen de ingebouwde vensters van de browser. Die faalden stil zodra ze
   in een scherm uitgeschakeld waren, en ze zijn niet te kleuren of te lezen op
   een tablet in de werkplaats.
   ========================================================================== */
.ss-venster-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, .45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 12000;
    padding: 1rem;
}
.ss-venster {
    background: var(--card);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.3rem 1.4rem 1.1rem;
    width: 460px;
    max-width: 100%;
    max-height: 86vh;
    overflow-y: auto;
    box-shadow: 0 12px 32px rgba(0, 0, 0, .28);
}
.ss-venster-titel {
    margin: 0 0 .5rem;
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.35;
}
.ss-venster-uitleg {
    margin: 0 0 .9rem;
    font-size: .85rem;
    line-height: 1.5;
    color: var(--muted-leesbaar);
}
.ss-venster-veld {
    width: 100%;
    padding: .55rem .7rem;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: var(--input-bg, var(--bg));
    color: var(--text);
    font-size: .92rem;
    font-family: inherit;
    line-height: 1.45;
}
.ss-venster-veld:focus {
    outline: none;
    border-color: var(--gold);
    box-shadow: 0 0 0 3px var(--gold-dim, rgba(196, 168, 98, .18));
}
.ss-venster-fout {
    min-height: 1.1rem;
    margin-top: .35rem;
    font-size: .8rem;
    color: var(--red-knop);
    font-weight: 500;
}
.ss-venster-knoppen {
    display: flex;
    gap: .5rem;
    justify-content: flex-end;
    margin-top: .9rem;
}

/* --- Een cijfer waar je op kan klikken ----------------------------------
   De eigenaar (7-8-2026): een getal op het dashboard zonder klik is een getal
   waar je niets mee kan. Deze klasse maakt zichtbaar DAT er iets achter zit:
   de aanwijzer verandert, de tegel krijgt een rustige tint bij aanwijzen, en
   een toetsenbordgebruiker ziet dezelfde tint plus een duidelijke rand.
   Geen gekleurde vulling van de rij zelf — alleen de zachte informatietint uit
   de meldingsniveaus, die in beide thema's is nagemeten. */
.dash-klikbaar {
    cursor: pointer;
}
/* De kaarten en tegels wippen al omhoog bij aanwijzen (.adm-card,
   .dash-kpi-tile); daar zou een extra vulling het beeld alleen maar drukker
   maken. De kale regels — een verkoperrij, "COI Maand", "NVD MTD" — hebben nog
   niets, en krijgen de zachte informatietint plus een linkerrand. Geen
   gekleurde rij-achtergrond, geen rood. */
.dash-klikbaar:not(.adm-card):not(.dash-kpi-tile) {
    border-radius: 8px;
    border-left: 3px solid transparent;
    padding-left: .35rem;
    transition: background .15s ease, border-color .15s ease;
}
.dash-klikbaar:not(.adm-card):not(.dash-kpi-tile):hover,
.dash-klikbaar:not(.adm-card):not(.dash-kpi-tile):focus-visible {
    background: var(--melding-info-bg);
    border-left-color: var(--gold);
}
/* Het toetsenbord moet altijd zien waar het staat, ook op de kaarten. */
.dash-klikbaar:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

/* --- De lijst achter een cijfer ----------------------------------------- */
.ss-venster-breed { width: 900px; }
.ss-lijst-omhulsel {
    max-height: 55vh;
    overflow: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
}
.ss-lijst-tabel {
    width: 100%;
    border-collapse: collapse;
    font-size: .85rem;
}
.ss-lijst-tabel th {
    position: sticky;
    top: 0;
    background: var(--bg);
    color: var(--muted-leesbaar);
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .02em;
    font-weight: 600;
    padding: .5rem .6rem;
    border-bottom: 1px solid var(--border);
}
.ss-lijst-tabel td {
    padding: .45rem .6rem;
    border-bottom: 1px solid var(--border);
}
.ss-lijst-rij {
    cursor: pointer;
    border-left: 3px solid transparent;
}
.ss-lijst-rij:hover,
.ss-lijst-rij:focus-visible {
    background: var(--melding-info-bg);
    border-left-color: var(--gold);
    outline: none;
}

/* --- Meldingen ---------------------------------------------------------- */
.ss-meldingen {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 12500;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    max-width: min(30rem, calc(100vw - 2rem));
}
.ss-melding {
    background: var(--card);
    color: var(--text);
    border: 1px solid var(--border);
    border-left: 3px solid var(--muted-leesbaar);
    border-radius: 8px;
    padding: .65rem .9rem;
    font-size: .88rem;
    line-height: 1.45;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .18);
    cursor: pointer;
    animation: ss-melding-in .22s ease-out;
}
.ss-melding-ok   { border-left-color: var(--green); }
.ss-melding-fout { border-left-color: var(--red-knop); }
.ss-melding-info { border-left-color: var(--blue); }

/* "LEEG" IS NIET HETZELFDE ALS "NIET GELADEN" (schermrapport 10-8-2026)
   ------------------------------------------------------------------
   Deze strook komt op de plek waar anders een lijst zou staan. Bewust rustig:
   geen alarmrood vlak, wel een duidelijke linkerrand — dezelfde taal als de
   rest van SalesSync. Wat telt is de zin zelf: dit is GEEN lege lijst. */
.ss-laadfout {
    border: 1px solid var(--border);
    border-left: 3px solid var(--red-knop);
    border-radius: 8px;
    background: var(--card);
    color: var(--text);
    padding: .7rem .9rem;
    margin: .5rem 0;
    font-size: .88rem;
    line-height: 1.5;
}
.ss-laadfout-uitleg { color: var(--muted-leesbaar); margin-top: .2rem; }
.ss-laadfout-reden  { font-size: .82rem; opacity: .85; }
.ss-melding-weg {
    opacity: 0;
    transform: translateX(1rem);
    transition: opacity .35s, transform .35s;
}
@keyframes ss-melding-in {
    from { opacity: 0; transform: translateX(1rem); }
    to   { opacity: 1; transform: translateX(0); }
}

@media (max-width: 640px) {
    .ss-venster { padding: 1.1rem 1rem .9rem; }
    .ss-venster-knoppen { flex-direction: column-reverse; }
    .ss-venster-knoppen .btn { width: 100%; }
    .ss-meldingen { right: .6rem; left: .6rem; bottom: .6rem; max-width: none; }
}

/* ==========================================================================
   AGENDA — HET ROOSTER
   Uren verticaal, dagen horizontaal, zoals Outlook. De kleur van een blok komt
   van de medewerker en wordt inline gezet; hier staat alleen de vorm.
   ========================================================================== */

/* --- De balk erboven ----------------------------------------------------- */
.ag-balk {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    align-items: center;
    justify-content: space-between;
    margin-bottom: .8rem;
}
.ag-nav { display: flex; gap: .35rem; align-items: center; flex-wrap: wrap; }
.ag-periode { font-weight: 600; margin-left: .5rem; white-space: nowrap; }
.ag-rechts { display: flex; gap: .4rem; align-items: center; flex-wrap: wrap; }
.ag-weergave { display: inline-flex; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; }
.ag-weergave button {
    border: none;
    background: var(--card);
    color: var(--text);
    padding: .3rem .75rem;
    font-size: .82rem;
    cursor: pointer;
    border-right: 1px solid var(--border);
}
.ag-weergave button:last-child { border-right: none; }
/* Wit op goud haalt 4,51:1; de paginakleur erop bleef op 4,18:1
   steken. In het donkere thema is --gold juist licht, dus daar moet
   de tekst wel donker (zie hieronder). */
.ag-weergave button.actief { background: var(--gold); color: #fff; font-weight: 600; }
[data-theme="dark"] .ag-weergave button.actief { color: var(--bg); }

/* --- Het rooster --------------------------------------------------------- */
.ag-rooster {
    border: 1px solid var(--border);
    border-radius: 9px;
    overflow: hidden;
    background: var(--card);
}
.ag-kop {
    display: grid;
    border-bottom: 1px solid var(--border);
}
.ag-kop-dag {
    padding: .45rem .3rem;
    text-align: center;
    border-left: 1px solid var(--border);
    min-width: 0;
}
.ag-kop-dag:first-child { border-left: none; }
.ag-kop-weekdag { font-size: .72rem; color: var(--muted-leesbaar); text-transform: lowercase; }
.ag-kop-nummer { font-size: 1rem; font-weight: 500; }
.ag-kop-dag.ag-vandaag { background: var(--blue-soft); }
.ag-kop-dag.ag-vandaag .ag-kop-nummer,
.ag-kop-dag.ag-vandaag .ag-kop-weekdag { color: var(--blue); font-weight: 600; }
.ag-kop-dag.ag-weekend { background: var(--hover-bg); }

/* --- De strook met wat over hele dagen loopt ----------------------------- */
.ag-strook {
    display: grid;
    border-bottom: 2px solid var(--border);
    min-height: 1.5rem;
    position: relative;
}
.ag-strook-cel { border-left: 1px solid var(--border); min-width: 0; padding: 2px; }
.ag-strook-cel:first-child { border-left: none; }
.ag-strook-hoek {
    font-size: .65rem;
    color: var(--muted-leesbaar);
    text-align: right;
    padding: 3px 4px 0 0;
}
/* Een balk die over meerdere dagen loopt, ligt over de cellen heen. */
.ag-balkje {
    position: absolute;
    height: 1.05rem;
    line-height: 1.05rem;
    font-size: .7rem;
    padding: 0 .4rem;
    border-radius: 3px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: default;
}
.ag-balkje-pijl-links { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.ag-balkje-pijl-rechts { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.ag-werkje {
    font-size: .68rem;
    padding: 1px 4px;
    margin-bottom: 1px;
    border-left: 2px solid var(--muted-leesbaar);
    background: var(--hover-bg);
    border-radius: 0 2px 2px 0;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ag-werkje:hover { background: var(--border); }
.ag-werkje.ag-te-laat { border-left-color: var(--red-knop); }

/* --- Het urenrooster ----------------------------------------------------- */
.ag-uren {
    display: grid;
    position: relative;
    max-height: 60vh;
    overflow-y: auto;
}
.ag-urengoot { position: relative; }
.ag-uurlabel {
    position: absolute;
    right: 4px;
    font-size: .68rem;
    color: var(--muted-leesbaar);
    transform: translateY(-.4em);
}
.ag-dagkolom {
    position: relative;
    border-left: 1px solid var(--border);
    min-width: 0;
}
.ag-dagkolom.ag-weekend { background: var(--hover-bg); }
.ag-dagkolom.ag-vandaag { background: var(--blue-soft); }

/* --- Wettelijke feestdagen (15-8-2026) ------------------------------------
   De eigenaar: *"De feestdagen mogen in de agenda automatisch gezet worden en
   op die dagen kunnen er geen agenda punten komen."*

   Geen gekleurd vlak — dat is de afspraak, en zeker geen rood. Een dag die
   dicht is leest als dicht door een fijne arcering en een cursor die niet meer
   'klikbaar' zegt. De naam staat in de kop, want "gesloten" zonder reden laat
   iemand denken dat er iets stuk is. */
.ag-dagkolom.ag-feestdag {
    background: repeating-linear-gradient(135deg,
        transparent 0 6px, var(--hover-bg) 6px 12px);
    cursor: default;
}
.ag-kop-dag.ag-feestdag { opacity: .72; }
.ag-kop-feestdag {
    font-size: .6rem;
    line-height: 1.15;
    margin-top: 2px;
    color: var(--muted-leesbaar);
    white-space: normal;
}
.ag-maand-feestdag {
    font-size: .62rem;
    font-weight: 600;
    color: var(--muted-leesbaar);
    margin-bottom: 2px;
}
.ag-uurlijn { position: absolute; left: 0; right: 0; border-top: 1px solid var(--border); }
.ag-halfuurlijn { position: absolute; left: 0; right: 0; border-top: 1px dotted var(--border); opacity: .5; }
.ag-nulijn { position: absolute; left: 0; right: 0; height: 2px; background: var(--red-knop); z-index: 6; pointer-events: none; }
.ag-nubol {
    position: absolute;
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--red-knop);
    margin-left: -4px;
    margin-top: -3px;
    z-index: 7;
    pointer-events: none;
}

/* --- Een afspraak in het rooster ---------------------------------------- */
.ag-afspraak {
    position: absolute;
    border-radius: 4px;
    padding: 2px 5px;
    font-size: .72rem;
    line-height: 1.25;
    color: #fff;
    overflow: hidden;
    cursor: pointer;
    z-index: 4;
    border-left: 3px solid rgba(0, 0, 0, .25);
    box-sizing: border-box;
}
.ag-afspraak:hover { filter: brightness(1.08); z-index: 8; }
.ag-afspraak.ag-sleept { opacity: .65; z-index: 9; }
.ag-afspraak-uur { font-weight: 600; }
.ag-afspraak-titel { font-weight: 500; }
.ag-afspraak-wie { opacity: .85; }
.ag-afspraak-reeks { opacity: .8; font-size: .65rem; }
/* De greep onderaan om een afspraak langer te maken. */
.ag-greep {
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 6px;
    cursor: ns-resize;
}
.ag-afspraak:hover .ag-greep { background: rgba(255, 255, 255, .35); }

/* --- Maandweergave ------------------------------------------------------- */
.ag-maand { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.ag-maanddag {
    border-left: 1px solid var(--border);
    border-top: 1px solid var(--border);
    min-height: 5.5rem;
    padding: 3px;
    min-width: 0;
    cursor: pointer;
}
.ag-maanddag.ag-buiten { opacity: .45; }
.ag-maanddag.ag-vandaag { background: var(--blue-soft); }
.ag-maanddag.ag-weekend { background: var(--hover-bg); }
/* ⚠️ Ná de weekendregel. Gemeten in het scherm: 1 november 2026 valt op een
   zondag, en dan overschreef de weekendregel (die verderop stond) de arcering —
   de naam stond er wel, de arcering niet. Gelijke specificiteit, dus wint wie
   het laatst komt. */
.ag-maanddag.ag-feestdag {
    background: repeating-linear-gradient(135deg,
        transparent 0 6px, var(--hover-bg) 6px 12px);
}
.ag-maanddag-nr { font-size: .75rem; color: var(--muted-leesbaar); margin-bottom: 2px; }
.ag-maanddag.ag-vandaag .ag-maanddag-nr { color: var(--blue); font-weight: 700; }
.ag-maanditem {
    font-size: .68rem;
    padding: 1px 4px;
    border-radius: 3px;
    margin-bottom: 1px;
    color: #fff;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ag-meer { font-size: .65rem; color: var(--muted-leesbaar); padding-left: 3px; }

/* --- De legende en de agendalijst ---------------------------------------- */
.ag-legende {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem .9rem;
    margin-top: .7rem;
    font-size: .78rem;
    color: var(--muted-leesbaar);
}
.ag-legende label { display: inline-flex; align-items: center; gap: .3rem; cursor: pointer; }
.ag-legende input { margin: 0; }
.ag-stip { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.ag-legende .ag-uit { opacity: .4; text-decoration: line-through; }

@media (max-width: 820px) {
    .ag-uren { max-height: 70vh; }
    .ag-afspraak { font-size: .66rem; padding: 1px 3px; }
    .ag-kop-nummer { font-size: .85rem; }
    .ag-periode { margin-left: 0; width: 100%; }
}

/* --- Het vraagvenster van SalesSync -------------------------------------
   Zelfde vorm als de andere vensters; alleen de vraagblokken zijn eigen. */
.ss-vraag {
    border-left: 3px solid var(--orange);
    background: var(--bg);
    border-radius: 0 6px 6px 0;
    padding: .6rem .9rem;
    margin-bottom: .8rem;
}
.ss-vraag-melding {
    border-left-color: var(--blue);
    font-size: .85rem;
    color: var(--muted-leesbaar);
}
.ss-vraag-tekst { font-weight: 600; margin-bottom: .3rem; line-height: 1.4; }
.ss-vraag-uitleg {
    font-size: .8rem;
    color: var(--muted-leesbaar);
    margin-bottom: .5rem;
    line-height: 1.45;
}
.ss-vraag-optie {
    display: block;
    margin: .25rem 0;
    font-size: .9rem;
    cursor: pointer;
}
.ss-vraag-toelichting { display: none; margin-top: .45rem; }

/* --- Chassis en sleutel, meteen zichtbaar -------------------------------
   Wie met een tablet op de parking staat, leest geen volzin maar zoekt twee
   getallen. Daarom staan ze apart, in een vast lettertype zodat cijfers netjes
   onder elkaar uitlijnen. */
.kenmerken { display: flex; gap: .4rem; flex-wrap: wrap; margin-top: .25rem; }
.kenmerk {
    display: inline-flex;
    align-items: baseline;
    gap: .3rem;
    padding: .1rem .45rem;
    border-radius: 4px;
    background: var(--hover-bg);
    border: 1px solid var(--border);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: .8rem;
    font-weight: 600;
    letter-spacing: .03em;
    color: var(--text);
}
.kenmerk-label {
    font-size: .62rem;
    font-weight: 500;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted-leesbaar);
}
.kenmerk-chassis { border-left: 3px solid var(--blue); }
.kenmerk-sleutel { border-left: 3px solid var(--gold); }

/* Een richtpunt: in de naverkoopagenda is een aflevering niet hun eigen
   afspraak maar het moment waar hun werk naartoe loopt. Gestreept en iets
   doorzichtiger, zodat het onderscheid zichtbaar is zonder te lezen. */
.ag-afspraak.ag-richtpunt {
    opacity: .82;
    border-left-style: dashed;
    border-left-width: 4px;
}
.ag-groepkeuze { margin-right: .3rem; }


/* ==========================================================================
 *  UITBESTEED WERK
 *
 *  Het paneel op een fiche en op een levering: wat er bij een externe
 *  leverancier uitstaat en wat hij geantwoord heeft.
 *
 *  Geen gekleurde rij-achtergronden: de stand staat in de linkerrand en in het
 *  tekstje eronder. Rood zou hier bovendien misleiden — "lukt niet" is geen
 *  fout, het betekent dat wij iemand anders zoeken.
 * ========================================================================== */

.ext-paneel { display: flex; flex-direction: column; gap: .5rem; }

.ext-leeg {
    color: var(--muted-leesbaar);
    font-size: .85rem;
    font-style: italic;
}

.ext-rij {
    border: 1px solid var(--border);
    border-left: 3px solid var(--muted-leesbaar);
    border-radius: 6px;
    padding: .5rem .65rem;
    background: var(--card);
}
.ext-rij-gevraagd   { border-left-color: var(--gold); }
.ext-rij-aanvaard   { border-left-color: var(--green); }
.ext-rij-geweigerd  { border-left-color: var(--red-knop); }
.ext-rij-uitgevoerd { border-left-color: var(--muted); }

.ext-rij-kop  { font-size: .9rem; }
.ext-rij-tekst {
    font-size: .85rem;
    color: var(--text-muted);
    margin-top: .15rem;
    white-space: pre-wrap;
}
.ext-rij-voet {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    margin-top: .4rem;
    flex-wrap: wrap;
}

.ext-blok {
    display: inline-block;
    margin-left: .4rem;
    padding: .05rem .4rem;
    border-radius: 4px;
    background: var(--orange-soft, #fdf5e6);
    color: var(--orange-tekst);
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.ext-stand { font-size: .83rem; font-weight: 600; }
.ext-stand-ok    { color: var(--green-tekst); }
.ext-stand-wacht { color: var(--orange-tekst); }
.ext-stand-nee   { color: var(--red-tekst); font-weight: 500; }
.ext-stand-klaar { color: var(--muted-leesbaar); }

.ext-knop-vraag { align-self: flex-start; margin-top: .2rem; }

/* De afmeldknop stond ongestyled in de kaart: in het donkere thema een
 * lichtgrijs blokje. Klein, rustig, en met genoeg contrast in beide thema's. */
.ext-rij .btn-mini {
    padding: .2rem .6rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--card);
    color: var(--text);
    font-size: .78rem;
    font-family: inherit;
    cursor: pointer;
}
.ext-rij .btn-mini:hover { background: var(--bg); }

/* Het chassisnummer op een werkbalkje in de agenda: apart, maar rustig — de
 * eigenaar wil die zes cijfers overal snel zien, niet luid. */
.ag-werkje-kenmerk {
    margin-left: .35rem;
    padding-left: .35rem;
    border-left: 1px solid var(--border);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: .92em;
    opacity: .85;
}

/* ==========================================================================
 *  HET CHASSISNUMMER OP DE TABLET
 *
 *  Drie foto's in plaats van één. De vakjes tellen af zodat de inspecteur ziet
 *  hoeveel er nog moet, en het gelezen nummer staat groot en in een vaste
 *  letterbreedte — hij moet het teken voor teken kunnen vergelijken met wat er
 *  op de wagen staat.
 * ========================================================================== */

.chassis-uitleg {
    background: var(--bg);
    border-left: 3px solid var(--gold);
    border-radius: 0 8px 8px 0;
    padding: .8rem 1rem;
    margin-bottom: 1rem;
    font-size: .88rem;
    line-height: 1.55;
}
.chassis-uitleg ul { margin: .4rem 0 0 1.1rem; padding: 0; }
.chassis-uitleg li { margin-bottom: .2rem; }
.chassis-waarom {
    margin-top: .6rem;
    font-size: .83rem;
    color: var(--muted-leesbaar);
}

.chassis-kaart {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1rem;
}

.chassis-fotos { display: flex; gap: .6rem; margin-bottom: .9rem; }
.chassis-vakje {
    width: 3.2rem;
    height: 3.2rem;
    border: 2px dashed var(--border);
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--muted-leesbaar);
}
.chassis-vakje-vol {
    border-style: solid;
    border-color: var(--green);
    color: var(--green-tekst);
    background: var(--green-soft);
}

.chassis-uitslag {
    border-radius: 10px;
    padding: .9rem 1rem;
    border-left: 4px solid var(--border);
    background: var(--bg);
}
.chassis-zeker   { border-left-color: var(--green); }
.chassis-twijfel { border-left-color: var(--gold); }

.chassis-label {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--muted-leesbaar);
}
.chassis-nummer {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 1.45rem;
    font-weight: 700;
    letter-spacing: .06em;
    word-break: break-all;
    margin: .1rem 0 .4rem 0;
}
.chassis-reden { font-size: .88rem; line-height: 1.5; }
.chassis-let-op {
    margin-top: .5rem;
    padding: .45rem .6rem;
    background: var(--orange-soft);
    color: var(--orange-tekst);
    border-radius: 6px;
    font-size: .85rem;
    font-weight: 600;
}
.chassis-match { margin-top: .5rem; font-size: .87rem; color: var(--green-tekst); }
.chassis-match-geen { color: var(--muted-leesbaar); }

.chassis-knoppen { display: flex; gap: .5rem; margin-top: .9rem; flex-wrap: wrap; }

.chassis-handmatig {
    margin-top: 1.2rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
}
.chassis-handmatig p { color: var(--muted-leesbaar); font-size: .87rem; }
.chassis-handmatig input {
    width: 100%;
    padding: .7rem;
    font-size: 16px;              /* onder 16px zoomt iOS in bij het tikken */
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    text-transform: uppercase;
    letter-spacing: .06em;
    border: 1px solid var(--border);
    border-radius: 8px;
    margin-bottom: .5rem;
}
.verborgen { display: none; }

/* De opdracht bij de volgende foto. Drie keer dezelfde foto geeft drie keer
   dezelfde leesfout, dus staat er bij elke foto wat er anders moet. */
.chassis-vakjes { display: flex; gap: .6rem; margin-bottom: .7rem; }
.chassis-vakje-nu {
    border-color: var(--gold);
    color: var(--gold);
    box-shadow: 0 0 0 3px rgba(133, 117, 78, .15);
}
.chassis-opdracht {
    background: var(--card);
    border: 1px solid var(--border);
    border-left: 3px solid var(--gold);
    border-radius: 0 8px 8px 0;
    padding: .6rem .8rem;
    margin-bottom: .9rem;
}
.chassis-opdracht-kop {
    font-weight: 700;
    font-size: .92rem;
    margin-bottom: .15rem;
}
.chassis-opdracht-tekst {
    font-size: .86rem;
    line-height: 1.5;
    color: var(--text-muted);
}

/* ==========================================================================
 *  DE HULPKNOP
 *
 *  Rechtsonder, naast de chat. Klein en rustig: hij mag opvallen als je hem
 *  zoekt, maar niet in de weg zitten als je aan het werk bent.
 * ========================================================================== */

.hulp-knop {
    position: fixed;
    right: 1.1rem;
    bottom: 5.6rem;                 /* boven de chatknop */
    width: 2.9rem;
    height: 2.9rem;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--gold);
    font-size: 1.35rem;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(15, 23, 42, .14);
    z-index: var(--laag-knoppen, 9992);
}
.hulp-knop:hover { background: var(--bg); }

.hulp-venster {
    position: fixed;
    right: 1.1rem;
    bottom: 9.2rem;
    width: min(23rem, calc(100vw - 2.2rem));
    max-height: min(28rem, calc(100vh - 12rem));
    display: flex;
    flex-direction: column;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 8px 30px rgba(15, 23, 42, .18);
    z-index: var(--laag-panelen, 9994);
    overflow: hidden;
}

.hulp-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: .7rem .9rem;
    background: var(--midnight, #05141E);
    color: #fff;
    font-weight: 600;
    font-size: .95rem;
}
.hulp-sluit {
    background: none;
    border: none;
    color: #fff;
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    opacity: .8;
}
.hulp-sluit:hover { opacity: 1; }

.hulp-inhoud {
    flex: 1;
    overflow-y: auto;
    padding: .8rem .9rem;
    font-size: .88rem;
    line-height: 1.55;
}
.hulp-welkom { color: var(--muted-leesbaar); margin: 0 0 .6rem 0; }
.hulp-voorbeelden { display: flex; flex-direction: column; gap: .35rem; }
.hulp-voorbeelden button {
    text-align: left;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: .45rem .6rem;
    font-size: .85rem;
    font-family: inherit;
    color: var(--text);
    cursor: pointer;
}
.hulp-voorbeelden button:hover { border-color: var(--gold); }

.hulp-vraag-blok {
    background: var(--bg);
    border-radius: 10px 10px 2px 10px;
    padding: .5rem .7rem;
    margin: .5rem 0 .3rem auto;
    max-width: 85%;
    width: fit-content;
    font-weight: 600;
}
.hulp-antwoord {
    border-left: 3px solid var(--gold);
    padding: .5rem .7rem;
    margin-bottom: .7rem;
    white-space: pre-wrap;
}
.hulp-bezig { color: var(--muted-leesbaar); font-style: italic; }
.hulp-antwoord-onbekend { border-left-color: var(--orange-tekst); }
.hulp-antwoord-fout { border-left-color: var(--red-knop); color: var(--red-tekst); }

.hulp-onder {
    display: flex;
    gap: .4rem;
    padding: .6rem .7rem;
    border-top: 1px solid var(--border);
}
.hulp-onder textarea {
    flex: 1;
    resize: none;
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: .45rem .55rem;
    font-family: inherit;
    font-size: 16px;              /* onder 16px zoomt iOS in bij het tikken */
    background: var(--card);
    color: var(--text);
}

@media (max-width: 640px) {
    .hulp-venster { bottom: 8.4rem; max-height: calc(100vh - 11rem); }
}

/* ===========================================================================
   DE DIEPTELAAG — glas, licht en beweging
   ===========================================================================

   De eigenaar (7-8-2026): *"kijk als designer naar SalesSync en bekijk of het
   wel modern en professioneel gestyled is. Ik wil dat het een motiverend
   kleurenpalet is dat ook rust geeft, maar aan de andere kant cutting edge
   lijkt. Ik vind animaties leuk van knoppen en hovers, glass design."*

   WAT ER MIS WAS — GEMETEN, NIET GEVOELD
   --------------------------------------
   Het palet zelf klopt: diep marineblauw (#0a1421), goud (#c4a862), rustige
   pasteltinten voor de statussen, en elk contrast is eerder nagemeten. Daar
   blijf ik af.

   Wat er niet klopte, is de DIEPTE. Elke kaart droeg
   `box-shadow: 0 1px 4px rgba(0,0,0,.06)`. Dat is een lichte-modus-schaduw:
   zwart op wit werkt, zwart op #0a1421 is letterlijk onzichtbaar. Gevolg: alle
   vlakken lagen even hoog, en een scherm zonder hoogteverschil oogt plat, hoe
   goed de kleuren ook zijn. Dat is precies het verschil tussen "nette kleuren"
   en "modern".

   In het donker maak je hoogte niet met schaduw maar met LICHT: hoe hoger een
   vlak ligt, hoe meer licht het vangt. Vandaar hieronder een randje licht
   bovenaan elk verhoogd vlak, plus een schaduw die diep genoeg is om op donker
   wel te lezen.

   DRIE REGELS DIE IK MEZELF OPGELEGD HEB
   --------------------------------------
   1. GEEN kleur van een tekst of een status veranderen. Die contrasten zijn
      stuk voor stuk nagemeten en staan met hun verhouding in dit bestand.
      Wat hier gebeurt is diepte, glas en beweging — nooit betekenis.
   2. Glas alleen waar iets OVER de inhoud ligt: de topbalk, de zijbalk, een
      venster, een uitklaplijst. Glas op een gewone kaart is versiering en kost
      alleen maar rekenkracht op een tablet.
   3. Beweging is kort (60-220 ms) en gaat een kant op: iets komt naar je toe
      als je het aanwijst. Nooit stuiteren, nooit draaien. En wie in Windows
      "animaties verminderen" aanzet, krijgt niets van dit alles — zie onderaan.
   =========================================================================== */

:root {
    /* De hoogtes. Elk niveau = meer licht bovenaan + een diepere schaduw. */
    --diepte-1: 0 1px 2px rgba(0,0,0,.28), inset 0 1px 0 rgba(255,255,255,.04);
    --diepte-2: 0 4px 14px rgba(0,0,0,.34), inset 0 1px 0 rgba(255,255,255,.055);
    --diepte-3: 0 12px 34px rgba(0,0,0,.44), inset 0 1px 0 rgba(255,255,255,.07);
    /* De gouden gloed van het huis. Alleen bij aanwijzen en bij focus. */
    --gloed-goud: 0 0 0 1px rgba(196,168,98,.34), 0 6px 20px rgba(196,168,98,.13);
    /* Een ronding-ritme: klein voor knoppen, groot voor vlakken. */
    --rond-klein: 8px;
    --rond-groot: 14px;
    --veer: cubic-bezier(.22,.61,.36,1);
}

/* In het lichte thema hoort een zwarte schaduw wel; daar blijft alles zoals het
   was, alleen wat verfijnd. */
:root[data-theme="light"] {
    --diepte-1: 0 1px 2px rgba(5,20,30,.06);
    --diepte-2: 0 4px 14px rgba(5,20,30,.09);
    --diepte-3: 0 12px 34px rgba(5,20,30,.14);
    --gloed-goud: 0 0 0 1px rgba(133,117,78,.35), 0 6px 20px rgba(133,117,78,.14);
}


/* ===========================================================================
   DE ZWEVENDE LAAG — één afgesproken volgorde
   ===========================================================================

   Alles wat OVER de inhoud heen komt, staat hier op volgorde. Losse getallen
   verspreid over het bestand leveren precies de fouten op die we op 10-8-2026
   gevonden hebben:

   - de meldingenlijst lag achter de dashboardkaarten (glas op de topbalk maakte
     een eigen stapel, en de balk zelf stond nergens);
   - Nova lag achter het chatvenster (900 tegen 9999) en wie op haar drukte,
     opende de chat;
   - de topbalk-fix schilderde daarna over het uitschuifmenu op een gsm;
   - Nova's PANEEL bedekte de hulpknop voor 96%, want bij het uitrekenen van de
     knoppenkolom was het paneel vergeten.

   Vier fouten, één oorzaak: er was geen afgesproken volgorde. Vandaar deze.

   WIE HIER IETS BIJZET: neem een nummer uit deze lijst, en meet het na op een
   gsm-breedte én op een breed scherm. Twee elementen op elkaar zie je niet in
   de code.
   =========================================================================== */
:root {
    --laag-topbalk:        1100;   /* de balk met glas; draagt bel en zoeker   */
    --laag-menu-waas:      1250;   /* het grijze waas achter het gsm-menu      */
    --laag-menu:           1300;   /* het uitschuifmenu zelf                   */
    --laag-chat:           9990;   /* het chatvenster                          */
    --laag-knoppen:        9992;   /* hulpknop en Nova: altijd bereikbaar      */
    --laag-panelen:        9994;   /* wat die twee knoppen openen              */
    /* de modal blijft op 10001 — die hoort boven alles, ook boven de chat */
}

/* --- Vlakken krijgen hoogte ------------------------------------------- */

.adm-card, .kpi-card, .card, .table-wrap, .aankoop-card {
    border-radius: var(--rond-groot);
    box-shadow: var(--diepte-1);
    transition: transform .18s var(--veer), box-shadow .18s var(--veer);
}

/* Alleen wat je kunt aanklikken komt omhoog. Een kaart die je niet kunt openen
   en toch beweegt, belooft iets dat er niet is. */
.adm-card[onclick]:hover, .kpi-card[onclick]:hover, .card[onclick]:hover,
.dash-klikbaar:hover {
    transform: translateY(-2px);
    box-shadow: var(--diepte-2);
}

/* --- Glas, alleen waar iets over de inhoud ligt ------------------------ */

.topbar {
    background: color-mix(in srgb, var(--card) 78%, transparent);
    backdrop-filter: blur(14px) saturate(1.25);
    -webkit-backdrop-filter: blur(14px) saturate(1.25);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--diepte-1);

    /* HET GLAS MAAKTE DE MELDINGEN ONLEESBAAR (gemeld 10-8-2026).
     *
     * `backdrop-filter` maakt een NIEUWE STAPELCONTEXT. Alles wat in de
     * topbalk zit -- de meldingsbel en zijn uitklaplijst -- zit daarmee
     * opgesloten in die context. De `z-index: 1200` van .notif-dropdown telt
     * dan alleen nog BINNEN de topbalk, en niet meer tegenover de rest van de
     * pagina.
     *
     * En de topbalk zelf stond op `position: static` zonder z-index, dus
     * gewoon in de gewone volgorde. Gevolg: de kaarten van het dashboard --
     * die later in de pagina komen -- schilderden over de uitklaplijst heen,
     * en de meldingen waren half onleesbaar.
     *
     * Gemeten in de browser: de bel had precies EEN voorouder die een
     * stapelcontext maakte, en dat was deze regel met backdrop-filter.
     *
     * De balk krijgt daarom een eigen plaats in de stapel, hoger dan de
     * inhoud. Dat is de prijs van glas: wie een stapelcontext maakt, moet ook
     * zeggen waar die staat. */
    position: relative;
    z-index: 1100;
}

/* `[data-theme="dark"] .sidebar` staat verderop en is specifieker dan een kale
   .sidebar, dus die won en de zijbalk bleef ondoorzichtig — het glas deed dan
   niets. Nagemeten in de browser. Vandaar dezelfde specificiteit hier. */
[data-theme="dark"] .sidebar,
:root:not([data-theme="dark"]) .sidebar {
    background: color-mix(in srgb, var(--sidebar) 92%, transparent);
    backdrop-filter: blur(18px) saturate(1.2);
    -webkit-backdrop-filter: blur(18px) saturate(1.2);
}

/* Een browser die color-mix niet kent, valt hierop terug: gewoon de volle
   kleur. Dan is er geen glas, maar wel een leesbaar scherm. */
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
    .topbar { background: var(--card); }
    .sidebar { background: var(--sidebar); }
}

.modal-content, .notif-dropdown, .hulp-venster {
    border-radius: var(--rond-groot);
    box-shadow: var(--diepte-3);
    backdrop-filter: blur(16px) saturate(1.2);
    -webkit-backdrop-filter: blur(16px) saturate(1.2);
}

/* --- Knoppen: een ritme, en beweging die een kant op gaat -------------- */

.btn, button.btn, .btn-primary, .btn-sm, .btn-export {
    border-radius: var(--rond-klein);
    /* `transition: all` stond hier. Dat animeert ook wat je niet bedoelt —
       breedtes, de kleur van een tabelrand — en dat kost beeldjes op een
       tablet. Alleen wat we echt bewegen. */
    transition: transform .14s var(--veer), box-shadow .14s var(--veer),
                background-color .14s ease, border-color .14s ease, opacity .14s ease;
}

.btn:hover:not(:disabled), .btn-primary:hover:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: var(--diepte-2);
}

/* Indrukken geeft antwoord. Op een tablet is dat het enige teken dat je
   aanraking aangekomen is — daar bestaat geen hover. */
.btn:active:not(:disabled), .btn-primary:active:not(:disabled) {
    transform: translateY(0) scale(.985);
    box-shadow: var(--diepte-1);
    transition-duration: .06s;
}

.btn:disabled { opacity: .55; }

/* --- Zichtbaar waar je bent ------------------------------------------- */

/* Er stond nergens een focusring die op donker leesbaar was. Wie met tab werkt
   — of met een toetsenbord op de werkvloer — zag niet waar hij stond. */
.btn:focus-visible, button:focus-visible, a:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
.dash-klikbaar:focus-visible, [role="button"]:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
    box-shadow: var(--gloed-goud);
}

/* --- De zijbalk: waar je bent, zonder schreeuwen ----------------------- */

.sidebar nav a {
    border-radius: var(--rond-klein);
    transition: background-color .16s ease, color .16s ease, transform .16s var(--veer);
}
.sidebar nav a:hover { transform: translateX(2px); }

/* De actieve pagina krijgt een gouden streepje links in plaats van een vlak.
   Dezelfde afspraak als bij de rijen: de linkerrand is de aanwijzer, niet de
   achtergrond. */
.sidebar nav a.active {
    position: relative;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--gold) 16%, transparent), transparent 62%);
}
.sidebar nav a.active::before {
    content: "";
    position: absolute;
    left: 0; top: 18%; bottom: 18%;
    width: 3px;
    border-radius: 0 3px 3px 0;
    background: var(--gold);
}

/* --- Tabellen: rustig, en de rij waar je op staat licht op ------------- */

table tbody tr { transition: background-color .12s ease; }
table tbody tr:hover {
    /* Geen kleurvlak: een spoortje licht. Gekleurde rij-achtergronden zijn hier
       uitdrukkelijk niet gewenst. */
    background: rgba(255,255,255,.028);
}
:root[data-theme="light"] table tbody tr:hover { background: rgba(5,20,30,.028); }

/* --- Wat binnenkomt, komt rustig binnen ------------------------------- */

@keyframes ss-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}
#content > * { animation: ss-in .22s var(--veer) both; }

/* --- En voor wie liever geen beweging heeft ---------------------------
 *
 * LET OP DE `html:not(.beweging-aan)` — DIE IS ER NIET VOOR NIETS (12-8-2026)
 * ==========================================================================
 * Dit blok stond hier eerst zonder die voorwaarde: een universele
 * `*, *::before, *::after { ... !important }` onder `prefers-reduced-motion`.
 * Dat is de standaardformule die overal rondgaat, en ze klopt niet voor ons.
 *
 * `prefers-reduced-motion: reduce` staat namelijk óók aan zodra iemand in
 * Windows gewoon "animaties weergeven" uitzet. Dat is de STANDAARD op een
 * Windows-server, en op een kantoor-pc zet men het uit voor de snelheid — niet
 * omdat men er misselijk van wordt. Gemeten op 12-8-2026: op deze machines
 * stond het op true.
 *
 * Gevolg: élke overgang in heel SalesSync werd platgeslagen. Geen hover die
 * meegeeft, geen paneel dat opent, geen tegel die omhoogkomt. Het programma
 * voelde daardoor dood aan, en niemand legde het verband met een vinkje in het
 * configuratiescherm. Nova stond om exact dezelfde reden stil.
 *
 * Nu geldt: de systeemvoorkeur blijft het uitgangspunt, maar een UITDRUKKELIJKE
 * keuze van de gebruiker in SalesSync wint. Zet hij beweging aan, dan krijgt
 * <html> de klasse `beweging-aan` en slaat dit blok over. Zet hij ze uit, dan
 * komt `beweging-uit` erop en staat alles stil, wat het systeem ook zegt.
 * De keuze van een mens gaat vóór de gok van een instelling.
 */

@media (prefers-reduced-motion: reduce) {
    html:not(.beweging-aan) *,
    html:not(.beweging-aan) *::before,
    html:not(.beweging-aan) *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
    html:not(.beweging-aan) .btn:hover,
    html:not(.beweging-aan) .adm-card[onclick]:hover,
    html:not(.beweging-aan) .dash-klikbaar:hover,
    html:not(.beweging-aan) .sidebar nav a:hover { transform: none; }
}

/* Uitdrukkelijk uitgezet: dan staat alles stil, ook op een machine die niets
   over bewegingsvoorkeur zegt. */
html.beweging-uit *,
html.beweging-uit *::before,
html.beweging-uit *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
}
html.beweging-uit .btn:hover,
html.beweging-uit .adm-card[onclick]:hover,
html.beweging-uit .dash-klikbaar:hover,
html.beweging-uit .sidebar nav a:hover { transform: none; }

/* ===========================================================================
   DE MASCOTTE
   ===========================================================================
   Rechtsonder, klein, van glas. Wie werkt moet kunnen werken: een mascotte die
   in de weg staat wordt na twee dagen weggeklikt en nooit meer geopend.

   Het gezicht is met CSS getekend en niet met een plaatje. Twee redenen: het
   schaalt mee met elk scherm zonder wazig te worden, en het volgt vanzelf het
   goud van het huis als dat ooit verandert.
   =========================================================================== */

/* NOVA LAG ACHTER HET CHATVENSTER (gemeten 10-8-2026).
 *
 * Rechtsonder zweven er DRIE knoppen: de chat (bottom 20px, z-index 9999), de
 * hulpknop (bottom 89,6px, z-index 900) en Nova. Nova stond op bottom 12,8px
 * met z-index 900 en overlapte de chat dus met 38 pixels -- en verloor, want
 * 900 is minder dan 9999.
 *
 * Gemeten met elementFromPoint op het midden van haar knop: daar lag de chat
 * overheen. Wie op Nova drukte, opende de chat.
 *
 * De drie staan nu als een kolom boven elkaar met dezelfde rechterkant:
 *   chat    bottom 20px   (blijft onderaan, die zit er het langst)
 *   hulp    bottom 89,6px
 *   Nova    bottom 160px
 *
 * Wie hier een vierde zwevende knop bijzet: neem het volgende vak, en meet het
 * na. Drie knoppen op elkaar merk je niet in de code, alleen op het scherm. */
.mascotte-knop {
    position: fixed;
    right: 20px;
    bottom: 160px;
    z-index: var(--laag-knoppen, 9992);
    /* 50% groter op vraag van de eigenaar (12-8-2026): op 34px was de
       robot met zijn cape en antennes niet te herkennen. */
    width: 80px;
    height: 80px;
    border-radius: 50%;
    border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
    background: color-mix(in srgb, var(--card) 82%, transparent);
    backdrop-filter: blur(14px) saturate(1.3);
    -webkit-backdrop-filter: blur(14px) saturate(1.3);
    box-shadow: var(--diepte-2);
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: transform .18s var(--veer), box-shadow .18s var(--veer);
}
.mascotte-knop:hover { transform: translateY(-2px) scale(1.04); box-shadow: var(--diepte-3); }
.mascotte-knop:active { transform: scale(.96); }

/* Het gezicht: een gouden ring met twee ogen en een glimlach. */
.mascotte-gezicht {
    position: relative;
    width: 30px; height: 30px;
    border-radius: 50%;
    background: radial-gradient(circle at 32% 28%,
        color-mix(in srgb, var(--gold) 85%, white), var(--gold) 62%,
        color-mix(in srgb, var(--gold) 70%, black) 100%);
    box-shadow: 0 0 14px color-mix(in srgb, var(--gold) 45%, transparent);
}
.mascotte-gezicht.klein { width: 26px; height: 26px; }
.mascotte-gezicht::before {
    /* de twee ogen */
    content: "";
    position: absolute; left: 22%; top: 34%;
    width: 4px; height: 4px; border-radius: 50%;
    background: var(--midnight, #05141E);
    box-shadow: 10px 0 0 var(--midnight, #05141E);
}
.mascotte-gezicht::after {
    /* de glimlach */
    content: "";
    position: absolute; left: 30%; top: 55%;
    width: 40%; height: 20%;
    border-bottom: 2px solid var(--midnight, #05141E);
    border-radius: 0 0 40% 40%;
}

/* Hij knippert af en toe. Eén keer per acht seconden, meer niet -- anders
   trekt hij de aandacht weg van het werk. */
@keyframes mascotte-knipper {
    0%, 92%, 100% { transform: scaleY(1); }
    95%           { transform: scaleY(.1); }
}
/* Vier keer knipperen na het openen van een scherm, en bij hover nog twee
   keer. Daarna stil. Die knop staat op ELK scherm de hele dag in beeld;
   eeuwig knipperen wordt een tic in je ooghoek. */
.mascotte-knop .mascotte-gezicht::before { animation: mascotte-knipper 8s 4; }
.mascotte-knop:hover .mascotte-gezicht::before { animation: mascotte-knipper 8s 2; }

/* Het rode stipje: er staat iets over tijd. Klein en zonder beweging -- een
   knipperend rood bolletje is precies het soort ding waar mensen zenuwachtig
   van worden. */
.mascotte-stip {
    position: absolute;
    right: 6px; top: 6px;
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--red, #dd9488);
    border: 2px solid var(--card);
}

.mascotte-paneel {
    position: fixed;
    right: 20px;
    /* Boven de knoppenkolom (Nova zit op 160px en is 54px hoog), niet
     * erdoorheen. Op 5rem bedekte dit paneel 96% van de hulpknop. */
    bottom: 224px;
    z-index: var(--laag-panelen, 9994);
    width: min(340px, calc(100vw - 2.4rem));
    max-height: min(70vh, 560px);
    overflow-y: auto;
    padding: 1rem 1.1rem 1.1rem;
    border-radius: var(--rond-groot, 14px);
    border: 1px solid var(--border);
    background: color-mix(in srgb, var(--card) 88%, transparent);
    backdrop-filter: blur(20px) saturate(1.3);
    -webkit-backdrop-filter: blur(20px) saturate(1.3);
    box-shadow: var(--diepte-3);
    animation: mascotte-op .22s var(--veer, ease) both;
}
@keyframes mascotte-op {
    from { opacity: 0; transform: translateY(10px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.mascotte-kop { display: flex; align-items: center; gap: .6rem; margin-bottom: .7rem; }
.mascotte-groet { font-weight: 700; font-size: 1rem; color: var(--text); }
.mascotte-naam { font-size: .72rem; color: var(--muted-leesbaar); text-transform: uppercase; letter-spacing: .06em; }
.mascotte-sluit {
    margin-left: auto; background: none; border: none; cursor: pointer;
    font-size: 1.4rem; line-height: 1; color: var(--muted-leesbaar); padding: 0 .2rem;
}
.mascotte-sluit:hover { color: var(--text); }

.mascotte-werk { font-size: .9rem; color: var(--text); margin: 0 0 .3rem; }
.mascotte-aanmoediging { font-size: .86rem; color: var(--muted-leesbaar); margin: 0 0 .8rem; font-style: italic; }

.mascotte-eerste {
    display: block; width: 100%; text-align: left;
    padding: .6rem .7rem; margin-bottom: .8rem;
    border-radius: var(--rond-klein, 8px);
    border: 1px solid var(--border);
    border-left: 3px solid var(--gold);
    background: color-mix(in srgb, var(--gold) 7%, transparent);
    cursor: pointer; color: inherit; font-family: inherit;
    transition: transform .14s var(--veer, ease), background-color .14s ease;
}
.mascotte-eerste:hover { transform: translateX(2px); background: color-mix(in srgb, var(--gold) 12%, transparent); }
.mascotte-eerste-label { display: block; font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--gold); }
.mascotte-eerste-titel { display: block; font-weight: 600; font-size: .88rem; margin: .1rem 0; }
.mascotte-eerste-tekst { display: block; font-size: .78rem; color: var(--muted-leesbaar); }

.mascotte-vraagblok { display: flex; gap: .4rem; margin-top: .6rem; }
.mascotte-vraagblok input {
    flex: 1; padding: .45rem .6rem;
    border: 1px solid var(--border); border-radius: var(--rond-klein, 8px);
    background: var(--bg); color: var(--text);
    font-family: inherit; font-size: 16px;   /* onder 16px zoomt iOS in */
}

.mascotte-duwknop {
    display: block; width: 100%; margin-top: .5rem;
    padding: .4rem; border: 1px dashed var(--border); border-radius: var(--rond-klein, 8px);
    background: none; color: var(--muted-leesbaar); cursor: pointer;
    font-family: inherit; font-size: .8rem;
    transition: color .14s ease, border-color .14s ease;
}
.mascotte-duwknop:hover { color: var(--gold); border-color: var(--gold); }

.mascotte-bubbel {
    margin: .6rem 0; padding: .65rem .75rem;
    border-radius: var(--rond-klein, 8px);
    border-left: 3px solid var(--gold);
    background: color-mix(in srgb, var(--gold) 7%, transparent);
    font-size: .88rem; line-height: 1.5; color: var(--text);
}
.mascotte-denkt { font-size: .84rem; color: var(--muted-leesbaar); margin: .6rem 0; }
.mascotte-uit { font-size: .8rem; color: var(--muted-leesbaar); margin: .6rem 0 0; }

.mascotte-duw { display: grid; gap: .5rem; margin: .6rem 0; }
.mascotte-duw label { font-size: .78rem; color: var(--muted-leesbaar); display: grid; gap: .2rem; }
.mascotte-duw input, .mascotte-duw select {
    padding: .4rem .5rem; border: 1px solid var(--border);
    border-radius: var(--rond-klein, 8px);
    background: var(--bg); color: var(--text);
    font-family: inherit; font-size: 16px;
}
.mascotte-optioneel { font-size: .72rem; color: var(--muted-leesbaar); margin: 0; }

/* Op een gsm gaat hij iets kleiner en schuift hij weg van de duim-zone.
 *
 * LET OP: deze regel overschreef de kolomvolgorde hierboven en zette Nova
 * terug op bottom .8rem -- precies bovenop het chatvenster. Gemeten op een
 * scherm van 620px: haar knop lag onder de chat en wie op haar drukte, opende
 * de chat.
 *
 * De kolom moet dus OOK hier staan. De knoppen zijn op een gsm kleiner, dus de
 * afstanden zijn krapper, maar de volgorde blijft: chat onderaan, dan hulp,
 * dan Nova. */
@media (max-width: 640px) {
    .mascotte-knop { width: 68px; height: 68px; right: 14px; bottom: 148px; }
    .mascotte-gezicht { width: 26px; height: 26px; }
    .mascotte-paneel { right: .8rem; left: .8rem; bottom: 202px; width: auto; }
}

@media (prefers-reduced-motion: reduce) {
    html:not(.beweging-aan) .mascotte-knop .mascotte-gezicht::before { animation: none; }
    html:not(.beweging-aan) .mascotte-paneel { animation: none; }
}


/* --- Het scherm van de externe leverancier ----------------------------- */
/* Zijn enige scherm. Groot genoeg voor een telefoon met werkhandschoenen aan:
   dat is waar hij het opent, naast de wagen. */

.ext-lijst { display: flex; flex-direction: column; gap: .7rem; }

.ext-telling {
    display: inline-block; min-width: 1.5rem; padding: 0 .45rem;
    border-radius: 999px; background: var(--accent); color: #0a1421;
    font-size: .8rem; font-weight: 700; text-align: center; vertical-align: middle;
}

.ext-rij .btn-sm { margin-left: auto; }

/* De strook in het meldingenpaneel als de lijst niet ververst raakte (S5).
   Zie core.js refreshNotificatiePaneel: de cache blijft staan, want die zeven
   meldingen die er al stonden waren echt. */
.notif-laadfout {
    border-left: 3px solid var(--red-knop);
    background: var(--card);
    color: var(--text);
    padding: .55rem .8rem;
    font-size: .82rem;
    line-height: 1.45;
    border-bottom: 1px solid var(--border);
}

/* Een veld waarvan het bewaren mislukte (S9, 11-8-2026).
   De tekst blijft staan — dat is met opzet, zodat je hem kunt kopiëren — maar
   hij mag er niet bewaard uitzien. */
.veld-niet-bewaard {
    border-color: var(--red-knop) !important;
    box-shadow: 0 0 0 2px rgba(193, 123, 110, .25);
}

/* =============================================================
   NOVA — HET GEZICHT DAT LEEFT (11-8-2026)
   =============================================================

   De eigenaar: "zal nova ook bewegen? want nu zie ik gewoon een gezichtje."

   Wat hier staat is de beweging die GEEN JavaScript nodig heeft: ademen en de
   overgangen. Alles wat onvoorspelbaar moet zijn — knipperen, kijken,
   rondkijken — staat in nova.js, want een CSS-animatie is per definitie
   voorspelbaar en dat is precies wat een gezicht dood maakt.

   Kleuren volgen het huisgoud, in beide thema's nagemeten.
   ============================================================= */
:root {
    /* DE KLEUREN VAN HET ONTWERP (Claude Design, 12-8-2026).
       Nova is een witte robot met een gouden cape en cyaan gloed — niet meer
       het gouden gezichtje van de eerste versie. De namen blijven dezelfde,
       zodat de rest van de stylesheet niets merkt. */
    --nova-mid:         #e9eef4;  /* wit schild */
    --nova-licht:       #ffffff;  /* glans */
    --nova-donker:      #bcc7d4;  /* schaduw, groeven */
    --nova-trek:        #0e1a2e;  /* vizier, lijnen */
    --nova-kleding:     #16233c;  /* navy gewrichten, borstplaat */
    --nova-schoen:      #0b1424;  /* zool */
    --nova-goud:        #c9a227;  /* kroon, cape, ringen, laarsbanden, naam */
    --nova-goud-licht:  #e0bd52;  /* glans op goud */
    --nova-goud-donker: #a8842a;  /* achterste capepaneel */
    --nova-glow:        #35c6ff;  /* ogen, mond, kern, vonken */
}
/* Geen aparte donkere variant meer: het ontwerp is al voor de
   donkere achtergrond van SalesSync (#0d1a26) getekend. */

.nova-svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* HIER STAAN GEEN KLEUREN, EN DAT IS MET REDEN (12-8-2026)
   ========================================================
   Het ontwerpdossier van Nova is high-fidelity: "Kleuren, verhoudingen en
   timings zijn definitief. Het figuur moet 1-op-1 overgenomen worden." Alle
   kleur zit daarom in de presentatie-attributen van de SVG zelf — zie novaSVG()
   in static/js/nova.js — en niet in deze stylesheet.

   Waarom dat zo scherp staat: CSS wint van een presentatie-attribuut. Er stonden
   hier nog drie blokken van mijn eigen, vervangen tekening (.nova-wb, .nova-mond
   en .nova-blos). Die overschreven het ontwerp zonder iets stuk te maken dat een
   test opmerkte: mond en wenkbrauwen kregen var(--nova-trek), exact de kleur van
   het vizier waar ze bovenop liggen. Contrast 1.00:1 — ze stonden er wel, maar
   je zag ze niet. De eigenaar zag het meteen: "ik zie geen mond?"

   Zet hier dus geen fill, stroke, stroke-width, opacity of d bij. Moet er een
   kleur wijzigen, wijzig ze in novaSVG(). test_geen_css_overschrijft_het_ontwerp
   in app/tests/test_nova_leeft.py bewaakt dit.

   Wat wel via CSS gaat — en wat het dossier ook precies zo voorschrijft — zijn
   de vier regels hieronder. De rest van de beweging (ademen, zweven, zwaaien,
   knipperen, de high five) zet nova.js op het transform-ATTRIBUUT, omdat CSS
   transform-origin onbetrouwbaar is binnen <use> en shadow-trees en de zwaaiende
   arm uit beeld zwiepte. */
.nova { display: block; }
.nova-pupil, .nova-vonk { transition: transform .2s cubic-bezier(.22,.61,.36,1); }
.nova-wb   { transition: transform .32s cubic-bezier(.22,.61,.36,1); }
.nova-mond { transition: d .28s ease; }

/* WIE GEEN BEWEGING WIL, KRIJGT ZE NIET — MAAR WIE ZE WÉL WIL OOK NIET (12-8-2026)
   ================================================================================
   De systeemvoorkeur blijft gelden. Voor wie last heeft van bewegende dingen op
   een scherm is een ademend mannetje in de hoek geen leuk detail maar een reden
   om weg te klikken.

   Alleen: die voorkeur staat óók aan zodra iemand in Windows gewoon "animaties
   weergeven" uitzet — standaard op een server. Gemeten op 12-8:
   prefers-reduced-motion stond op true, en Nova stond doodstil terwijl niemand
   het verband legde met een vinkje in het configuratiescherm.

   Vandaar de uitweg: zet de gebruiker het in SalesSync uitdrukkelijk aan, dan
   krijgt <html> de klasse `nova-beweegt` en wint die van de systeemvoorkeur.
   Zet hij het uit, dan komt `nova-stil` erop en staat alles stil, wat het
   systeem ook zegt. De keuze van een mens gaat vóór de gok van een instelling. */
@media (prefers-reduced-motion: reduce) {
    /* De beweging zelf staat in nova.js en kijkt naar de keuze van de
       gebruiker (_novaMagBewegen). Hier blijven alleen de overgangen over. */
    html:not(.nova-beweegt) .nova-pupil,
    html:not(.nova-beweegt) .nova-vonk,
    html:not(.nova-beweegt) .nova-wb,
    html:not(.nova-beweegt) .nova-mond { transition: none; }
}

html.nova-stil .nova-pupil,
html.nova-stil .nova-vonk,
html.nova-stil .nova-wb,
html.nova-stil .nova-mond { transition: none; }

/* --- HET AANBOD OM TE ADEMEN --- */
.nova-aanbod {
    border-left: 3px solid var(--gold);
    background: var(--hover-bg, rgba(0,0,0,.03));
    border-radius: 8px;
    padding: .7rem .85rem;
    margin: .5rem 0;
    font-size: .88rem;
    line-height: 1.5;
}
.nova-aanbod p { margin: 0 0 .5rem; }
.nova-aanbod .btn { margin-right: .35rem; }

/* --- DE OEFENING ZELF --- */
.nova-adem { text-align: center; padding: .6rem 0 .2rem; }
.nova-adem-cirkel {
    width: 92px; height: 92px;
    margin: 0 auto .7rem;
    border-radius: 50%;
    border: 3px solid var(--gold);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.6rem; font-weight: 700;
    color: var(--text);
    /* De duur per stap staat hier hard, want ze hoort bij de oefening zelf:
       4 tellen in, 7 vasthouden, 8 uit. Het uitademen duurt langer dan het
       inademen — dat is het werkzame deel. */
    transition: transform 4s ease-in-out, background-color 1s ease;
    background: color-mix(in srgb, var(--gold) 8%, transparent);
}
.nova-adem-in   { transform: scale(1.35); transition-duration: 4s; }
.nova-adem-vast { transform: scale(1.35); transition-duration: .3s;
                  background: color-mix(in srgb, var(--gold) 18%, transparent); }
.nova-adem-uit  { transform: scale(1);    transition-duration: 8s; }
.nova-adem-tekst { font-size: .95rem; margin: 0 0 .2rem; }
.nova-adem-ronde { font-size: .78rem; color: var(--muted-leesbaar); margin: 0 0 .6rem; }

@media (prefers-reduced-motion: reduce) {
    html:not(.beweging-aan) .nova-adem-cirkel { transition: none; transform: none !important; }
}

/* De houder van Nova's gezicht in de kop van het paneel. De SVG vult zijn
   houder, dus die moet een maat hebben — anders klapt hij samen tot niets. */
.mascotte-gezicht-houder {
    flex: 0 0 auto;
    width: 51px;
    height: 51px;
    display: block;
}
/* En op de knop rechtsonder. .mascotte-knop had een vaste maat voor het oude
   bolletje; de SVG neemt die nu over. */
.mascotte-knop .nova-svg { width: 51px; height: 51px; }

/* ===================================================================
   DE DERDE REGEL VAN DE VERWELKOMING (22-8-2026)
   ===================================================================
   Het weetje of de mop. De eigenaar wil dat het dashboard "altijd een leuke
   verwelkoming geeft". Drie regels, en niet meer: begroeting, stand, weetje.

   Een dun scheidingslijntje erboven, zodat het duidelijk iets anders is dan
   de stand — dit is het enige stukje op het scherm dat niets van je vraagt.
   =================================================================== */
.hero-weetje {
    display: flex;
    align-items: flex-start;
    gap: .45rem;
    margin-top: .7rem;
    padding-top: .6rem;
    border-top: 1px solid var(--border);
    font-size: .88rem;
    line-height: 1.45;
    color: var(--muted-leesbaar);
}

.hero-weetje-icoon { flex: 0 0 auto; }
.hero-weetje-tekst { flex: 1 1 auto; }

.hero-weetje-volgende {
    flex: 0 0 auto;
    background: none;
    border: 0;
    padding: 0 0 0 .5rem;
    font-size: .72rem;
    color: var(--muted-leesbaar);
    cursor: pointer;
    opacity: .75;
    transition: opacity 160ms ease;
}

.hero-weetje-volgende:hover,
.hero-weetje-volgende:focus-visible { opacity: 1; text-decoration: underline; }

/* Op een gsm past de knop niet meer naast de tekst. */
@media (max-width: 640px) {
    .hero-weetje { flex-wrap: wrap; }
    .hero-weetje-volgende { padding-left: 0; margin-top: .25rem; }
}

/* ===================================================================
   DE RACE (22-8-2026)
   ===================================================================
   *"Ik wil wel bij de ranking nog een leuke animatie dat het lijkt of er is
   een paardenloopwedstrijd."*

   Twee regels die het ontwerp bepalen:

   1. De eindpositie staat in het style-attribuut (--pos). De animatie beweegt
      er alleen naartoe. Speelt ze niet af, dan staat iedereen meteen goed.
      Beweging draagt nooit in haar eentje informatie.
   2. Geen rood, nergens. Achterlopen op tempo op dag twaalf is geen fout, en
      rood zeggen tegen iemand die nog negentien dagen heeft is onjuist.
   =================================================================== */
.race { display: flex; flex-direction: column; gap: .5rem; }

.race-kop {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: .78rem;
}
.race-titel { font-weight: 700; }
.race-rest { color: var(--muted-leesbaar); }

.race-banen { display: flex; flex-direction: column; gap: 8px; }

.race-baan {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding-left: .5rem;
    /* Eén tint voor ALLE banen. Geen gekleurde rijen — dat is de huisregel, en
       de race is precies het blok waar de verleiding het grootst is. */
    background: var(--glas-licht),
                color-mix(in srgb, var(--muted) 8%, transparent);
    border-radius: 0 8px 8px 0;
    /* Het huisrecept voor glas: lichte bovenrand, donkere onderrand. Een
       `border` zou 1px ruimte innemen en de hele lijst verschuiven; een
       inset-schaduw tekent hetzelfde en kost geen plek. Zie glas.css. */
    box-shadow: var(--binnenrand);
    position: relative;
    overflow: hidden;
}

/* ⚠️ DE BREEDTE VAN DE RENNER STAAT ÉÉN KEER, HIER.
   Chip 28 + wagen 66 − 4 overlap = 90. CSS rekent er de baan mee uit en JS
   raakt het niet aan. Verander je de wagen, verander je dit getal, en de
   plaatsing klopt weer vanzelf. */
.race { --renner-breedte: 92px; }

/* VANAF ACHT RENNERS (eigenaar: "Ik heb mss 10 verkopers binnenkort")
   ==================================================================
   Alles wordt kleiner, niets verdwijnt. Vooral de NAAM blijft staan: een race
   waarin je alleen "V01, V02, V03" ziet, beantwoordt de enige vraag niet die
   je erbij stelt. Tien banen komen zo op ongeveer 420 pixels. */
.race--krap { --renner-breedte: 70px; }
.race--krap .race-naam { font-size: .74rem; }
.race--krap .race-auto { width: 48px; height: 20px; }
.race--krap .race-doel { font-size: .7rem; }

.race-plaats {
    flex: 0 0 auto;
    width: 1.2rem;
    font-size: .85rem;
    color: var(--muted-leesbaar);
    text-align: right;
}

.race-naam {
    flex: 0 0 auto;
    font-size: .82rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.race-baanvlak {
    position: relative;
    flex: 1 1 auto;
    min-width: 160px;
    height: 100%;
    /* Het asfalt: een ingedrukte glasgoot waar de wagen doorheen rijdt. */
    border-radius: 999px;
    background: color-mix(in srgb, var(--muted) 10%, transparent);
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, .35),
                inset 0 -1px 0 rgba(255, 255, 255, .06);
}

/* DE VOORTGANGSBALK (eigenaar, 23-8-2026: "Ik wil voortgang ballen")
   ==================================================================
   Het stuk baan dat al afgelegd is, in de kleur van de renner. Zonder deze
   balk moest je de stand aflezen aan de plaats van een wagentje van negentig
   pixels op een baan van zeshonderd — dat leest niemand.

   ⚠️ HIJ EINDIGT WAAR DE WAGEN BEGINT, NIET WAAR ZIJN NEUS ZIT.
   Eerste versie liep tot de neus. Gemeten op het scherm: de verkoper op NUL
   procent had daardoor toch een balkje van negentig pixels liggen — precies de
   breedte van de wagen — en dat leest als "hij heeft al wat". Nu duwt de wagen
   de balk voor zich uit: op nul is er niets, op honderd loopt de balk tot aan
   de wagen en staat zijn neus op de finish. Aan allebei de uiteinden eerlijk. */
.race-vulling {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: calc((100% - var(--renner-breedte)) * var(--pos, 0) / 100);
    border-radius: 999px;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--renner-kleur, var(--blue)) 18%, transparent) 0%,
        color-mix(in srgb, var(--renner-kleur, var(--blue)) 62%, transparent) 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
    transition: width 900ms cubic-bezier(.22, 1, .36, 1) var(--start, 0ms);
}

/* De tempolijn: waar je vandaag zou moeten staan. Op dezelfde schaal als de
   wagen, anders meet je twee dingen met twee verschillende linialen. */
.race-tempo {
    position: absolute;
    top: 15%;
    bottom: 15%;
    left: calc((100% - var(--renner-breedte)) * var(--tempo, 0) / 100
               + var(--renner-breedte));
    width: 2px;
    background: var(--muted);
    opacity: .55;
}

/* ⚠️ DE WAGEN MAG NIET DOOR HET CIJFER RIJDEN (eigenaar, 23-8-2026).
   ==================================================================
   Hier stond ``left: var(--pos); transform: translate(-50%, -50%)``. Op 100%
   lag het MIDDEN van de renner op de rechterrand van de baan, dus hing de
   halve wagen eroverheen — over het percentage ernaast. Gemeten op het
   draaiende scherm: er stond "00%" waar "400%" hoorde te staan.

   Nu schuift de renner binnen een spoor dat precies zijn eigen breedte korter
   is dan de baan. Op 0 staat hij tegen de start, op 100 raakt zijn neus de
   finish, en nooit steekt er iets buiten. */
.race-renner {
    position: absolute;
    top: 50%;
    left: calc((100% - var(--renner-breedte)) * var(--pos, 0) / 100);
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    transition: left 900ms cubic-bezier(.22, 1, .36, 1) var(--start, 0ms);
}

/* De bol met de afkorting is weg (eigenaar 24-8-2026); de markering van de
   koploper (goud) en van jezelf (accent) draagt de wagen nu zelf. */
.race-renner.is-eerste .race-auto { filter: drop-shadow(0 0 5px var(--gold)); }
.race-renner.is-mij .race-auto { filter: drop-shadow(0 0 4px var(--accent)); }

/* De wagen. Getekend en niet als emoji: deze server heeft geen
   kleuren-emoji-lettertype, en een emoji is niet in de kleur van de renner te
   zetten. Zie raceAuto() in core.js.

   ⚠️ 66 BIJ 27 EN NIET 44 BIJ 18 (eigenaar, 23-8-2026: "Wagen is wazig").
   De tekening heeft coördinaten tot op 0,05 nauwkeurig — vleugels van driekwart
   pixel, een luchtinlaat van anderhalve. Op 44 bij 18 valt dat allemaal tussen
   de pixels en maakt de browser er grijze randen van. Anderhalf keer zo groot
   is exact dezelfde verhouding (44×1,5 en 18×1,5) en past nog altijd in een
   baan van 44 pixels hoog.

   De slagschaduw is meteen een halve pixel geworden. Een waas van 2 pixels
   rond een vorm van 18 hoog is geen diepte meer, dat is gewoon onscherpte. */
.race-auto {
    margin-left: -4px;
    filter: drop-shadow(0 1px .5px rgba(0, 0, 0, .55));
}

/* De finishlijn. Die ontbrak: zonder streep aan het eind is het geen race maar
   een balk. Staat altijd op 100% — het eigen maanddoel. */
.race-finish {
    position: absolute;
    top: 8%;
    bottom: 8%;
    right: 0;
    width: 3px;
    background: repeating-linear-gradient(
        180deg,
        var(--gold) 0 4px,
        transparent 4px 8px);
    opacity: .85;
}

.race-doel {
    flex: 0 0 auto;
    width: 56px;
    text-align: right;
    padding-right: .5rem;
    font-size: .76rem;
    color: var(--muted-leesbaar);
    font-variant-numeric: tabular-nums;
}

.race-voet { font-size: .7rem; color: var(--muted-leesbaar); }

/* HET STARTSCHOT
   ==============
   De eigenaar: *"als je het dashboard opent moeten de auto's racen van de start
   tot waar de score van dat moment staat."*

   Vandaar de langere, snellere curve dan bij een gewone voortgangsbalk: hij
   trekt op en rolt uit, in plaats van gelijkmatig te schuiven.

   De trilling loopt ALLEEN tijdens het rijden (de klasse gaat er daarna weer
   af). Een wagen die de hele dag staat te trillen is na twintig seconden
   hinderlijk en na een week een reden om het blok weg te klikken. */
.race-renner { transition: left 1100ms cubic-bezier(.16, .84, .44, 1) var(--start, 0ms); }

html.beweging-aan .race-renner.rijdt .race-auto {
    animation: race-trilt 90ms linear var(--start, 0ms) 12;
}

/* Snelheidsstrepen achter de wagen, alleen terwijl hij rijdt. */
html.beweging-aan .race-renner.rijdt::before {
    content: "";
    position: absolute;
    right: 100%;
    top: 50%;
    width: 26px;
    height: 2px;
    margin-top: -1px;
    background: linear-gradient(to left, var(--muted), transparent);
    opacity: .55;
    animation: race-streep 1100ms ease-out var(--start, 0ms) 1;
}

@keyframes race-trilt {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-.5px); }
}

@keyframes race-streep {
    0%   { opacity: 0; width: 0; }
    35%  { opacity: .55; width: 26px; }
    100% { opacity: 0; width: 4px; }
}

/* Smal scherm: de naamkolom valt weg, de code blijft. */
@media (max-width: 640px) {
    .race-naam { width: 52px !important; }
    .race-doel { width: 44px; }
}

/* ===================================================================
   WERKPUNTEN EN BERICHTEN, GESCHEIDEN (22-8-2026)
   ===================================================================
   *"Ik zou bij de aandachtspunten gewoon een duidelijk onderscheid maken van
   werkpunten en berichtmeldingen."*

   Een werkpunt is iets dat JIJ moet doen en dat blijft staan tot het gebeurd
   is. Een bericht is iets dat gebeurd is. Die twee door elkaar in één bel
   leerde iedereen om de bel te negeren — en dan mis je ook het werkpunt.
   =================================================================== */
.aandacht-groep-kop {
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted-leesbaar);
    margin: .9rem 0 .35rem;
}
.aandacht-groep-kop:first-child { margin-top: 0; }

.aandacht-bericht {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    padding: .45rem .6rem;
    border-left: 3px solid var(--blue);
    background: var(--bg);
    border-radius: 0 5px 5px 0;
    margin-bottom: .3rem;
    font-size: .8rem;
}

.aandacht-bericht[role="button"] { cursor: pointer; }
.aandacht-bericht[role="button"]:hover { background: var(--hover-bg); }
.aandacht-bericht.is-gelezen { border-left-color: var(--border); opacity: .7; }

.aandacht-bericht-titel { font-weight: 600; }
.aandacht-bericht-tekst { color: var(--muted-leesbaar); font-size: .74rem; }

.aandacht-bericht-leeg {
    font-size: .8rem;
    color: var(--muted-leesbaar);
    padding: .3rem 0;
}

/* ===================================================================
   RUIMTE VOOR DE ZWEVENDE KNOPPEN (22-8-2026)
   ===================================================================
   Rechtsonder zweven er drie: Nova (80px), de hulpknop (46px) en de chat
   (56px). Samen nemen ze een strook van ongeveer 110 pixels in, over de volle
   hoogte — en ze liggen BOVEN de inhoud.

   Gemeten op de draaiende app: op het dashboard dekte Nova de "0%" van het
   Retail-blok af, en op Jaar Overzicht de jaarcijfers van drie van de vier
   verkopers. De zaakvoerder zag dus precies de getallen niet waarvoor hij dat
   scherm opent.

   Een losse pleister per blok werkt niet — het is de hele rechterrand. Vandaar
   dat de inhoudskolom ruimte houdt. Alleen op brede schermen: op een gsm
   staan de knoppen onderaan en is die ruimte juist kostbaar.
   =================================================================== */
@media (min-width: 1200px) {
    #content { padding-right: 118px; }
}

/* ===================================================================
   SCHUIFBALKEN IN DE HUISSTIJL (22-8-2026)
   ===================================================================
   Met color-scheme: dark tekent de browser ze al donker. Deze regels geven ze
   de huiskleur, zodat ze niet meer het lichtste ding op het scherm zijn.

   Met variabelen, geen losse hexwaarden: dan bewegen ze mee als het palet ooit
   verandert.
   =================================================================== */
* {
    scrollbar-color: color-mix(in srgb, var(--gold) 28%, transparent) transparent;
    scrollbar-width: thin;
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }

::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--gold) 28%, transparent);
    border-radius: 8px;
}

::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--gold) 45%, transparent);
}

/* ===========================================================================
   RETAIL-HERONTWERP 24-8
   ===========================================================================
   De eigenaar: "heel slecht leesbaar (...) meer met voortgangsbalken werken
   en tabellen. En dit in volgorde van belangrijkheid: maand, kwartaal en dan
   jaar. (...) De tabellen staan te dicht bij elkaar waardoor het onduidelijk
   wordt. (...) Kijk naar het dashboard van mij, daar staan leuke animaties."

   Alles hieronder hoort bij retail.js en is geprefixt met rtl-. De balken
   zelf zijn de bestaande .dash-progress van het dashboard (zelfde animatie,
   zelfde statuskleuren); hier staan alleen de retail-specifieke schil en de
   markers van de A/B/C-contractniveaus.

   BEWEGING: alle animaties hier zijn aankleding — de eindstand staat altijd
   in het style-attribuut (--progress) en in de tekst ernaast. Er staat hier
   bewust GEEN eigen prefers-reduced-motion-regel: het globale blok bovenaan
   dit bestand (html:not(.beweging-aan), zie de les van 12-8-2026) legt deze
   animaties al stil voor wie geen beweging wil, en niets valt dan weg.
   =========================================================================== */

/* ---- De kop: titel, uitleg en de twee handelingen ---- */
.rtl-kop {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.75rem;
}
.rtl-titel {
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--primary);
    letter-spacing: -.5px;
    line-height: 1.15;
    margin: 0 0 .3rem;
}
.rtl-ondertitel {
    font-size: .88rem;
    color: var(--muted-leesbaar);
    line-height: 1.5;
    max-width: 62ch;
}
.rtl-kop-acties {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-wrap: wrap;
}

/* ---- De blokken: elk in een eigen kaart, met lucht ertussen ----
   .dash-card levert de kaart en de hover-lift (zelfde toon als het
   dashboard); hier komen alleen maat, rand en binnenverdeling bij. */
.rtl-blokken { margin-bottom: 1.75rem; }
.rtl-blok {
    padding: 1.4rem 1.6rem;
    border-left: 4px solid var(--border);
    /* Binnenkomst zoals de dashboard-tegels: trapsgewijs en kort. TWEE
       animaties, bewust gescheiden (gemeten met headless Edge, 24-8):
       de opacity heeft GEEN vertraging — een fill-mode backwards mét delay
       op de opacity hield elk blok zolang de delay duurde op onzichtbaar,
       en de globale reduced-motion-regel dooft wel duur maar geen delay.
       Alleen de transform komt trapsgewijs; inhoud is er altijd meteen.
       Fill-mode backwards zodat na afloop niets vastgepind blijft en de
       hover-lift van .dash-card gewoon blijft werken. */
    animation: rtl-blok-fade .35s ease-out backwards,
               rtl-blok-rise .55s var(--veer, cubic-bezier(.22, 1, .36, 1)) backwards;
    animation-delay: 0ms, calc(var(--rtl-volgorde, 0) * 90ms);
}
@keyframes rtl-blok-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
@keyframes rtl-blok-rise {
    from { transform: translateY(14px); }
    to   { transform: translateY(0); }
}
/* De maand is het grootst: hier valt deze week nog iets aan te doen. */
.rtl-blok-maand {
    padding: 1.8rem 2rem;
    margin-bottom: 1.5rem;
}
.rtl-blok-rij {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 1.5rem;
}

/* Eén oordeel kleurt rand, balk en badge samen (zie _retailStand in
   retail.js). Rustige pastel, linkerrand als indicator — geen rode vlakken. */
.rtl-stand-gehaald  { border-left-color: var(--melding-ok-rand); }
.rtl-stand-achter   { border-left-color: var(--melding-waarschuwing-rand); }
.rtl-stand-op_tempo { border-left-color: var(--primary); }

.rtl-blok-kop {
    display: flex;
    align-items: baseline;
    gap: .6rem;
    flex-wrap: wrap;
    margin-bottom: .9rem;
}
.rtl-blok-naam {
    font-size: .78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .6px;
    color: var(--muted-leesbaar);
}
.rtl-blok-periode {
    font-size: .95rem;
    font-weight: 700;
    color: var(--text);
    text-transform: capitalize;
}
.rtl-badge {
    margin-left: auto;
    font-size: .72rem;
    font-weight: 700;
    padding: .22rem .65rem;
    border-radius: 999px;
    white-space: nowrap;
}
.rtl-badge-gehaald {
    color: var(--melding-ok-rand);
    border: 1px solid color-mix(in srgb, var(--melding-ok-rand) 45%, transparent);
    background: color-mix(in srgb, var(--melding-ok-rand) 10%, transparent);
}
.rtl-badge-achter {
    color: var(--melding-waarschuwing-fg);
    border: 1px solid var(--melding-waarschuwing-rand);
    background: var(--melding-waarschuwing-bg);
}
.rtl-badge-neutraal {
    color: var(--muted-leesbaar);
    border: 1px solid var(--border);
    background: transparent;
}

/* ---- Het klikbare cijfer: elk getal is een deur ---- */
.rtl-cijfer-rij {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    flex-wrap: wrap;
    margin-bottom: .5rem;
}
.rtl-cijfer {
    background: none;
    border: none;
    padding: 0 0 .1rem;
    margin: 0;
    cursor: pointer;
    font: inherit;
    font-size: 3.2rem;
    font-weight: 800;
    line-height: 1;
    color: var(--primary);
    /* De stippellijn zegt "hier zit iets achter" zonder te schreeuwen. */
    border-bottom: 2px dashed color-mix(in srgb, var(--primary) 35%, transparent);
    transition: transform .2s cubic-bezier(.4, 0, .2, 1), color .2s, border-color .2s;
    animation: rtl-pop .45s cubic-bezier(.34, 1.56, .64, 1) backwards;
    animation-delay: calc(var(--rtl-volgorde, 0) * 90ms + 120ms);
}
.rtl-cijfer:hover {
    transform: translateY(-2px) scale(1.04);
    color: var(--accent);
    border-bottom-color: var(--accent);
}
.rtl-cijfer:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}
/* ⚠️ GEEN opacity in deze keyframes: met fill-mode backwards en een delay is
   opacity 0 anders de rusttoestand tijdens de delay, en dan staat het
   belangrijkste getal van het scherm er even niet (gemeten 24-8). Een lichte
   schaal is tijdens de delay gewoon leesbaar. */
@keyframes rtl-pop {
    0%   { transform: scale(.85); }
    60%  { transform: scale(1.05); }
    100% { transform: scale(1); }
}
.rtl-cijfer-klein { font-size: 2.1rem; }
.rtl-cijfer-doel {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--muted-leesbaar);
}
.rtl-cijfer-label {
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--muted-leesbaar);
}

/* ---- De balk met de A/B/C-markers van het contract ---- */
.rtl-balk { margin-top: .4rem; }
.rtl-balk-rail { position: relative; }
.rtl-blok-maand .rtl-balk-rail { height: 16px; }
.rtl-balk-marker {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 2px;
    transform: translateX(-50%);
    background: var(--text);
    opacity: .45;
    z-index: 3;
    pointer-events: none;
}
.rtl-balk-schaal {
    position: relative;
    height: 1.05rem;
    margin-top: .35rem;
}
.rtl-balk-label {
    position: absolute;
    top: 0;
    font-size: .68rem;
    font-weight: 600;
    color: var(--muted-leesbaar);
    white-space: nowrap;
}
.rtl-balk-zin {
    font-size: .78rem;
    color: var(--muted-leesbaar);
    margin-top: .2rem;
}
.rtl-balk-leeg {
    font-size: .8rem;
    color: var(--muted-leesbaar);
    padding: .4rem 0;
}
.rtl-minibalk {
    height: 8px;
    flex: 0 1 150px;
    min-width: 90px;
}

/* ---- De sublijnen (705, EV-poort) en de open poort ---- */
.rtl-subcijfers {
    display: flex;
    align-items: center;
    gap: .4rem 1.4rem;
    flex-wrap: wrap;
    margin-top: 1rem;
    padding-top: .8rem;
    border-top: 1px solid var(--border);
    font-size: .82rem;
    color: var(--muted-leesbaar);
}
.rtl-subcijfer { display: inline-flex; align-items: baseline; gap: .35rem; }
.rtl-subcijfers .rtl-cijfer {
    font-size: 1.05rem;
    border-bottom-width: 1px;
    animation: none;
}
.rtl-ev-noot { font-size: .72rem; }
.rtl-poort-ok {
    margin-top: .8rem;
    font-size: .78rem;
    color: var(--muted-leesbaar);
}
.rtl-poort-ok::before {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--melding-ok-rand);
    margin-right: .45rem;
}
.rtl-poort-vangnet { opacity: .85; }

/* ---- De verwittigingsbalk: één amberkleurige regelaar, alleen als er echt
   iets te verwittigen valt (anders staat er niets) ---- */
.rtl-verwittiging {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    background: var(--melding-waarschuwing-bg);
    border-left: 4px solid var(--melding-waarschuwing-rand);
    color: var(--melding-waarschuwing-fg);
    border-radius: 8px;
    padding: .65rem .9rem;
    margin-bottom: 1.1rem;
    font-size: .85rem;
    line-height: 1.5;
}

/* ---- De retaillijst: luchtig, zebrastrepen, chassis prominent ---- */
.rtl-lijstkaart, .rtl-doelenkaart { margin-bottom: 1.75rem; }
.rtl-samenvatting {
    font-size: .85rem;
    color: var(--muted-leesbaar);
    line-height: 1.5;
    margin-bottom: .8rem;
}
.rtl-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-bottom: 1rem;
}
.rtl-chip {
    font-size: .74rem;
    padding: .22rem .6rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--muted-leesbaar);
    white-space: nowrap;
}
.rtl-chip strong { color: var(--text); font-weight: 700; }
.rtl-chip-rest { border-style: dashed; }

/* Op een telefoon neemt de bestaande app-regel het over (elke <table> wordt
   daar zelf een scrollend blok, zie de mobiele sectie rond "Alle tables
   krijgen scrollable wrapper-gedrag"); deze wrapper doet het werk op de
   bredere schermen. */
.rtl-tabel-scroll { overflow-x: auto; }
.rtl-tabel { width: 100%; border-collapse: collapse; }
.rtl-tabel th {
    font-size: .72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
    color: var(--muted-leesbaar);
    text-align: left;
    padding: .5rem .65rem;
    border-bottom: 1px solid var(--border);
}
.rtl-tabel td {
    padding: .7rem .65rem;
    font-size: .88rem;
    border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
    transition: background .15s;
}
/* Zebra via een mix op --muted: werkt in licht én donker zonder aparte
   override, en blijft ver onder de drempel van "gekleurde rijen". */
.rtl-tabel tbody tr:nth-child(even) td {
    background: color-mix(in srgb, var(--muted) 6%, transparent);
}
.rtl-tabel tbody tr:hover td {
    background: color-mix(in srgb, var(--primary) 8%, transparent);
}
.rtl-tabel-compact td { padding: .45rem .6rem; font-size: .82rem; }
.rtl-chassis {
    font-family: var(--font-mono, ui-monospace, 'Cascadia Mono', Consolas, monospace);
    font-weight: 700;
    font-size: .92rem;
    letter-spacing: .3px;
}
/* In het donkere thema is het standaard-linkblauw van de browser onleesbaar
   op de donkere zebra (gemeten 24-8); het huispalet heeft er een lichtere
   blauw-token voor. Licht thema houdt de vertrouwde linkkleur. */
[data-theme="dark"] .rtl-tabel a { color: var(--blue); }
.rtl-los { font-size: .7rem; color: var(--muted-leesbaar); }
.rtl-nog-niet { color: var(--muted-leesbaar); }
.rtl-leeg { color: var(--muted-leesbaar); padding: 1rem; }

/* ---- Het naslagwerk: de objectieven uit het Kia-contract ---- */
.rtl-doelen-rij {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
}
.rtl-doelen-soort { flex: 1; min-width: 250px; }
.rtl-doelen-soortnaam {
    font-weight: 600;
    font-size: .85rem;
    margin-bottom: .3rem;
}
.rtl-doelen-bron {
    font-size: .7rem;
    color: var(--muted-leesbaar);
    margin-top: .25rem;
}

/* ---- Het drill-venster: breder dan het standaardvenster, de tabel scrolt
   in zijn eigen kader ---- */
.ss-venster.rtl-venster-breed { width: 780px; }
.rtl-drill-scroll {
    max-height: 55vh;
    overflow: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
}

/* ---- Klein scherm: de maandkaart mag inschikken, de cijfers blijven
   leesbaar ---- */
@media (max-width: 700px) {
    .rtl-blok-maand { padding: 1.2rem 1rem; }
    .rtl-blok { padding: 1.1rem 1rem; }
    .rtl-cijfer { font-size: 2.4rem; }
    .rtl-cijfer-klein { font-size: 1.8rem; }
    .rtl-kop { align-items: flex-start; }
    /* Op een gsm knipt de app-brede .main/100vw-kwestie ±16px van de
       rechterrand van elke kaart (gemeten via CDP op 390px, 24-8; zit ook in
       de andere schermen). De balk en de kopregel springen hier wat naar
       binnen zodat het C-label op 100% en de badge leesbaar blijven —
       markers en labels delen dezelfde breedte, dus de uitlijning
       verschuift niet. */
    .rtl-balk { padding-right: 20px; }
    .rtl-blok-kop { padding-right: 16px; }
    /* A/B/C liggen vaak dicht bij elkaar (43/48/54); op een smal scherm
       botsen drie labels. De B-tekst wijkt dan — de B-marker op de balk en
       zijn tooltip blijven staan, en de waarde staat ook in de
       objectieventabel onderaan. */
    .rtl-balk-label-b { display: none; }
}
