/*
 * Componentklassen. Datow — Stijlgids & Design System v1.0, secties 4 en 5.
 *
 * GEEN HEXWAARDEN. Alles verwijst naar tokens.css; een test bewaakt dat (gids §7).
 * De canvas/knooppunt-component uit §5 van de gids is bewust NIET geïmplementeerd: deze
 * applicatie heeft geen diagram- of editorweergave.
 *
 * Waar de gids zwijgt staat "NIET IN DE GIDS" met de redenering erbij; die punten staan als
 * openstaand in docs/design-system.md.
 */

/* ============================================================================
   Frame — gids §4. Navigatiekolom en topbalk scrollen niet, alleen main.
   ============================================================================ */

.app {
    display: grid;
    grid-template-columns: var(--nav-width) 1fr;
    grid-template-rows: var(--topbar-height) 1fr;
    grid-template-areas:
        "sidebar topbar"
        "sidebar main";
    height: 100vh;
}

.app__sidebar {
    grid-area: sidebar;
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 14px 12px;
    background: var(--sidebar);
    border-right: 1px solid var(--border);
    overflow-y: auto;
}

.app__topbar {
    grid-area: topbar;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 24px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.app__main {
    grid-area: main;
    padding: var(--page-padding);
    overflow-y: auto;
}

/* De paginakop draagt de titel, de verplichte zin eronder (§6) en rechts hooguit één primaire
   knop (§5). */
.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 18px;
}

.page-head__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Kaartraster: gap, nooit marges per element (§4). */
.grid {
    display: grid;
    gap: var(--gap-grid);
}

.grid--kpi {
    grid-template-columns: repeat(6, 1fr);
}

.grid--2 {
    grid-template-columns: repeat(2, 1fr);
}

/* Master–detail: 1fr plus een vaste detailkolom, detail is sticky (§4). */
.master-detail {
    display: grid;
    grid-template-columns: 1fr var(--detail-width);
    gap: var(--gap-grid);
    align-items: start;
}

.master-detail__detail {
    position: sticky;
    top: 0;
}

.stack {
    display: flex;
    flex-direction: column;
    gap: var(--gap-grid);
}

.row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.row--wrap {
    flex-wrap: wrap;
    gap: 12px;
}

/* Eén stap ruimte boven een toelichting. Bewust een klasse en geen inline marge: §4 wil groepen
   met gap, en losse marges per element zijn precies wat daar niet mag. */
.note {
    margin-top: 12px;
}

.spacer {
    flex: 1;
}

/* ============================================================================
   Kaart — gids §4: "--surface vlak, 1px --border, radius 10px, --shadow."
   ============================================================================ */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow);
}

.card__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--border);
}

.card__body {
    padding: 14px;
}

/* Een kaart met een tabel erin heeft geen eigen padding: de tabel loopt tot de rand. */
.card--flush .card__body {
    padding: 0;
}

.stat {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 13px 14px;
}

/* ============================================================================
   Statusbadge — gids §5
   "Altijd stip + label, nooit kleur alleen. 6px stip, 11px vet, radius 20px.
    In tabellen zonder vlak (alleen stip en gekleurde tekst); in koppen mét
    soft-achtergrond."
   ============================================================================ */

.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-radius: var(--radius-pill);
    font-size: var(--size-badge);
    font-weight: 600;
    line-height: 1.45;
    white-space: nowrap;
}

.badge::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

/* In koppen: mét soft-achtergrond. */
.badge--filled {
    padding: 3px 10px 3px 8px;
}

.badge--ok {
    color: var(--ok-fg);
}

.badge--ok.badge--filled {
    background: var(--ok-soft);
}

.badge--warn {
    color: var(--warn-fg);
}

.badge--warn.badge--filled {
    background: var(--warn-soft);
}

.badge--err {
    color: var(--err-fg);
}

.badge--err.badge--filled {
    background: var(--err-soft);
}

.badge--info {
    color: var(--info-fg);
}

.badge--info.badge--filled {
    background: var(--info-soft);
}

/* Alles wat niet actief is: neutraal (SPEC 14.6). */
.badge--neutral {
    color: var(--text-2);
}

.badge--neutral.badge--filled {
    background: var(--surface-3);
}

/* ErrorCode-waarden zijn GEEN status. Ze staan in mono naast de Failed-badge (SPEC 14.6). */
.error-code {
    font-family: var(--font-mono);
    font-size: var(--size-mono-small);
    color: var(--text-2);
}

/* ============================================================================
   Knoppen — gids §5
   "Maximaal één primaire knop per weergave, rechts uitgelijnd in de paginakop.
    Padding 8×14px, radius 8px, gewicht 600. Icoon links van het label met 7px
    gap. Destructieve acties zijn outline-rood, nooit gevuld."
   ============================================================================ */

.btn {
    display: inline-flex;
    align-items: center;
    gap: var(--gap-button-icon);
    padding: 8px 14px;
    border: 1px solid transparent;
    border-radius: var(--radius-control);
    font-size: var(--size-body);
    font-weight: 600;
    line-height: 1.25;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition), color var(--transition);
}

.btn:hover {
    text-decoration: none;
}

.btn .icon {
    /* Icoon links van het label — de gap hierboven regelt de afstand. */
    order: -1;
}

.btn--primary {
    background: var(--brand);
    border-color: var(--brand);
    color: var(--on-brand);
}

.btn--primary:hover {
    background: var(--brand-2);
    border-color: var(--brand-2);
}

.btn--secondary {
    background: var(--surface);
    border-color: var(--border-strong);
    color: var(--text);
}

.btn--secondary:hover {
    background: var(--surface-2);
}

/* Outline-rood, nooit gevuld. */
.btn--danger {
    background: transparent;
    border-color: var(--err-fg);
    color: var(--err-fg);
}

.btn--danger:hover {
    background: var(--err-soft);
}

.btn--quiet {
    background: transparent;
    border-color: transparent;
    color: var(--text-2);
}

.btn--quiet:hover {
    background: var(--surface-2);
    color: var(--text);
}

/* NIET IN DE GIDS — disabled en de knop tijdens een lopende actie.
   Disabled: verzadiging weg en de aanwijzer verandert, zodat het niet op "niet gevonden" lijkt.
   Bezig: het label BLIJFT staan (§6, "een actie houdt dezelfde naam door de hele flow") en er
   komt een stip-animatie bij; de knop wordt tegelijk inert zodat dubbelklikken niets doet. */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn[data-busy="true"] {
    cursor: progress;
    pointer-events: none;
}

.btn[data-busy="true"]::after {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    animation: pulse 900ms ease-in-out infinite;
}

@keyframes pulse {
    0%,
    100% {
        opacity: 0.25;
    }

    50% {
        opacity: 1;
    }
}

/* ============================================================================
   Tabel — gids §5
   ============================================================================ */

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--size-cell);
}

.table th {
    padding: 9px 10px;
    background: var(--surface-2);
    font-size: var(--size-label);
    font-weight: 600;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-3);
    text-align: left;
    white-space: nowrap;
}

.table td {
    /* Celpadding 10–11px verticaal, 10–18px horizontaal. */
    padding: 10px;
    /* Rijen gescheiden door border-top, nooit zebra. */
    border-top: 1px solid var(--border);
    vertical-align: middle;
}

/* Buitenste kolommen ruimer. */
.table th:first-child,
.table td:first-child {
    padding-left: 18px;
}

.table th:last-child,
.table td:last-child {
    padding-right: 18px;
}

/* Eerste kolom is de identificerende waarde: gewicht 600. */
.table td:first-child {
    font-weight: 600;
}

/* ...en mono in --brand als het een technisch id is. */
.table td:first-child .id {
    font-family: var(--font-mono);
    font-size: var(--size-mono-small);
    font-weight: 500;
    color: var(--brand-fg);
}

/* Status staat altijd in de laatste kolom (gids §5). Dat is een regel over WAAR de status staat,
   niet over uitlijning: de laatste kolom klakkeloos rechts uitlijnen zet ook een gewone
   tekstkolom rechts, en dan leest de tabel als een rekenblad. Vandaar een klasse op de cel. */
.table .cell--status {
    text-align: right;
}

.table__row--clickable {
    cursor: pointer;
}

.table__row--clickable:hover {
    background: var(--surface-2);
}

.table__row--selected,
.table__row--selected:hover {
    background: var(--brand-soft);
}

.table .numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ============================================================================
   Formuliervelden — gids §5
   ============================================================================ */

.field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.field__label {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-2);
}

.field__control {
    width: 100%;
    padding: 8px 10px;
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-control);
    color: var(--text);
    transition: border-color var(--transition);
}

.field__control::placeholder {
    color: var(--text-3);
}

/* "Geen zichtbare focusring buiten de standaard randkleurwissel." De rand wisselt naar
   --focus-border, die tegen zowel het veldvlak als het werkvlak boven 3:1 uitkomt; zie
   tokens.css en het openstaande punt in docs/design-system.md. */
.field__control:focus,
.field__control:focus-visible {
    outline: none;
    border-color: var(--focus-border);
}

/* Velden die een technische waarde bevatten gebruiken mono. */
.field__control--mono {
    font-family: var(--font-mono);
    font-size: var(--size-mono);
}

.field__control:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.field__hint {
    font-size: var(--size-label);
    color: var(--text-3);
}

.field__error {
    font-size: var(--size-label);
    font-weight: 600;
    color: var(--err-fg);
}

.field--invalid .field__control {
    border-color: var(--err);
}

/* AFGELEID — de gids beschrijft geen toggle of checkbox. Bewust de platformcheckbox, getint met
   --brand, en niet een zelfgebouwde schuif: dat laatste zou een nieuwe kleur, een eigen
   focusstand en eigen toetsenbordgedrag vragen voor een besturingselement dat de browser al
   correct levert. Het label staat naast het vakje en niet erboven, want los van elkaar is niet te
   zien waar de vraag bij hoort. */
.field--check {
    flex-direction: row;
    align-items: flex-start;
    gap: 9px;
}

.field--check input[type="checkbox"] {
    width: 15px;
    height: 15px;
    margin-top: 1px;
    flex: 0 0 auto;
    accent-color: var(--brand);
}

.field__check-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.field--check .field__label {
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
}

/* ============================================================================
   Gevoelige waarde — gids §5
   "Nooit uitgeschreven: toon een masker of een verwijzing, in mono, met slotje
    in --accent. Onthullen gebeurt alleen op expliciete actie en wordt vastgelegd."
   ============================================================================ */

.secret {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-family: var(--font-mono);
    font-size: var(--size-mono);
    color: var(--text-2);
}

.secret .icon {
    color: var(--accent);
}

/* ============================================================================
   Codeblok & logvenster — gids §5. Vast palet, in beide thema's identiek.
   ============================================================================ */

.code {
    padding: 12px 14px;
    background: var(--code-bg);
    border-radius: var(--radius-code);
    font-family: var(--font-mono);
    font-size: var(--size-mono);
    line-height: var(--code-line-height);
    color: var(--text);
    overflow-x: auto;
}

/* De tekstkleur binnen het codeblok hangt niet van het thema af: het vlak is altijd donker. */
[data-theme="light"] .code {
    color: var(--surface);
}

.code__time,
.code__comment {
    color: var(--code-muted);
}

.code__key {
    color: var(--code-key);
}

.code__ok {
    color: var(--code-ok);
}

.code__warn {
    color: var(--code-warn);
}

.code__err {
    color: var(--code-err);
}

/* ============================================================================
   Iconen — gids §5
   "24×24 viewBox, stroke-width 1.7, ronde uiteinden, geen vulling. Weergave
    14–18px, standaard currentColor. Neutrale iconen zijn --text-3."
   ============================================================================ */

.icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
}

.icon--neutral {
    color: var(--text-3);
}

.icon--18 {
    width: 18px;
    height: 18px;
}

.icon--14 {
    width: 14px;
    height: 14px;
}

/* Iconvlakken zijn 30–40px met radius 8–10px op een soft-achtergrond. */
.icon-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--radius-icon);
    background: var(--accent-soft);
    color: var(--accent);
}

.icon-tile--brand {
    background: var(--brand-soft);
    color: var(--brand-fg);
}

.icon-tile--ok {
    background: var(--ok-soft);
    color: var(--ok-fg);
}

.icon-tile--warn {
    background: var(--warn-soft);
    color: var(--warn-fg);
}

.icon-tile--err {
    background: var(--err-soft);
    color: var(--err-fg);
}

/* ============================================================================
   Navigatie & tabs — gids §5
   ============================================================================ */

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 10px 2px;
    color: var(--text);
}

.brand:hover {
    text-decoration: none;
}

.brand__name {
    display: block;
    font-weight: 600;
}

.nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.nav__group-title {
    padding: 0 10px;
    margin-bottom: 4px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--text-3);
}

.nav__item {
    display: flex;
    align-items: center;
    gap: var(--gap-nav-icon);
    padding: 8px 10px;
    border-radius: var(--radius-control);
    font-weight: 500;
    color: var(--text-2);
    transition: background var(--transition), color var(--transition);
}

.nav__item:hover {
    background: var(--surface-2);
    color: var(--text);
    text-decoration: none;
}

.nav__item--active,
.nav__item--active:hover {
    background: var(--brand-soft);
    color: var(--brand-fg);
    font-weight: 600;
}

.nav__item--active .icon {
    color: var(--brand-fg);
}

/* Op de stijlgidspagina staat de navigatie los van de zijbalk; daar hoort hij binnen een kaart
   te blijven in plaats van tegen de rand te plakken. */
.nav--demo {
    padding: 8px;
    background: var(--sidebar);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
}

/* De swatchtabel van de stijlgids: elk token als vlak met zijn naam en waarde eronder. */
.swatches {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
    margin-top: 8px;
}

.swatch__chip {
    height: 42px;
    background: var(--swatch);
    border: 1px solid var(--border);
    border-radius: var(--radius-control);
}

.swatch__name {
    display: block;
    margin-top: 5px;
    font-family: var(--font-mono);
    font-size: var(--size-mono-small);
    font-weight: 500;
}

.swatch__value {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--size-mono-small);
    color: var(--text-3);
}

/* Segmented tabs zitten in een --surface-2 spoor met 2–3px padding; de actieve tab is een
   --surface pil met schaduw. */
.tabs {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    background: var(--surface-2);
    border-radius: var(--radius-control);
}

.tabs__tab {
    padding: 5px 12px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font-size: var(--size-cell);
    font-weight: 500;
    color: var(--text-2);
    cursor: pointer;
}

.tabs__tab:hover {
    color: var(--text);
}

.tabs__tab[aria-selected="true"] {
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
    box-shadow: var(--shadow);
}

/* ============================================================================
   Tijdlijn & stappen — gids §5
   ============================================================================ */

.timeline {
    display: flex;
    flex-direction: column;
}

.timeline__item {
    position: relative;
    display: flex;
    gap: 12px;
    padding-bottom: 16px;
}

.timeline__item:last-child {
    padding-bottom: 0;
}

/* 1,5px verbindingslijn in --border, tussen de stippen door. */
.timeline__item:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 13px;
    bottom: 0;
    width: 1.5px;
    background: var(--border);
}

/* 9px gekleurde stip. */
.timeline__dot {
    position: relative;
    z-index: 1;
    width: 9px;
    height: 9px;
    margin-top: 5px;
    border-radius: 50%;
    background: var(--text-3);
    flex-shrink: 0;
}

.timeline__dot--ok {
    background: var(--ok);
}

.timeline__dot--info {
    background: var(--info);
}

.timeline__dot--err {
    background: var(--err);
}

.timeline__dot--pending {
    background: var(--surface-3);
    box-shadow: inset 0 0 0 1.5px var(--border-strong);
}

/* Titel op 500 met metadata ERONDER in --text-3 mono — dus block, niet naast elkaar. */
.timeline__title {
    display: block;
    font-weight: 500;
}

.timeline__meta {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--size-mono-small);
    color: var(--text-3);
}

/* Stappenreeksen: genummerde 24–26px cirkels. */
.steps {
    display: flex;
    align-items: center;
    gap: 10px;
}

.steps__step {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--text-2);
}

.steps__number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: var(--surface-3);
    color: var(--text-2);
    font-size: var(--size-cell);
    font-weight: 600;
}

.steps__step--done .steps__number {
    background: var(--ok);
    color: var(--on-ok);
}

.steps__step--active .steps__number {
    background: var(--brand);
    color: var(--on-brand);
}

.steps__step--active {
    color: var(--text);
    font-weight: 600;
}

.steps__line {
    width: 28px;
    height: 1.5px;
    background: var(--border);
}

/* ============================================================================
   NIET IN DE GIDS — de aanvullingen uit SPEC 14.4.
   Elk hiervan is opgebouwd uit onderdelen die de gids wél vastlegt, zodat er geen tweede
   vormtaal ontstaat. Zie docs/design-system.md.
   ============================================================================ */

/* Lege staat. Twee varianten, want "nog niets aangemaakt" en "geen resultaten voor dit filter"
   zijn verschillende situaties met verschillende uitwegen (SPEC 14.3). Vandaar geen eigen
   vormgeving maar hetzelfde iconvlak, dezelfde tekstschaal en één knop. */
.empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 44px 24px;
    text-align: center;
}

.empty__title {
    font-size: var(--size-card-title);
    font-weight: 600;
}

.empty__body {
    max-width: 46ch;
    color: var(--text-2);
}

/* Paginering. Server-side paging is een eis; de control is bewust smal: vorige, volgende en
   waar je bent. Geen paginanummers, want bij 90 dagen jobs zijn dat er honderden. */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 18px;
    border-top: 1px solid var(--border);
    color: var(--text-2);
    font-size: var(--size-cell);
}

.pager__range {
    font-variant-numeric: tabular-nums;
}

.pager__controls {
    display: flex;
    gap: 6px;
}

/* Bevestiging bij een destructieve actie. De gids geeft wel de destructieve knop, niet de
   bevestiging. Een <dialog> en geen eigen overlay: die regelt focus-trapping, Escape en de
   inert-achtergrond zelf. */
.modal {
    width: min(420px, calc(100vw - 48px));
    padding: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow);
    color: var(--text);
}

.modal::backdrop {
    background: var(--backdrop);
}

.modal__head {
    padding: 14px 16px 0;
}

.modal__body {
    padding: 8px 16px 16px;
    color: var(--text-2);
}

.modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
}

/* Melding na een actie. De -soft statuskleuren zijn hier volgens de gids voor bedoeld; de vorm
   is die van een kaart, zodat er geen nieuwe radius of schaduw bijkomt. */
.toast-stack {
    position: fixed;
    right: 24px;
    bottom: 24px;
    z-index: 40;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.toast {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    max-width: 380px;
    padding: 11px 13px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--text-3);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow);
}

.toast--ok {
    border-left-color: var(--ok);
    background: var(--ok-soft);
}

.toast--warn {
    border-left-color: var(--warn);
    background: var(--warn-soft);
}

.toast--err {
    border-left-color: var(--err);
    background: var(--err-soft);
}

.toast__title {
    display: block;
    font-weight: 600;
}

/* De toelichting staat onder de titel, niet erachter. */
.toast > span > span {
    display: block;
}

/* Laadstaat van een vlak. Geen spinner: een skeleton laat de vorm van wat er komt al zien, en
   een beheerder die elke minuut ververst wil geen draaiend icoon in beeld. */
.skeleton {
    display: block;
    background: var(--surface-3);
    border-radius: 4px;
    animation: shimmer 1.2s ease-in-out infinite;
}

.skeleton--title {
    width: 40%;
    height: 14px;
}

.skeleton--line {
    width: 100%;
    height: 10px;
}

.skeleton-demo {
    gap: 8px;
}

@keyframes shimmer {
    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.55;
    }
}

/* Alleen voor screenreaders — labels die visueel al uit de context blijken. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ============================================================================
   Responsive — NIET IN DE GIDS. Desktop-first, minimum 1280px; onder 1000px klapt de
   navigatiekolom in tot alleen iconen. Dit is een beheerinterface, geen publieke site.
   ============================================================================ */

@media (max-width: 1000px) {
    .app {
        grid-template-columns: 56px 1fr;
    }

    .nav__item span,
    .nav__group-title {
        display: none;
    }

    .nav__item {
        justify-content: center;
    }

    .master-detail {
        grid-template-columns: 1fr;
    }

    .master-detail__detail {
        position: static;
    }

    .grid--kpi {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* Het filterblok boven de joblijst: een raster dat meeschaalt, geen vaste kolommen. */
.grid--filters {
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    align-items: start;
}

/* De uitklapbare legenda onder de joblijst (SPEC 14.6). */
.legend > summary {
    cursor: pointer;
    list-style: none;
}

.legend > summary::-webkit-details-marker {
    display: none;
}

.legend > summary::after {
    content: "";
    width: 7px;
    height: 7px;
    margin-left: auto;
    border-right: 1.5px solid var(--text-3);
    border-bottom: 1.5px solid var(--text-3);
    transform: rotate(45deg);
    transition: transform var(--transition);
}

.legend[open] > summary::after {
    transform: rotate(-135deg);
}

/* ============================================================================
   Tenantwisselaar — de combobox in de topbalk
   ----------------------------------------------------------------------------
   NIET IN DE GIDS. De gids kent geen wisselaar; de vorm is die van een
   secundaire knop (§5) met een select erin, zodat er geen nieuwe radius, hoogte
   of randkleur bijkomt. De chevron is de submitknop: zonder JavaScript wisselt
   de beheerder ermee, met JavaScript dient het formulier zichzelf in bij
   wijziging en blijft de chevron puur de affordance uit het ontwerp.
   ============================================================================ */

.tenant-switch {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 4px 0 10px;
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-control);
    transition: border-color var(--transition);
}

.tenant-switch:focus-within {
    border-color: var(--focus-border);
}

/* Het vierkantje uit het ontwerp. Gevuld als er een tenant gekozen is, hol als
   er geen keuze staat — zo is "geen tenant" ook zonder de tekst te lezen te
   zien, en dat is precies de stand waarin elke tenant-scoped query nul rijen
   geeft. */
.tenant-switch__swatch {
    width: 9px;
    height: 9px;
    flex-shrink: 0;
    border-radius: 2px;
    border: 1.5px solid var(--brand-fg);
    background: var(--brand-fg);
}

.tenant-switch__swatch--empty {
    background: transparent;
    border-color: var(--text-3);
}

/* De select draagt de rand van de wisselaar, niet zijn eigen: samen zijn ze
   één besturingselement. De eigen pijl van de browser gaat weg omdat de
   chevron er al staat. */
.tenant-switch__select {
    appearance: none;
    max-width: 220px;
    padding: 7px 0;
    background: transparent;
    border: none;
    color: var(--text);
    font-size: var(--size-body);
    font-weight: 600;
    cursor: pointer;
    text-overflow: ellipsis;
}

.tenant-switch__select:focus,
.tenant-switch__select:focus-visible {
    outline: none;
}

.tenant-switch__go {
    display: inline-flex;
    align-items: center;
    padding: 5px;
    border: none;
    border-radius: var(--radius-control);
    background: transparent;
    color: var(--text-3);
    cursor: pointer;
    transition: color var(--transition), background var(--transition);
}

.tenant-switch__go:hover {
    background: var(--surface-3);
    color: var(--text);
}

/* ============================================================================
   Tenantkaart — het tenantoverzicht
   ----------------------------------------------------------------------------
   NIET IN DE GIDS. Opgebouwd uit bestaande onderdelen: het kaartvlak van §4,
   de statusbadge van §5 en de statwaarde van §3. Er komt geen kleur bij; de
   kaarten onderscheiden zich met initialen, niet met een per-tenant kleur —
   dat zou hexwaarden buiten tokens.css betekenen (§7).
   ============================================================================ */

.grid--cards {
    grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
    align-items: start;
}

.tenant-card {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow);
    transition: border-color var(--transition);
}

.tenant-card:hover {
    border-color: var(--border-strong);
}

/* De gekozen tenant. De rand alleen zou een kleurverschil van weinig contrast
   zijn; het label ACTIEF in de kop draagt dezelfde informatie in tekst — nooit
   kleur alleen (§5). */
.tenant-card--active {
    border-color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent-soft), var(--shadow);
}

/* Een gedeactiveerde tenant blijft leesbaar: het job log en de layouts mogen
   nog bekeken worden (SPEC 5). Hij wordt dus gedempt, niet weggestreept. */
.tenant-card--inactive .tenant-card__identity {
    opacity: 0.7;
}

.tenant-card__head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 14px;
}

.tenant-card__identity {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    min-width: 0;
}

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: var(--radius-icon);
    background: var(--brand-soft);
    color: var(--brand-fg);
    font-size: var(--size-label);
    font-weight: 700;
    letter-spacing: var(--tracking-label);
}

.tenant-card__name {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* De bestemming op de broker. Afgekapt en niet afgebroken: een halve vhost is
   nog te herkennen, een over drie regels gevouwen queuenaam duwt de kaarten
   scheef. De volledige waarde staat op het instellingenscherm. */
/* De slug rechtsboven op de kaart. Bewust GEEN .badge: die is in §5 de statusbadge en draagt
   altijd een stip, en de slug is geen status maar een identificatie. Met .badge zou de kaart
   twee stippen dragen die verschillende dingen betekenen. */
.tenant-card__slug {
    padding: 3px 8px;
    border-radius: var(--radius-pill);
    background: var(--surface-3);
    color: var(--text-2);
    white-space: nowrap;
}

/* Het woord ACTIEF naast de naam van de gekozen tenant. Een eigen klasse en geen inline
   stijl: §7 wil dat kleur uit een component komt, niet uit de markup. */
.tenant-card__chosen {
    color: var(--accent);
}

.tenant-card__where {
    display: block;
    margin-top: 2px;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Drie gelijke kolommen voor de tellers, plus een vierde op maat voor de statusbadge.
   Gelijk verdeeld en niet op inhoudsbreedte: bij twintig kaarten naast elkaar staan de
   getallen dan op dezelfde plek, en dan is "waar loopt het vast" een blik in plaats van
   drie keer lezen. minmax(0, 1fr) omdat een 1fr-kolom anders niet onder zijn inhoud
   krimpt en de rij op de smalste kaart (380px, of de volle breedte onder 900px) alsnog
   buiten de rand zou lopen. */
.tenant-card__stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
    align-items: end;
    gap: 12px;
    padding: 12px 14px;
    border-top: 1px solid var(--border);
}

.tenant-card__stats .badge {
    justify-self: end;
}

.tenant-card__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-top: 1px solid var(--border);
}

/* De kaartstat heeft geen eigen padding: die zit al op .tenant-card__stats. */
.tenant-card__stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Alleen als er iets mislukt is. Kleur draagt hier geen informatie die niet ook in
   het label en het getal staat (§5); het maakt de kaart met werk alleen sneller
   vindbaar tussen twintig andere. */
.tenant-card__failed {
    color: var(--err-fg);
}

/* Een breed formulier past niet in de 420px van .modal: zeven velden op die
   breedte wordt een koker. */
.modal--wide {
    width: min(560px, calc(100vw - 48px));
}

@media (max-width: 900px) {
    .grid--cards {
        grid-template-columns: 1fr;
    }

    .tenant-switch__select {
        max-width: 140px;
    }
}
