html, body { height: 100%; margin: 0; }

.shell { display: flex; flex-direction: column; height: 100vh; }

.topbar {
    display: flex; align-items: center; gap: 12px;
    height: 52px; padding: 0 16px; flex: 0 0 auto;
    border-bottom: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
}
.brand { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; text-decoration: none; color: var(--bs-body-color); }

.shell-body { display: flex; flex: 1; min-height: 0; }

.sidebar {
    flex: 0 0 220px; overflow-y: auto; padding: 12px 8px;
    border-right: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
}

.nav-menu { display: flex; flex-direction: column; gap: 2px; }
.nav-menu .nav-link {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px; border-radius: 8px;
    color: var(--bs-body-color); text-decoration: none; font-size: .92rem;
}
.nav-menu .nav-link:hover { background: var(--bs-secondary-bg); }
/* ⚠️ `--adm-accent-text`, niet `--bs-primary` (AppKit 0.461.0): de accentkleur is voor VLAKKEN; als tekst op haar eigen
   tint haalt ze de contrastnorm bij tien van de elf accenten niet. Zie de kop van adm-shell.css in het pakket. */
.nav-menu .nav-link.active { background: var(--bs-primary-bg-subtle); color: var(--adm-accent-text); font-weight: 600; }

/* ⚠️ min-height: 0 is niet optioneel. Zonder die regel krimpt dit flex-item niet onder zijn inhoudshoogte:
   het contentgebied groeit voorbij de viewport en de HELE pagina scrollt in plaats van enkel dit vak.
   Zet ze op .content ZELF — enkel op .content-inner (zoals de :has-regels verderop) repareert de binnenkant
   en laat de buitenkant stuk. */
.content { flex: 1; min-width: 0; min-height: 0; overflow-y: auto; }

/* De max-width is een bewuste LEESCAP voor formulieren en tekstpagina's: regels van 2000px lezen niet.
   Pagina's die de ruimte moeten vullen (grid, tweekoloms-werkscherm) ontsnappen eraan via de
   :has(.adm-grid-fill)-regels verderop en de :has(.adm-page-fill)-regels in adm-shell.css. Een FICHE heeft haar eigen cap
   (zie de :has(.adm-fiche)-regel verderop). Schrap deze cap dus niet — voeg een uitzondering toe als je een nieuw
   vol-formaat patroon bouwt. */
.content-inner { padding: 20px 24px; max-width: 1100px; }

/* ⚠️ VLAK EN TEKST UIT DEZELFDE FAMILIE (12/10/2026). Tot dan had de balk een VAST licht vlak (#fee) zonder eigen
   tekstkleur: in donker erfde de zin de lichte tekstkleur van het thema en de twee links de lichte accentkleur — wit op
   bijna-wit (gemeten: 1,16 en 1,87–2,40 over de elf accenten; norm 4,5). De balk verschijnt enkel wanneer het circuit
   sterft, precies wanneer iemand moet kunnen lezen wat er aan de hand is. Gemeld door de CEOS-sessie.
   Het thema levert vlak en tekst als paar, in licht en in donker; de terugval is hetzelfde paar in vaste kleuren. De
   links nemen de tekstkleur van de balk over (de accentkleur is niet voor dit vlak gekozen) en zijn onderlijnd.
   Bewaakt door ContrastBrowserTests in de AppKit, die de balk eerst zichtbaar maakt: op display:none meet niemand iets. */
#blazor-error-ui {
    display: none; position: fixed; bottom: 0; left: 0; right: 0;
    padding: 10px 16px; z-index: 1100;
    background: var(--bs-danger-bg-subtle, #fee);
    color: var(--bs-danger-text-emphasis, #58151c);
    border-top: 1px solid var(--bs-danger-border-subtle, #f5c2c7);
}
#blazor-error-ui .reload, #blazor-error-ui .dismiss { margin-left: 12px; cursor: pointer; color: inherit; text-decoration: underline; }

/* === AdmGrid (overgezet uit ADM One — playbook §6) ============================================ */
/* Accentkleur voor o.a. de selectie-balk; overschrijfbaar per thema/tenant. */
:root { --adm-accent: #2563eb; }

/* AdmGrid: uniforme toolbar (zoek + kolomselector + export) boven elke grid. */
.adm-grid-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}

.adm-grid-bar-spacer {
    flex: 1 1 auto;
}

.adm-grid-search {
    width: 300px;
    max-width: 100%;
}

.adm-grid-empty {
    padding: 18px;
    color: var(--bs-secondary-color);
    font-style: italic;
}

/* Laadfase: grid verbergen (layout wordt nog toegepast) en een spinner tonen, zodat de gebruiker
   geen herformattering ("flikker") ziet. */
.adm-grid-body { position: relative; }
.adm-grid-veil { visibility: hidden; }
.adm-grid-fill .adm-grid-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.adm-grid-loading {
    position: absolute;
    inset: 0;
    min-height: 180px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}
.adm-spinner {
    width: 34px;
    height: 34px;
    border: 3px solid var(--dx-color-border, #e0e0e0);
    border-top-color: var(--dx-color-primary, #2563eb);
    border-radius: 50%;
    animation: adm-spin .7s linear infinite;
}
@keyframes adm-spin { to { transform: rotate(360deg); } }

/* FullHeight: de grid vult de beschikbare hoogte (toolbar vast, grid scrollt intern). De :has-regels
   koppelen aan de layout-wrapper (.content/.content-inner — aanwezig in deze app). */
.content:has(.adm-grid-fill) {
    display: flex;
    flex-direction: column;
}
.content:has(.adm-grid-fill) > .content-inner {
    flex: 1;
    min-height: 0;
    max-width: none;   /* grid-pagina's vullen de volle breedte, niet de 1100px-leescap */
    display: flex;
    flex-direction: column;
}

/* Op een pagina met een FICHE bepaalt de fiche haar eigen breedte (.adm-fiche: max-width var(--adm-fiche-breedte, 1100px)
   in de AppKit), niet de leescap van de pagina.
   ⚠️ Waarom (15/10/2026, gezien door Dominique, gemeten en voorgesteld door CleanOps, beslist door Dominique): de leescap
   hierboven maakte een fiche bij het openen 1052 px breed (1100 min 2×24 rand), en de vulrasterregel hierboven hief ze op
   zodra er ERGENS een FullHeight-raster in de pagina stond. Een raster in een fichetabblad (het vlootadvies van Huis
   Jacobs, 13/09) komt pas in de pagina bij de eerste klik op dat tabblad: de fiche sprong dan van 1052 naar 1100 px en
   bleef zo. Nu is een fiche van bij het openen 1100 px — de breedte die ze na de klik al kreeg. Lijstpagina's, brede
   fiches (.adm-fiche-breed) en fiches zonder raster in een tab veranderen verder niet (gemeten bij CleanOps op 1440 px). */
.content:has(.adm-fiche) > .content-inner {
    max-width: none;
}
.content:has(.adm-grid-fill) > .dxbl-btn {
    align-self: flex-start;
}
.adm-grid-fill {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.adm-grid-fill .adm-grid-bar { flex: 0 0 auto; }

/* Vol-hoogte WERKSCHERM (`adm-page-fill`, `adm-fill-row`, `adm-fill-panel`): sinds AppKit 0.435.0 in adm-shell.css.
   ⚠️ Zet de regels hier NIET terug. De vlootversie die hier stond, droeg de `overflow: hidden` op .content BUITEN de
   media query: onder 992px scrolde de pagina dan niet (Auto's Bart, 30/09/2026 — 62.387px bord, alles onder de vouw
   onbereikbaar). Een app-regel wint van de fundering, en zo erfde elke nieuwe app de fout opnieuw. */
.adm-grid-fill .dxbl-grid { flex: 1; min-height: 0; }

/* Rijmarkering (selectie + focus) staat sinds AppKit 0.19.0 in adm-shell.css — AdmGrid komt uit het
   pakket, dus hoort zijn stijl daar ook. Zet ze hier NIET opnieuw: een app-regel wint van de fundering
   en je krijgt stil afwijkend gedrag per app. */

/* Login-scherm: de stijl staat in het AppKit-pakket (Adm.AppKit.Web, AdmLoginTweeluik.razor.css), niet hier. */

/* Nav: gebruiker + afmelden onderaan. */
.nav-spacer { flex: 1 1 auto; min-height: 12px; }
.nav-user { padding: 8px 12px; font-size: .82rem; color: var(--bs-secondary-color); font-weight: 600; }
.nav-section { padding: 12px 12px 4px; font-size: .72rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: var(--bs-secondary-color); }

/* === Release notes ("Wat is nieuw") ============================================================ */
.release-notes { max-width: 760px; }
.rn-item { padding: 16px 0; border-bottom: 1px solid var(--bs-border-color); }
.rn-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.rn-version { font-weight: 700; }
.rn-date { color: var(--bs-secondary-color); font-size: .85rem; }
.rn-cat { font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em;
    padding: 2px 8px; border-radius: 10px; background: var(--bs-secondary-bg); color: var(--bs-secondary-color); }
.rn-title { font-size: 1.05rem; margin: 2px 0 6px; }
.rn-body { color: var(--bs-body-color); }
.rn-body :last-child { margin-bottom: 0; }
.rn-body img { max-width: 100%; height: auto; border-radius: 6px; }
/* ══ De neutrale kleuren van de eigen Ceos-schermen — licht én donker ═════════════════════════════════
   Tot 12/10/2026 stonden hieronder elf VASTE neutrale kleuren (leisteengrijs voor legendes, dagnummers en
   veldlabels; lichtgrijs voor koppen, weekend en «vandaag»). In het lichte thema klopt dat; in het donkere
   blijft een vaste donkere tekst op een donker vlak staan, en krijgt een vast licht vlak de lichte tekst van
   het thema. Gemeten in de browser op vier schermen: de titel van «Planning des visites» op 1,07, de kop van
   «Tableau indicateurs» op 1,19, elke legende op 2,2 (de norm is 4,5).
   ⚠️ LICHT = letterlijk de kleuren van vroeger: wie het lichte thema gebruikt, mag hier niets van merken.
   ⚠️ DONKER = de kleuren van het thema zelf (Bootstrap/fundering), niet een eigen donker palet: zo volgen
      deze schermen de rest van de app wanneer het thema wijzigt.
   ⚠️⚠️ Een NIEUWE neutrale kleur hoort hier, met een waarde in BEIDE blokken — niet als hex in een regel.
        ThemakleurenTests faalt op een vaste tekstkleur zonder eigen vlak (en omgekeerd), en op een variabele
        die maar in één van de twee blokken staat.
   De kleurenPAREN verderop (rollen van de kalender, rood/oranje van de alerten, groen/rood van het rooster)
   blijven vast: ze dragen hun eigen vlak ÉN hun eigen tekst, en komen letterlijk uit de analyse.
   ═══════════════════════════════════════════════════════════════════════════════════════════════════ */
:root, [data-bs-theme="light"] {
    --ceos-tekst-gedempt: #475569;    /* legendes, dagnummers, veldlabels, uitleg */
    --ceos-tekst-sterk: #334155;      /* het opschrift van een legende */
    --ceos-tekst-titel: #0f172a;      /* de maand boven de kalender, de dagkop van de lijst */
    --ceos-tekst-vaag: #cbd5e1;       /* het nummer van een dag uit een andere maand — bewust vervaagd */
    --ceos-tekst-conflict: #b91c1c;   /* «⚠ Indisponibilité sur une visite» in de legende */
    --ceos-vlak-kop: #f1f5f9;         /* koppen van kalender, lijst en indicatorentabel */
    --ceos-vlak-weekend: #f8fafc;
    --ceos-vlak-vandaag: #eff6ff;
    --ceos-vlak-neutraal: #ffffff;    /* het vlekje «geen kleur» in de legende van de alerten */
}

/* ⚠️ Dit blok moet NA het lichte staan: op <html> hebben `:root` en `[data-bs-theme]` dezelfde sterkte, en
      dan wint wie het laatst staat. */
[data-bs-theme="dark"] {
    --ceos-tekst-gedempt: var(--bs-secondary-color);
    --ceos-tekst-sterk: var(--bs-body-color);
    --ceos-tekst-titel: var(--bs-emphasis-color);
    --ceos-tekst-vaag: var(--bs-tertiary-color);
    --ceos-tekst-conflict: var(--adm-danger-text);
    --ceos-vlak-kop: var(--bs-secondary-bg);
    --ceos-vlak-weekend: var(--bs-tertiary-bg);
    --ceos-vlak-vandaag: color-mix(in srgb, var(--adm-accent) 28%, var(--bs-body-bg));
    --ceos-vlak-neutraal: var(--bs-body-bg);
}

/* ══ «Planification» — het stapcellenrooster (B09 S1) ═════════════════════════════════════════════════
   ⚠️⚠️ DE VOLGORDE IN DIT BLOK IS BETEKENISVOL. `.adm-planning-knop` staat BEWUST BOVENAAN, vóór de drie
        klassen die kleur en vet zetten. Alle vier hebben dezelfde specificiteit (één klasse), en bij gelijke
        specificiteit wint wie het LAATST staat. Zet je de knop onderaan, dan wist ze de opmaak van de cellen
        eronder — en dat is precies wat er op 18/09/2026 gebeurde: `background: none` en `font: inherit` zijn
        VERKORTE eigenschappen die óók `background-color`, `color` en `font-weight` terugzetten. Gemeten in de
        browser: groen en rood kwamen allebei als `rgba(0,0,0,0)` uit `getComputedStyle`, de witte tekst van
        een rode cel als `rgb(22,22,22)`, en het vet als 400 in plaats van 700.
   ⚠️⚠️ EN DIT IS DE LES: het rooster telde op dat moment nog steeds 127 elementen met `.adm-planning-groen`
        en 37 met `.adm-planning-rood`. De KLASSEN stonden er allemaal. Een telling van klassen bewijst dus
        niets over kleur — meet `getComputedStyle`, niet `querySelectorAll`.
   ⚠️ De kleuren zelf komen uit B09 S1.R#8 en zijn niet vrij te kiezen: lichtgroen #DCFCE7 met zwarte tekst,
      donkerrood #B91C1C met witte tekst en vet. ⚠️ Het ROOD wijkt sinds 28/10/2026 bewust af (Dominique, visuele controle #21:
      «kan het rood iets minder fel? Het groen is mooi»): nu de kleur de hele cel vult, sloeg de legacy-kleur veel harder dan het
      groen. Het is het rood dat het alertendashboard al draagt — achtergrond #FEE2E2 (rood-100, de tegenhanger van groen-100
      #DCFCE7) met donkerrode tekst #B91C1C, vet. Rood en groen zijn voor kleurenblinde gebruikers niet te
      onderscheiden; daarom draagt de rode cel óók vet, en staat er onder het rooster een legende. De legacy
      laat het bij kleur alleen.
   ═══════════════════════════════════════════════════════════════════════════════════════════════════ */

/* De stapcel als KNOP — B09 S1.A7. Ze mag er niet als een knop uitzien: twaalf knoppen per rij maal 42 rijen
   maakt van een rooster een knoppenveld.
   ⚠️ `min-height` en de volle breedte staan er om ÉÉN reden: een cel zonder datum heeft GEEN TEKST, en een
      knop zonder tekst is nul pixels groot. B09 S1.A7 zegt uitdrukkelijk dat het commentaar ook in te voeren
      is «wanneer de cel leeg oogt». Zonder die twee regels is dat geval onbereikbaar met de muis — de functie
      zou bestaan, compileren en onzichtbaar stuk zijn. Gemeten: 13 zulke cellen, elk 100×20 px.
   ⚠️ De LANGE vorm van font-* en background-color, nooit de verkorte `font:` of `background:` — zie de kop.
      `font-weight` staat er bewust NIET: dan blijft de 400 van de browser staan voor een gewone cel, en
      winnen de klassen hieronder voor een rode of becommentarieerde. */
.adm-planning-knop {
    display: block;
    width: 100%;
    min-height: 1.25rem;
    border: 0;
    background-color: transparent;
    padding: 0;
    margin: 0;
    font-family: inherit;
    font-size: inherit;
    font-style: inherit;
    line-height: inherit;
    color: inherit;
    /* De uitlijning van de KOLOM (gecentreerd sinds 28/10/2026, #21) — een vaste `left` hier centreerde enkel de cellen
       zonder bewerkrecht (een span), want een knop erft text-align niet uit zichzelf. */
    text-align: inherit;
    cursor: pointer;
}

.adm-planning-knop:focus-visible {
    outline: 2px solid var(--bs-primary, #0d6efd);
    outline-offset: -2px;
}

/* De KLEUR staat op de CEL, niet rond de datum (visuele controle #21, Dominique 28/10/2026). Zo deed de legacy het
   ook: S1.R#8 kleurt de «achtergrond van een stapcel». Tot dan droeg de datum zelf de kleur, met een negatieve
   marge om de cel te vullen — gemeten 90×28 px in een cel van 110×52, want de celmarge van DevExpress is groter
   en een rij met een klantnaam op twee regels is hoger. `:has()` vraagt de cel of haar inhoud het merkteken draagt;
   de tekstkleur staat erbij (ThemakleurenTests: een vast vlak draagt zijn eigen tekstkleur), knop en span erven ze. */
.dxbl-grid .dxbl-grid-table > tbody > tr > td:has(> .adm-planning-groen) {
    background-color: #DCFCE7;
    color: #000;
}

.dxbl-grid .dxbl-grid-table > tbody > tr > td:has(> .adm-planning-rood) {
    background-color: #FEE2E2;
    color: #B91C1C;
}

/* Op de datum zelf blijft enkel het merkteken — en bij rood het vet, het tweede signaal naast de kleur. */
.adm-planning-groen {
    color: inherit;
}

.adm-planning-rood {
    color: inherit;
    font-weight: 700;
}

/* Het commentaarmerkteken: vet met een gestippelde onderlijning, 3 px onder de tekst (B09 S1.R#6d).
   ⚠️ Zonder datum tekent dit NIETS — een onderlijning over lege tekst is nul pixels breed. Dat is de legacy
      zelf (S1.R#6d: «dan is er niets te zien»), geen fout hier. */
.adm-planning-commentaar {
    font-weight: 700;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}

/* ══ «Planning des visites» — de maandkalender (B09 S2.G1) ════════════════════════════════════════════
   ⚠️ De zes kleurenparen komen LETTERLIJK uit de legende van S2.G1 en zijn niet vrij te kiezen: de klant
      kent ze uit de legacy. Elk paar is achtergrond / rand / tekst.
   ⚠️⚠️ Dezelfde valkuil als bij «Planification»: gebruik NOOIT de verkorte `background:` of `font:` op een
        knop die óók een kleurklasse draagt. Die verkorte vormen zetten background-color, color en
        font-weight terug, en bij gelijke specificiteit wint wie het laatst staat — het rooster ziet er dan
        volledig correct uit met alle klassen op hun plaats en zonder één kleur. Daarom staat de basisknop
        hier BOVEN de kleurklassen, net als daar, en bewaakt CssKlassenTests dat.
   ═══════════════════════════════════════════════════════════════════════════════════════════════════ */

.adm-kal-legende {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 14px;
    font-size: .6875rem;
    color: var(--ceos-tekst-gedempt);
    margin-bottom: 8px;
}

.adm-kal-legende-item { display: inline-flex; align-items: center; gap: 5px; }

.adm-kal-vlek {
    width: 11px;
    height: 11px;
    border-radius: 3px;
    border: 1px solid transparent;
    display: inline-block;
}

/* Het conflictteken: rood en vet, zoals S2.R#6. Géén eigen achtergrond — de rolkleur blijft staan.
   ⚠️ Deze regel kleurt enkel de LEGENDE (ze staat op het vlak van de pagina, dus themabewust). Het ETIKET
      krijgt zijn rood verderop, NA de zes kleurenparen — zie daar waarom. */
.adm-kal-conflict { color: var(--ceos-tekst-conflict); font-weight: 700; }

.adm-kal-balk {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}

.adm-kal-balk-links, .adm-kal-balk-rechts { display: flex; gap: 6px; }
.adm-kal-balk-rechts { margin-left: auto; }

.adm-kal-titel {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--ceos-tekst-titel);
    text-transform: capitalize;   /* «septembre 2026» → «Septembre 2026» */
}

/* Het rooster vult de resterende hoogte; de weken delen die gelijk. */
.adm-kal { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: auto; }

.adm-kal-kop {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    position: sticky;
    top: 0;
    z-index: 2;
}

.adm-kal-kop > div {
    padding: 4px 6px;
    font-size: .6875rem;
    font-weight: 600;
    color: var(--ceos-tekst-gedempt);
    background: var(--ceos-vlak-kop);
    border: 1px solid var(--bs-border-color);
    border-bottom: 0;
    text-transform: uppercase;
    text-align: center;
}

.adm-kal-week {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    padding: 0 0 2px;
}

/* De achtergrond van één dag; ze loopt over de VOLLE hoogte van de weekrij, zodat een balk eroverheen
   kan liggen zonder dat de cel hem afkapt. */
.adm-kal-cel {
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    min-height: 92px;
    position: relative;
}

.adm-kal-weekend { background: var(--ceos-vlak-weekend); }
.adm-kal-vandaag { background: var(--ceos-vlak-vandaag); }

.adm-kal-nummer {
    position: absolute;
    top: 2px;
    right: 5px;
    font-size: .6875rem;
    color: var(--ceos-tekst-gedempt);
}

/* Dagen van de vorige/volgende maand: nummer vervaagd, etiketten gewoon zichtbaar (S2.G1). */
.adm-kal-buiten { color: var(--ceos-tekst-vaag); }

/* Een etiket is een KNOP: aanklikbaar met de muis én met het toetsenbord (S2.R#8). Ze mag er niet als een
   knop uitzien — twaalf per dag maakt van een kalender een knoppenveld. Lange tekst loopt door op een
   volgende regel binnen de cel, zoals S2.G1 vraagt. */
.adm-kal-etiket {
    z-index: 1;
    margin: 0 3px;
    padding: 1px 4px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-family: inherit;
    font-size: .6875rem;
    line-height: 1.25;
    text-align: left;
    cursor: pointer;
    overflow-wrap: anywhere;
    align-self: start;
}

.adm-kal-etiket:focus-visible { outline: 2px solid var(--bs-primary, #0d6efd); outline-offset: 1px; }

/* De eerste rij etiketten begint onder het dagnummer. */
.adm-kal-week > .adm-kal-etiket:first-of-type { margin-top: 0; }

.adm-kal-meer {
    z-index: 1;
    margin: 0 3px;
    padding: 0 4px;
    border: 0;
    background: none;
    color: var(--adm-accent-text);
    font-family: inherit;
    font-size: .6875rem;
    text-align: left;
    cursor: pointer;
    align-self: start;
}

/* ── De zes kleurenparen van S2.G1 ── */
.adm-kal-klant        { background-color: #dbeafe; border-color: #3b82f6; color: #1e3a8a; }
.adm-kal-coord        { background-color: #dcfce7; border-color: #22c55e; color: #14532d; }
.adm-kal-binome       { background-color: #ede9fe; border-color: #8b5cf6; color: #4c1d95; }
.adm-kal-supervise    { background-color: #fef3c7; border-color: #f59e0b; color: #78350f; }
.adm-kal-observateur  { background-color: #cffafe; border-color: #06b6d4; color: #155e75; }
.adm-kal-indispo      { background-color: #fee2e2; border-color: #ef4444; color: #991b1b; }

/* Een etiket met een conflict: ROOD en vet op de kleur van zijn rol (S2.R#6).
   ⚠️⚠️ Tot 12/10/2026 was zo'n etiket vet maar NIET rood. `.adm-kal-conflict` stond boven de zes paren, met
        dezelfde sterkte (één klasse) — en dan wint wie het laatst staat, dus de tekstkleur van de rol.
        Gemeten in de browser: vier etiketten met «⚠», alle vier in de kleur van hun rol. Dezelfde valkuil
        als in de kop van «Planification», één blok hoger. Daarom hier TWEE klassen: dat wint van elk paar,
        waar de regel ook staat.
   ⚠️ Vast en niet themabewust: het vlak eronder is het vaste lichte vlak van de rol, in licht én donker.
   ⚠️ #b91c1c en niet de #dc2626 van de legacy: op de zes rolkleuren haalt #dc2626 3,95 tot 4,40 (norm 4,5),
      dezelfde tint donkerder 5,30 tot 5,89 (nagerekend 12/10/2026; in de eerste versie van deze noot stond «5,6 of
      meer» — uit het hoofd, en te gunstig). Zelfde keuze als bij de kopbalk van het portaal.
      ✅ Beslist door Dominique op 12/10/2026, met beide tinten naast elkaar: het donkerdere rood blijft. */
.adm-kal-etiket.adm-kal-conflict { color: #b91c1c; }

/* ── De lijstweergave ── */
.adm-kal-lijst { flex: 1; min-height: 0; overflow: auto; }

.adm-kal-lijst-kop {
    display: flex;
    justify-content: space-between;
    padding: 6px 8px;
    background: var(--ceos-vlak-kop);
    border-top: 1px solid var(--bs-border-color);
    font-size: .8125rem;
    font-weight: 600;
    color: var(--ceos-tekst-titel);
    /* GEEN text-transform: capitalize (visuele controle #22, 28/10/2026). Dat zet een hoofdletter op ELK woord: «1 Octobre 2026»,
       «Jeudi». In het Frans krijgen maand- en dagnamen een kleine letter, zoals de legacy («10 septembre 2026», «jeudi») en het
       dagvenster achter «+N». De titel van de maand houdt de zijne: daar begint «Octobre» een kop. */
}

.adm-kal-lijst-regel {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 4px 8px;
    border: 0;
    background: none;
    font-family: inherit;
    font-size: .8125rem;
    text-align: left;
    cursor: pointer;
}

.adm-kal-lijst-regel:hover { background: var(--bs-secondary-bg); }

/* In de lijst is een conflict VET maar niet rood — zo doet de legacy het (S2.G1). */
.adm-kal-lijst-regel .adm-kal-conflict { color: inherit; }

/* Het bolletje draagt de RANDkleur van de rol, niet de achtergrond. */
.adm-kal-bol { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.adm-kal-bol.adm-kal-klant        { background-color: #3b82f6; }
.adm-kal-bol.adm-kal-coord        { background-color: #22c55e; }
.adm-kal-bol.adm-kal-binome       { background-color: #8b5cf6; }
.adm-kal-bol.adm-kal-supervise    { background-color: #f59e0b; }
.adm-kal-bol.adm-kal-observateur  { background-color: #06b6d4; }
.adm-kal-bol.adm-kal-indispo      { background-color: #ef4444; }

/* ⚠️ Tot 12/10/2026 #94a3b8: op wit 2,6 — «Aucune visite planifiée» is een mededeling, geen versiering. */
.adm-kal-leeg { text-align: center; font-style: italic; color: var(--ceos-tekst-gedempt); padding: 24px; }

/* ══ «Tableau indicateurs» (B10 S3) ══════════════════════════════════════════════════════════════════ */

.adm-ind-uitleg {
    max-width: 780px;
    margin-bottom: 14px;
    font-size: .8125rem;
    color: var(--ceos-tekst-gedempt);
}

.adm-ind-uitleg > summary { cursor: pointer; }

.adm-ind-balk {
    display: flex;
    align-items: flex-end;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}

.adm-ind-veld { display: flex; flex-direction: column; gap: 3px; }
.adm-ind-veld > label { font-size: .75rem; font-weight: 600; color: var(--ceos-tekst-gedempt); }

/* ⚠️ Een breedte op de WRAPPER en niet op het veld zelf: DxSpinEdit en AdmLookup rekken anders uit tot de
      volle breedte van de balk. Een `Width`-parameter bestaat er niet op — die gooit bij het renderen. */
.adm-ind-veld > .dxbl-edtr, .adm-ind-veld > .dxbl-combobox { width: 160px; }

.adm-ind-tabel {
    border-collapse: collapse;
    margin-bottom: 18px;
    min-width: 420px;
}

.adm-ind-tabel th, .adm-ind-tabel td {
    border: 1px solid var(--bs-border-color);
    padding: 5px 14px;
}

/* Kolomkoppen vet én gecentreerd; rijlabels vet maar LINKS — ook «Total» (S3.G1). */
.adm-ind-tabel thead th { font-weight: 700; text-align: center; background: var(--ceos-vlak-kop); }
.adm-ind-tabel tbody th, .adm-ind-tabel tfoot th { font-weight: 700; text-align: left; }

/* Kwartaalwaarden gecentreerd en normaal; de waarden in de rij «Total» gecentreerd en VET (S3.G1). */
.adm-ind-tabel tbody td { text-align: center; font-weight: 400; }
.adm-ind-tabel tfoot td { text-align: center; font-weight: 700; }
.adm-ind-tabel tfoot { border-top: 2px solid var(--bs-border-color); }

/* De tabel staat sinds 13/10/2026 in een kaart naast de grafiek: ze vult die kaart, zonder marge eronder. */
.adm-card > .adm-ind-tabel { width: 100%; min-width: 0; margin-bottom: 0; }

/* De vijf tegels op ÉÉN regel (visuele controle #20, 28/10/2026). Het raster van de AppKit (auto-fit, minstens 180 px) zette er
   op 1280 px vier boven en «Taux d'atteinte (faites + prévues)» alleen eronder — net de twee percentages die je samen leest.
   Vijf gelijke kolommen: op 1280 px ±176 px elk, boven de min-width van een tegel (165 px). */
.adm-metric-group.is-large.ceos-tegels-vijf { grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* ══ «Tableau qualifications» (B10 S4.K) ═════════════════════════════════════════════════════════════
   De kleurREGELS komen uit de klantvraag van 09/2026 (Habilitatieregels). De kleuren zelf: sinds visuele controle #55
   (Dominique, 30/10/2026) kleurt de CEL, met het zachtere rood van het alertendashboard en van Planification (#21) — de klantvraag
   zei #B91C1C met witte tekst, «bewust verzadigd» zodat het ook op een geselecteerde rij opvalt. Op de cel zelf vult de kleur nu de
   hele cel en blijft ze op een geselecteerde rij staan; het vet blijft het tweede signaal naast de kleur.
   ═══════════════════════════════════════════════════════════════════════════════════════════════════ */

/* De KLEUR staat op de td (`:has()`), zoals bij Planification: een blok met negatieve marge in de cel vulde haar niet (de celmarge
   van DevExpress is groter, en een rij met een opmerking op twee regels is hoger). De tekstkleur staat erbij (ThemakleurenTests:
   een vast vlak draagt zijn eigen tekstkleur). Een LEGE rode cel bij «compétences» draagt «Jamais réalisée» (#55). */
.dxbl-grid .dxbl-grid-table > tbody > tr > td:has(> .adm-kw-rood) { background-color: #FEE2E2; color: #B91C1C; }
.dxbl-grid .dxbl-grid-table > tbody > tr > td:has(> .adm-kw-oranje) { background-color: #FEF3C7; color: #B45309; }

.adm-kw-cel { font-weight: 700; }

/* De vlekken van de legende: dezelfde twee vlakken, met een rand in de tekstkleur zodat het lichte rood op wit te zien is. */
.adm-kw-vlek.adm-kw-rood { background-color: #FEE2E2; color: #B91C1C; border: 1px solid #B91C1C; }
.adm-kw-vlek.adm-kw-oranje { background-color: #FEF3C7; color: #B45309; border: 1px solid #B45309; }

.adm-kw-legende { display: flex; gap: 16px; flex-wrap: wrap; font-size: .75rem; color: var(--ceos-tekst-gedempt); }
.adm-kw-legende-item { display: inline-flex; align-items: center; gap: 6px; }

.adm-kw-vlek {
    width: 11px;
    height: 11px;
    border-radius: 3px;
    display: inline-block;
}

.adm-kw-opmerking { display: flex; align-items: flex-start; gap: 6px; }
.adm-kw-opmerking > span { white-space: pre-wrap; flex: 1; min-width: 0; }

/* Het potlood: geen knop-uiterlijk, wel knop-gedrag (ook met het toetsenbord). */
.adm-kw-pen {
    flex: 0 0 auto;
    border: 0;
    background-color: transparent;
    padding: 0 2px;
    font-family: inherit;
    color: var(--adm-accent-text);
    cursor: pointer;
    opacity: .55;
}

.adm-kw-pen:hover, .adm-kw-pen:focus-visible { opacity: 1; }

/* ══ «Tableau de bord des alertes» (B10 S1.G1) ═══════════════════════════════════════════════════════
   ⚠️ De twee kleurenparen komen uit S1.L en zijn niet vrij te kiezen. ⚠️⚠️ Nooit de verkorte `background:`
      of `font:` op een cel die ook een kleurklasse draagt — zie de kop van het planningblok hierboven.
   ═══════════════════════════════════════════════════════════════════════════════════════════════════ */

.adm-alert-cel {
    display: block;
    margin: -0.25rem -0.5rem;
    padding: 0.25rem 0.5rem;
}

.adm-alert-rood { background-color: #FEE2E2; color: #B91C1C; }
.adm-alert-oranje { background-color: #FEF3C7; color: #B45309; }

/* Tabbladen die de VOLLE HOOGTE doorgeven aan hun lijst — «Documents à valider» (27/10/2026, visuele controle #6 door Dominique:
   «waarom gebruiken de grids niet de volledige hoogte in de verschillende tabbladen?»). De AppKit trekt de hoogteketen door
   tabbladen enkel binnen een fiche (.adm-fiche-tabstrip); een DxTabs op een werkscherm (adm-page-fill) is voor DevExpress een blok
   dat met zijn inhoud meegroeit. Gemeten op 1440 × 900: werkvlak 700 px, tabbladen 324 px, de rest wit. Vier schakels, alle vier
   nodig: de tabbladen, het inhoudsvak van DevExpress, ons omhulsel per tabblad, en FullHeight op het raster. Elke regel apart
   weggehaald uit het stijlblad (1920 × 1080): het raster eindigt op 571 in plaats van 1060. Behalve de content-panel-regel: die
   lijkt niets te doen omdat DevExpress dat vak al flex maakt, maar in een venster van 480 px hoog scrolt de PAGINA zonder haar
   126 px (haar min-height: 0). Zelfde vorm als
   .adm-tabs-vol in CreditSoft en .ws-tabs in ADM One (derde kopie: promotiekandidaat). Bewaakt door VolleHoogteTabsTests. */
.adm-page-fill .ceos-tabs-vol { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* En binnen een fichetab (visuele controle #32, «Résultats», 29/10/2026): de AppKit geeft het ene kind van de tab al de volle
   hoogte als flexkolom, maar een DxTabs daarin is een gewoon blok. Gemeten in de preview (1280 × 800): het tabblad 744 en 1 498 px
   hoog in 442, zonder deze regel. */
.adm-fiche-tabinhoud .ceos-tabs-vol { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.ceos-tabs-vol .dxbl-tabs-content-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.ceos-tabs-vol .dxbl-tabs-content { display: flex; flex-direction: column; min-height: 0; }
.ceos-tabblad-vol { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }

/* De ontvangers van «E-mails groupés» (visuele controle #62, 30/10/2026): één lijst met een eigen schuifbalk in een vak van vaste
   hoogte, zoals de legacy (S2.G1, geen paginering). Het raster draagt VirtualScroll en vult dit vak; de rest van het formulier
   (CC, Objet, Contenu) blijft eronder bereikbaar. */
.ceos-ontvangers { height: 26rem; display: flex; flex-direction: column; }

/* De tegels van «Administration» (visuele controle #63, 30/10/2026): minstens 225 px, zodat er op elke breedte 4 per rij staan en de titels
   op één regel passen. De fundering geeft 180 px binnen een raster van hoogstens 1 000 px: op 1440 en 1920 werden dat 5 tegels van 192 px,
   en 8 van de 14 titels liepen over twee of drie regels. ⚠️ Niet meer dan 227 px: op 1280 is het raster 938 px breed, en dan zakt het
   naar 3 per rij. Drie klassen diep, omdat de regel van de fundering een scoped selector is (.tiles-compact[b-…]). */
.ceos-beheer-tegels .tiles.tiles-compact { grid-template-columns: repeat(auto-fill, minmax(225px, 1fr)); }

/* Het EIGEN zoekveld in de werkbalk van een lijst (ZoekveldFocus, 27/10/2026, visuele controle #7 door Dominique: «waarom staat
   dit over de volledige breedte van het scherm?»). Tien lijsten laten de dienst zoeken en zetten het zoekvak van de grid uit; hun
   eigen veld kreeg geen breedte, en een DevExpress-tekstveld is 100 % breed: het nam een volle regel boven de lijst (gemeten 1 112 px
   op 1440). Nu 300 px, op de regel van de filters: het omhulsel staat op display: contents, dus zijn ::before is een kind van de
   werkbalk, en met flex-basis 100 % breekt het de regel vlak vóór het veld (de titel blijft alleen op zijn regel). Enkel als DIRECT
   kind van de werkbalk: Planification en Catapulte zetten ZoekveldFocus in een eigen vak. Bewaakt door ZoekveldBreedteTests. */
.adm-grid-bar > .ceos-zoekveld::before { content: ""; flex: 0 0 100%; height: 0; }
.adm-grid-bar > .ceos-zoekveld > .dxbl-text-edit { flex: 0 0 300px; width: 300px; }
/* Hetzelfde voor een keuzelijst (AdmLookup) rechtstreeks in de werkbalk: de status van Formateurs en Personnel was 1 112 px breed en
   zette zoekveld, keuzelijst en teller elk op een eigen regel. 220 px, de breedte van het zoekvak van de AppKit. */
.adm-grid-bar > dxbl-combo-box.dxbl-text-edit { flex: 0 0 220px; width: 220px; }

/* Een rij in de SubBar van AdmGrid (27/10/2026, visuele controle #5 door Dominique: «de knop plakt tegen de grid»). De AppKit geeft
   de titelrij (.adm-grid-bar) 10 px ruimte onderaan en de SubBar niets: «Filtrer les alertes», de zoekvelden van Planification en de
   legende van Qualifications raakten het raster (gemeten: 0 px). Dezelfde 10 px. Bewaakt door SubBarTests. */
.ceos-subbar { margin-bottom: 10px; }

.adm-alert-legende {
    display: flex;
    gap: 6px 14px;
    flex-wrap: wrap;
    align-items: center;
    font-size: .75rem;
    color: var(--ceos-tekst-gedempt);
}

.adm-alert-legende > strong { color: var(--ceos-tekst-sterk); }
.adm-alert-legende-item { display: inline-flex; align-items: center; gap: 6px; }

.adm-alert-vlek {
    width: 12px;
    height: 12px;
    border-radius: 3px;
    display: inline-block;
    border: 1px solid #cbd5e1;
}

.adm-alert-vlek.adm-alert-rood { border-color: #B91C1C; }
.adm-alert-vlek.adm-alert-oranje { border-color: #B45309; }
.adm-alert-neutraal { background-color: var(--ceos-vlak-neutraal); }
.adm-alert-leeg { background-color: var(--ceos-vlak-kop); border-style: dashed; }

/* De filterpopup van het alertendashboard (B10 S2). */
.adm-alert-filter {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

@media (max-width: 640px) {
    .adm-alert-filter { grid-template-columns: 1fr; }
}

.adm-alert-filter-kop {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    margin-bottom: 6px;
}

/* De titel op een eigen regel, de twee links samen eronder (27/10/2026, visuele controle #5): met de titel en de links op één
   regel paste in een kolom van ±340 px enkel «Tout sélectionner» ernaast, en brak «Tout désélectionner» af naar de volgende regel. */
.adm-alert-filter-kop > strong { flex: 0 0 100%; font-size: .875rem; }

.adm-alert-keuze {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 0;
    font-size: .875rem;
    cursor: pointer;
}

/* ══ «Résultats → Détail des réponses»: de kolom «Correct» (legacy 4f09199, 12/10/2026) ═══════════════
   Groen bij «Oui», rood bij «Non», zoals de legacy (gs_CellBgSuccess / gs_CellBgDanger); een lege cel krijgt
   geen kleur — het sjabloon tekent dan niets.
   ⚠️ Een PAAR, vlak én tekst (ThemakleurenTests): de cel is in licht en in donker dezelfde. De kleur is nooit
      het enige signaal: het woord staat erin.
   ⚠️ De lange `background-color`, nooit de verkorte `background:` — zie de kop van «Planification».
   ═══════════════════════════════════════════════════════════════════════════════════════════════════ */
/* De KLEUR staat op de CEL (visuele controle #32, Dominique 29/10/2026), zoals Planification (#21): tot dan droeg het woord
   een vlak met een negatieve marge om de cel te vullen, en dat bleef een vlakje in een hogere cel (de vraag ernaast loopt over
   meerdere regels). `:has()` vraagt de cel of haar inhoud het merkteken draagt; het woord erft de tekstkleur. */
.dxbl-grid .dxbl-grid-table > tbody > tr > td:has(> .adm-quiz-juist) { background-color: #DCFCE7; color: #14532D; }
.dxbl-grid .dxbl-grid-table > tbody > tr > td:has(> .adm-quiz-fout) { background-color: #FEE2E2; color: #991B1B; }

.adm-quiz-cel { font-weight: 600; }
.adm-quiz-juist, .adm-quiz-fout { color: inherit; }

/* «Générer document» (A2 stap 3): de PDF-kijker in het resultaatvenster. DxPdfViewer heeft geen style-parameter; de hoogte
   gaat via CssClass, zoals in CreditSoft. Hoog genoeg voor een A4 in breedte, binnen het scherm. */
.ceos-pdfkijker {
    height: min(75vh, 900px);
}

/* B07 S1.G1 (B2, 08/10/2026): een verwijderde missie in «Supprimé»/«Tous» is doorgestreept, zoals in de legacy — en gedempt,
   zoals de fundering een record toont dat er nog staat maar niet meer leeft (adm-grid-rij-gedempt). Sinds #57 (30/10/2026) ook een
   gedeactiveerde klant in «Liste des clients» — de legacy streepte daar de hele rij door (B05 S1.G1). */
.adm-grid tr.ceos-rij-verwijderd > td { color: var(--bs-secondary-color); text-decoration: line-through; }

/* === Het portaal «Portail Elyos» (A2.1 F4, P01 S2) ============================================================================
   De legacy kleurt de kopbalk #F47D3B; met witte tekst haalt dat 2,7:1 — te weinig (AA: 4,5:1). Dezelfde tint, donkerder: 4,6:1.
   Kolom links met naamblok en tegels; onder 768 px (évaluateurs zijn buitendienst, P01.18) schuiven de tegels in een rij boven
   het werkvlak. Kleuren uit de Bootstrap-variabelen, zodat een donker thema vanzelf volgt. */
:root { --portaal-accent: #c4531b; }
.portaal-schil { min-height: 100vh; display: flex; flex-direction: column; background: var(--bs-body-bg); }
.portaal-kop { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 16px;
    background: var(--portaal-accent); color: #fff; }
.portaal-titel { font-weight: 700; font-size: 1.3rem; }
.portaal-afmelden { min-height: 36px; color: #fff; border: 1px solid rgba(255, 255, 255, .75); }
.portaal-afmelden:hover, .portaal-afmelden:focus-visible { color: var(--portaal-accent); background: #fff; }
.portaal-romp { display: flex; flex: 1; min-height: 0; }
.portaal-menu { width: 220px; flex-shrink: 0; background: var(--bs-tertiary-bg); border-right: 1px solid var(--bs-border-color); }
.portaal-naamblok { display: flex; align-items: center; gap: 8px; padding: 16px 12px; background: var(--bs-secondary-bg); font-weight: 600; }
.portaal-naam { flex: 1; min-width: 0; overflow-wrap: anywhere; }
/* 36 × 36: het enige doel naar «Modifier votre mot de passe», en op een gsm een vinger (gemeten 10/10: 24 × 29 was te klein). */
.portaal-wachtwoord { display: inline-flex; align-items: center; justify-content: center; min-width: 36px; min-height: 36px;
    color: var(--bs-body-color); border-radius: 4px; }
.portaal-wachtwoord:hover, .portaal-wachtwoord:focus-visible { background: var(--bs-body-bg); color: var(--portaal-accent); }
.portaal-menukop { padding: 12px 12px 4px; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--bs-secondary-color); }
.portaal-tegels { display: flex; flex-direction: column; }
.portaal-tegel { display: flex; align-items: center; gap: 10px; padding: 12px; color: var(--bs-body-color); text-decoration: none;
    font-weight: 600; border-left: 3px solid transparent; }
.portaal-tegel:hover, .portaal-tegel:focus-visible { background: var(--bs-secondary-bg); color: var(--bs-body-color); }
/* De legacy toont nergens waar je bent (P01 S2.R3); hier wel. */
.portaal-tegel.active { border-left-color: var(--portaal-accent); background: var(--bs-body-bg); }
.portaal-werkvlak { flex: 1; min-width: 0; padding: 20px 24px; }
.portaal-paginatitel { font-size: 1.5rem; font-weight: 700; margin-bottom: 12px; }
.portaal-nieuws { display: block; width: 100%; height: calc(100vh - 190px); min-height: 360px; border: 1px solid var(--bs-border-color);
    border-radius: 4px; background: #fff; }
@media (max-width: 767.98px) {
    .portaal-romp { flex-direction: column; }
    .portaal-menu { width: auto; border-right: 0; border-bottom: 1px solid var(--bs-border-color); }
    .portaal-naamblok { padding: 10px 12px; }
    .portaal-menukop { display: none; }
    .portaal-tegels { flex-direction: row; flex-wrap: wrap; }
    .portaal-tegel { flex: 1 1 45%; justify-content: center; border-left: 0; border-bottom: 3px solid transparent; }
    .portaal-tegel.active { border-bottom-color: var(--portaal-accent); }
    .portaal-werkvlak { padding: 16px; }
    .portaal-nieuws { height: 70vh; }
}

/* De missiefiche van het portaal (E8): blokken naast elkaar op een breed scherm, onder elkaar op een gsm; label boven de waarde. */
.portaal-fiche { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; align-items: start; }
.portaal-blok { border: 1px solid var(--bs-border-color); border-radius: 6px; padding: 14px 16px; background: var(--bs-body-bg); }
.portaal-blok-breed { grid-column: 1 / -1; }
.portaal-blok h2 { font-size: 1rem; font-weight: 700; margin: 0 0 10px; }
.portaal-blok dl { margin: 0; }
.portaal-blok dt { font-size: .8rem; font-weight: 600; color: var(--bs-secondary-color); }
.portaal-blok dd { margin: 0 0 8px; overflow-wrap: anywhere; }
.portaal-blok dd:last-child { margin-bottom: 0; }
.portaal-team, .portaal-documenten { list-style: none; margin: 0; padding: 0; }
.portaal-team li { padding: 6px 0; border-bottom: 1px solid var(--bs-border-color-translucent); }
.portaal-team li:last-child, .portaal-documenten li:last-child { border-bottom: 0; }
.portaal-documenten li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 0;
    border-bottom: 1px solid var(--bs-border-color-translucent); }

/* De missielijst van het portaal op een gsm (E7): één kaart per missie, de hele kaart is de link naar de fiche. */
.portaal-kaarten { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.portaal-kaart { display: block; padding: 12px 14px; border: 1px solid var(--bs-border-color); border-radius: 6px;
    background: var(--bs-body-bg); color: var(--bs-body-color); text-decoration: none; }
.portaal-kaart:hover, .portaal-kaart:focus-visible { border-color: var(--portaal-accent); color: var(--bs-body-color); }
.portaal-kaart-kop, .portaal-kaart-voet { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.portaal-kaart-kop { margin-bottom: 4px; color: var(--bs-secondary-color); font-size: .875rem; }
.portaal-kaart-voet { margin-top: 6px; font-size: .875rem; flex-wrap: wrap; }

/* De documenten op de missiefiche van het portaal (E8): per regel de naam en de status, haar bestanden, en een eigen oplaadveld. */
.portaal-documenten li[data-portaal-document] { display: block; padding: 12px 0; }
.portaal-document-kop { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.portaal-bestanden { list-style: none; margin: 8px 0 0; padding: 0; }
.portaal-bestanden li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; padding: 4px 0; border: 0; }
.portaal-bestanden li a, .portaal-bestanden li > span:first-child { flex: 1 1 200px; min-width: 0; }
.portaal-depot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.portaal-depot input[type=file] { flex: 1 1 220px; min-width: 0; max-width: 420px; }
/* Aanraakdoelen op een gsm: 36 px, zoals het slotje en de afmeldknop (gemeten 10/10: het oplaadveld en zijn knop waren 30 px). */
.portaal-depot .btn, .portaal-depot input[type=file], .portaal-bestanden .btn { min-height: 36px; }
/* «Jours d'indisponibilité» (A2.1 E10): het maandblad is ÉÉN formulier, elke dag een knop. Rood = zijn eigen invoer, gearceerd rood =
   ingevoerd door het kantoor (niet weg te klikken), blauw = een missiedag. Kleur is nooit de enige drager: de arcering, de legende en
   het aria-label zeggen hetzelfde. */
.portaal-kalenderblok { max-width: 860px; }
.portaal-kalender-kop { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.portaal-kalender-kop a { min-width: 36px; min-height: 36px; display: inline-flex; align-items: center; justify-content: center; }
.portaal-kalender-maand { flex: 1; margin: 0 !important; font-size: 1.1rem !important; text-align: center; text-transform: capitalize; }
.portaal-kalender { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.portaal-weekdag { padding: 4px 0; text-align: center; font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    color: var(--bs-secondary-color); }
.portaal-dag { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-height: 64px; padding: 6px; text-align: left;
    border: 1px solid var(--bs-border-color); border-radius: 6px; background: var(--bs-body-bg); color: var(--bs-body-color); cursor: pointer; }
.portaal-dag:hover, .portaal-dag:focus-visible { border-color: var(--portaal-accent); outline: 2px solid var(--portaal-accent); outline-offset: -2px; }
.portaal-dag:disabled { cursor: default; opacity: .5; }
.portaal-dag-weekend { background: var(--bs-tertiary-bg); }
.portaal-dag-buiten .portaal-dagnummer { color: var(--bs-secondary-color); opacity: .6; }
.portaal-dag-vandaag .portaal-dagnummer { color: var(--adm-accent-on); background: var(--bs-primary); border-radius: 999px; padding: 0 6px; }
.portaal-dag-eigen { background: var(--bs-danger-bg-subtle); border-color: var(--bs-danger-border-subtle); }
.portaal-dag-kantoor { background: repeating-linear-gradient(135deg, var(--bs-danger-bg-subtle) 0 6px, var(--bs-body-bg) 6px 12px);
    border-color: var(--bs-danger-border-subtle); }
.portaal-dagnummer { font-weight: 600; font-size: .9rem; line-height: 1.4; }
.portaal-dag-missie { max-width: 100%; padding: 0 6px; border-radius: 4px; font-size: .7rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; color: var(--bs-primary-text-emphasis); background: var(--bs-primary-bg-subtle); border: 1px solid var(--bs-primary-border-subtle); }
.portaal-legende { display: flex; flex-wrap: wrap; gap: 6px 18px; list-style: none; margin: 12px 0 0; padding: 0; font-size: .875rem; }
.portaal-legende li { display: inline-flex; align-items: center; gap: 6px; }
.portaal-legende-vak { display: inline-block; width: 18px; height: 18px; border: 1px solid var(--bs-danger-border-subtle); border-radius: 4px; }
.portaal-legende-missie { background: var(--bs-primary-bg-subtle); border-color: var(--bs-primary-border-subtle); }
.portaal-periodeformulier { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; align-items: end; }
.portaal-periodeformulier label { display: flex; flex-direction: column; gap: 2px; margin: 0; font-size: .8rem; font-weight: 600; color: var(--bs-secondary-color); }
.portaal-periodeformulier-breed { grid-column: 1 / -1; }
.portaal-periodeformulier .form-control, .portaal-periodeformulier .btn, .portaal-periodes .btn { min-height: 36px; }
.portaal-periodeformulier .btn { justify-self: start; }
.portaal-periodes { list-style: none; margin: 0; padding: 0; }
.portaal-periodes li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; padding: 8px 0;
    border-bottom: 1px solid var(--bs-border-color-translucent); }
.portaal-periodes li:last-child { border-bottom: 0; }
.portaal-periode-tekst { flex: 1 1 200px; min-width: 0; }
/* «Aide» (bouwlijst F12): het uitklapbare hulpblokje boven elk portaalscherm — een knopje rechts, de uitleg eronder over de volle breedte. */
.portaal-aide { margin: 0 0 4px; max-width: 1200px; }
.portaal-aide summary { display: flex; align-items: center; gap: 6px; width: fit-content; margin-left: auto; min-height: 32px; padding: 2px 10px;
    border: 1px solid var(--bs-border-color); border-radius: 999px; cursor: pointer; font-size: .85rem; color: var(--bs-body-color);
    background: var(--bs-body-bg); list-style: none; }
.portaal-aide summary::-webkit-details-marker { display: none; }
.portaal-aide summary:hover, .portaal-aide summary:focus-visible { background: var(--bs-tertiary-bg); }
.portaal-aide[open] summary { background: var(--bs-tertiary-bg); }
.portaal-aide ul { margin: 8px 0 12px; padding: 12px 16px 12px 32px; border: 1px solid var(--bs-border-color); border-radius: 6px;
    background: var(--bs-tertiary-bg); }
.portaal-aide li + li { margin-top: 4px; }
/* «Résultats des questionnaires» (A2.1 T3): de gekozen opleiding, de andere achter een uitklapper, en één blok per ingediend formulier. */
.portaal-opleidingkeuze { max-width: 860px; }
.portaal-opleidingkeuze-kop { font-size: .8rem; font-weight: 600; color: var(--bs-secondary-color); }
.portaal-opleidingkeuze-gekozen { font-weight: 600; overflow-wrap: anywhere; }
.portaal-opleidingkeuze details { margin-top: 6px; }
.portaal-opleidingkeuze summary { cursor: pointer; color: var(--bs-link-color); min-height: 32px; display: flex; align-items: center; gap: 6px; }
.portaal-opleidingkeuze summary::before { content: "\25B8"; }
.portaal-opleidingkeuze details[open] summary::before { content: "\25BE"; }
.portaal-opleidingkeuze summary::-webkit-details-marker { display: none; }
.portaal-opleidingkeuze ul { list-style: none; margin: 4px 0 0; padding: 0; border: 1px solid var(--bs-border-color); border-radius: 6px;
    max-height: 16rem; overflow-y: auto; background: var(--bs-body-bg); }
.portaal-opleidingkeuze li + li { border-top: 1px solid var(--bs-border-color); }
.portaal-opleidingkeuze li a { display: block; padding: 8px 12px; text-decoration: none; color: var(--bs-body-color); overflow-wrap: anywhere; }
.portaal-opleidingkeuze li a:hover, .portaal-opleidingkeuze li a:focus-visible { background: var(--bs-tertiary-bg); }
/* «Résultats des questionnaires» (#72, 30/10/2026): één regel per formulier, open te klappen — voluit waren 24 formulieren 8 449 px. */
.portaal-resultaten { display: flex; flex-direction: column; gap: 6px; max-width: 1200px; }
.portaal-formulier { border: 1px solid var(--bs-border-color); border-radius: 6px; background: var(--bs-body-bg); }
.portaal-formulier > summary { display: flex; align-items: baseline; gap: 16px; padding: 8px 14px; cursor: pointer; }
.portaal-formulier > summary .portaal-formulier-soort { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portaal-formulier > summary .portaal-formulier-wie,
.portaal-formulier > summary .portaal-formulier-score { flex: 0 0 auto; white-space: nowrap; font-size: .875rem; }
.portaal-formulier[open] > summary { border-bottom: 1px solid var(--bs-border-color); }
.portaal-formulier .portaal-antwoorden { margin: 0; padding: 10px 16px 12px; }
.portaal-formulier .portaal-antwoorden dt { font-size: .8rem; font-weight: 600; color: var(--bs-secondary-color); }
.portaal-formulier .portaal-antwoorden dd { margin: 0 0 8px; overflow-wrap: anywhere; }
.portaal-formulier .portaal-antwoorden dd:last-child { margin-bottom: 0; }
.portaal-antwoorden { margin: 0; }
.portaal-antwoorden dt { font-size: .85rem; font-weight: 600; color: var(--bs-body-color); }
.portaal-antwoorden dd { margin: 0 0 8px; overflow-wrap: anywhere; }
.portaal-antwoorden dd:last-child { margin-bottom: 0; }
/* «Correct» achter een quizantwoord (legacy 4f09199): enkel het woord, geen kleur — zoals het legacy-portaal. */
.portaal-correct { margin-left: 10px; color: var(--bs-secondary-color); white-space: nowrap; }
.portaal-correct > strong { color: var(--bs-body-color); }
@media (max-width: 575.98px) {
    .portaal-kalender { gap: 2px; }
    .portaal-dag { min-height: 48px; padding: 4px; align-items: center; }
    /* Op een gsm is de cel te smal voor het woord: een blauwe stip, de naam staat in de lijst eronder en in het aria-label. */
    .portaal-dag-missie { width: 10px; height: 10px; padding: 0; border-radius: 999px; font-size: 0; background: var(--bs-primary); border: 0; }
}

/* ── Kaarten NAAST elkaar op een fiche (12/10/2026) ──────────────────────────────────────────────────────────────
   De twee contactblokken van de klant staan naast elkaar, zoals in de legacy. Een Bootstrap-rij kan dat niet zonder
   de buitenste kaarten 4 px in te springen (de goot zit als binnenmarge in de kolom); een raster met een tussenruimte
   wel. `auto-fit` + `minmax`: op een smal scherm vallen de kaarten vanzelf onder elkaar. De tussenruimte is die van
   `mb-2` tussen de andere kaarten (.5rem). */
.adm-kaarten-naast {
    display: grid;
    gap: .5rem;
    grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
}

/* ── Merk Elyos (27/10/2026) ─────────────────────────────────────────────────────────────────────────────────────
   Het logo van de klant: het woordmerk «elyos» en het CEOS-icoon, aangeleverd door DAMC (05/11/2025 en 09/07/2025).
   Kleuren gemeten in die bestanden: bruin #512B1A, oranje #F47D3B, perzik #FFE4D7.
   1. Linksboven: de AppKit-MainLayout heeft geen logo-optie (AppKitOptions kent er geen), dus hetzelfde patroon als
      CleanOps, Cares, Nimble en CreditSoft: het DevExpress-icoon verbergen en het merkicoon ervoor tekenen.
   2. Het aanmeldscherm: AdmLoginTweeluik zet wit op een verloop van de accentkleur, en het logo in een vierkant van 104 px.
      Ons logo is bruin en breed, dus een perzik vlak met bruine tekst. Vlak én tekstkleur in ÉÉN regel (en niet het vlak
      via de parameter Achtergrond in Login.razor): zo draagt de regel haar eigen vlak en is ze in beide thema's leesbaar
      (ThemakleurenTests). ⚠️ `body` ervoor is nodig: app.css laadt VÓÓR de scoped stijl van het component, dus bij gelijk
      gewicht wint het component. De ondertitel erft de kleur. Contrast bruin op het verloop: 11,5 tot 10,1. */
.topbar .brand > svg.adm-icon { display: none; }
.topbar .brand::before {
    content: "";
    width: 24px; height: 24px; flex: 0 0 auto;
    background: url("/brand/ceos-icoon.png") center / contain no-repeat;
}
.adm-login-tweeluik .adm-login-merk .adm-login-logo { width: min(320px, 70%); height: auto; }
body .adm-login-tweeluik .adm-login-merk { background: linear-gradient(150deg, #FFF6F1 0%, #FFE4D7 100%); color: #512B1A; }
.adm-login-tweeluik .adm-login-merk .adm-login-tagline { color: inherit; }

/* ── Zijbalk 280 px (27/10/2026, beslist door Dominique, visuele controle #2) ───────────────────────────────────────
   De Franse menuteksten zijn lang: bij de 220 px van het sjabloon (regel 16) liepen 13 van de 26 items over twee regels,
   bij 280 px nog 2 (beide «Avertissements documents éval.»). 280 is ook de breedte van de legacy-zijbalk (B01 S2).
   Enkel de basisbreedte: het in- en uitklappen en de gsm-weergave van de schil blijven die van de fundering. */
.sidebar { flex-basis: 280px; }

/* ── Dashboardpanelen (27/10/2026, visuele controle #3) ───────────────────────────────────────────────────────────
   «Prochaines visites» en «Prochaines formations» naast de grafiek. Overgenomen van DAMC (adm-damc/…/wwwroot/app.css,
   «Dashboard-panelen»), zodat de twee dashboards dezelfde vorm hebben. ⚠️ Daarmee staat deze opmaak TWEE keer in de vloot:
   een kandidaat voor de AppKit (AdmChartCard heeft dezelfde kaartvorm, een lijstpaneel niet). De AppKit is dicht.
   Eigen toevoeging: .dash-panel-stapel + .dash-panel-row-sub — de titel met een tweede regel eronder (de évaluateurs, de klant),
   omdat een meta-tekst op dezelfde regel bij lange namen de titel wegduwt. */
/* ⚠️ Altijd TWEE kolommen, elk de halve breedte (27/10/2026): «Prochaines visites» en «Prochaines formations» naast elkaar, de
   grafiek eronder. DAMC laat de kolommen vrij vloeien (auto-fit, 320 px); hier gaf dat op 1440 px drie smalle kolommen met
   afgeknipte namen, en met 420 px een halve rij leeg naast de laatste kaart. */
.dash-panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.dash-panels + .dash-panels { margin-top: 14px; }
.dash-panel { border: 1px solid var(--bs-border-color); border-radius: 12px; padding: 12px 14px; background: var(--bs-body-bg); }
.dash-panel-head { display: flex; align-items: center; gap: 8px; font-weight: 600; margin-bottom: 8px; white-space: nowrap; }
.dash-panel-count { background: var(--bs-secondary-bg); border-radius: 999px; padding: 0 .5rem; font-size: .78rem; }
.dash-panel-empty { color: var(--bs-secondary-color); font-size: .85rem; padding: .5rem 0; }
.dash-panel-row { display: flex; align-items: center; gap: 8px; padding: 6px 4px; border-top: 1px solid var(--bs-border-color); text-decoration: none; color: inherit; }
.dash-panel-row:first-of-type { border-top: 0; }
.dash-panel-row:hover { background: var(--bs-secondary-bg); border-radius: 6px; }
.dash-panel-stapel { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.dash-panel-row-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-panel-row-sub { font-size: .78rem; color: var(--bs-secondary-color); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-panel-badge { font-size: .72rem; background: var(--bs-secondary-bg); border-radius: 6px; padding: 1px 6px; flex: 0 0 auto; }
.dash-panel-badge.is-overdue { background: color-mix(in srgb, #dc2626 15%, transparent); color: #dc2626; font-weight: 600; }

/* Een memo op de volle hoogte van een fichetab — «Remarques» van de missiefiche (visuele controle #10, 27/10/2026). Het kaartje groeit in
   de kolom van het tabblad; het memo (een DevExpress-omhulsel rond een textarea) groeit in het kaartje. min-height houdt het bruikbaar
   in een laag venster. Bewaakt door VolleHoogteMemoTests. */
.ceos-kaart-vol { min-height: 0; }
.ceos-memo-vol { flex: 1 1 auto; min-height: 12rem; display: flex; flex-direction: column; }
.ceos-memo-vol textarea { flex: 1 1 auto; height: auto !important; resize: none; }
/* Twee memo's die de hoogte GELIJK delen — «Convention» van de opleidingsfiche (visuele controle #27, 29/10/2026): elk de helft, met een
   lager minimum, want twee keer 12rem past niet onder elkaar op 1280 × 800. Gelijk omdat beide dezelfde Rows als basis dragen. */
.ceos-memo-vol.ceos-memo-gedeeld { min-height: 8rem; }

/* Het datumveld van een opvolgstap op «Dates» van de opleidingsfiche (visuele controle #28, 29/10/2026): een vaste breedte, met het
   vinkje ernaast op één lijn. Tot dan 598 px voor een datum van tien tekens. */
.ceos-stapdatum { flex: 0 0 11rem; width: 11rem; }

/* De thema's van een formateur in drie kolommen, kolom per kolom alfabetisch (visuele controle #37, 29/10/2026): onder elkaar schoven
   de 14 thema's op 1280 × 800 uit beeld. Elk vakje blijft heel in zijn kolom; onder 768 px één kolom. */
.ceos-themakolommen { columns: 3; column-gap: 1.5rem; }
.ceos-thema { break-inside: avoid; padding: 0.25rem 0; }
@media (max-width: 767.98px) { .ceos-themakolommen { columns: 1; } }

/* Het weekend in de kalender van «Jours d'indisp.» (visuele controle #47, 29/10/2026), met dezelfde kleur als «Planning des visites».
   Een dag van de vorige of volgende maand houdt het grijs van DevExpress (dxbl-scheduler-disabled-color): anders zou een weekend daar
   lichter worden dan een werkdag ernaast. */
.dxbl-sc-time-cell.ceos-kal-weekend:not(.dxbl-scheduler-disabled-color) { background: var(--ceos-vlak-weekend); }
