/* De opmaak die in templates/base.html.twig stond, als eigen bestand.
   Verplaatst op 3 november 2026 (JOEY-240, fase 9): 898 regels CSS in een
   sjabloon zijn niet te vinden en niet te cachen.

   Dit bestand wordt geladen op precies de plek waar dat <style>-blok stond,
   dus vóór websignaal.css. Dat is met opzet. Zet het er niet achter, dan
   verandert het beeld op plekken die je niet verwacht.

   **Het zijn twee lagen, geen dubbeling.** Op 4 november 2026 nagemeten:
   37 selectors komen in allebei de bestanden voor, maar op één na zetten ze
   verschillende eigenschappen. Dit bestand geeft de bouw (maat, padding,
   positie, randen), websignaal.css geeft de huisstijl eroverheen (kleur,
   typografie, ronding). `.kpi-block` krijgt hier zijn witte vlak en padding en
   daar zijn blauwe vulling; `.ws-btn` krijgt hier zijn hele vorm en daar zijn
   hoogte. Weghalen van wat "dubbel" lijkt breekt dus de helft van de
   schermen; het is dezelfde opzet als een thema bovenop een basisbestand.

   De enige echte dubbeling was `.ws-view:hover`, woord voor woord gelijk in
   beide bestanden. Die staat sinds 4 november 2026 alleen nog in
   websignaal.css. */

/* ===== Uit partials/head-css.html.twig, de gedeelde <head>. Stond daar als
   <style>-blok en geldt ook voor de inlogpagina, die verder niets van ons
   laadt. Verplaatst op 4 november 2026. ===== */
    [x-cloak] { display: none !important; }

    /* Gevulde primary-knoppen volgen de site: het accent met de inkt uit het logo,
       niet met wit. Het thema zet ze via --bs-btn-* op de donkere tint, en dat
       is precies de variabele die hier opnieuw gezet wordt. De 76 templates met
       .btn-primary hoeven zo niet aangeraakt te worden.

       Alleen de gevulde knoppen. Alles wat het thema verder "primary" noemt,
       tekst, links, randen en actieve items, houdt de donkere tint: het accent op wit
       haalt maar 2,8 staat tot 1 en is dan niet te lezen. */
    .btn-primary {
        --bs-btn-color: #fff;
        --bs-btn-bg: var(--ws-ink);
        --bs-btn-border-color: var(--ws-ink);
        --bs-btn-hover-color: #fff;
        --bs-btn-hover-bg: var(--ws-primary);
        --bs-btn-hover-border-color: var(--ws-primary);
        --bs-btn-active-color: #fff;
        --bs-btn-active-bg: var(--ws-primary);
        --bs-btn-active-border-color: var(--ws-primary);
        --bs-btn-disabled-color: #fff;
        --bs-btn-disabled-bg: var(--ws-ink);
        --bs-btn-disabled-border-color: var(--ws-ink);
    }

    .btn-outline-primary {
        --bs-btn-hover-color: #fff;
        --bs-btn-hover-bg: var(--ws-ink);
        --bs-btn-hover-border-color: var(--ws-ink);
        --bs-btn-active-color: #fff;
        --bs-btn-active-bg: var(--ws-primary);
        --bs-btn-active-border-color: var(--ws-primary);
    }

    /* Een badge in de huisstijlkleur krijgt dezelfde inkt, anders valt de witte
       tekst weg op het accent. */
    .badge.bg-primary {
        background-color: var(--ws-accent) !important;
        color: var(--ws-ink) !important;
    }

    /* Koppen in Archivo, lopende tekst in Inter, net als op websignaal.nl. De
       body volgt vanzelf via --bs-font-sans-serif in variables.css; koppen
       hebben een eigen regel nodig, want die erven alleen. */
    h1, h2, h3, h4, h5, h6,
    .h1, .h2, .h3, .h4, .h5, .h6 {
        font-family: var(--ws-font-head);
        letter-spacing: -0.01em;
    }

    /* Globale leesbaarheid voor 'rustige' knoppen (o.a. Annuleren in modals).
       Thema-/app-CSS gaf .btn-light witte tekst -> onleesbaar op een lichte
       achtergrond. Hier één keer goed gezet voor het hele CRM. */
    .btn-light,
    .btn-light:focus,
    .btn-light:active,
    .btn-outline-secondary {
        color: #1f2937 !important;
        background-color: #f1f3f5;
        border-color: #d1d5db;
    }
    .btn-light:hover,
    .btn-outline-secondary:hover {
        color: #111827 !important;
        background-color: #e5e7eb;
        border-color: #cbd5e1;
    }

    /* Een keuzelijst en een tekstveld met dezelfde Bootstrap-padding worden
       toch niet even hoog: browsers negeren line-height: 1.5 voor de regel in
       een <select> en rekenen met de eigen regelhoogte van het lettertype. Op
       elke rij waar beide naast elkaar staan zie je dat verschil, dus hier
       één keer rechtgezet voor het hele CRM.

       Dezelfde formule die Bootstrap zelf voor .form-control-color gebruikt:
       1,5em regel plus tweemaal .47rem padding plus de randen. De kleine en
       grote varianten blijven erbuiten, die hebben hun eigen maat. */
    .form-control:not(.form-control-sm):not(.form-control-lg):not(textarea),
    .form-select:not(.form-select-sm):not(.form-select-lg) {
        min-height: calc(1.5em + 0.94rem + calc(var(--bs-border-width) * 2));
    }

    /* Elke .form-select wordt door Select2 vervangen (zie initializeSelect2 in
       app.js), en Select2 zet op zijn eigen element een vaste height van 28px.
       Daarom hielp de regel hierboven niet: die raakt het originele element,
       dat verborgen wordt. Hier dezelfde maat als een tekstveld, met de inhoud
       verticaal gecentreerd in plaats van op een vaste regelhoogte. */
    .select2-container--default .select2-selection--single {
        height: auto;
        min-height: calc(1.5em + 0.94rem + calc(var(--bs-border-width) * 2));
        display: flex;
        align-items: center;
        padding: 0 1.75rem 0 0.75rem;
    }

    .select2-container--default .select2-selection--single .select2-selection__rendered {
        line-height: 1.5;
        padding-left: 0;
        padding-right: 0;
    }

    /* Het pijltje staat standaard op een vaste hoogte van 26px en zweeft dan
       boven in het hogere vak. */
    .select2-container--default .select2-selection--single .select2-selection__arrow {
        top: 0;
        right: 0.25rem;
        height: 100%;
    }


    /* On-hold tijdregistraties: zachte amber-markering */
    .badge.bg-onhold { background-color: #f3c969; color: #5c4400; font-weight: 600; }
    .is-onhold { background-color: #fff8e6 !important; }
    tr.is-onhold > td { background-color: #fff8e6 !important; }

    /* Compacte on-hold kaartjes in de tijdregistratie-popup */
    .onhold-card {
        background: #fffaf0;
        border: 1px solid #f0e2c4;
        border-left: 3px solid #e6a23c;
        border-radius: 4px;
        padding: .35rem .5rem;
        margin-bottom: .35rem;
    }
    .onhold-card .onhold-title { font-size: .78rem; font-weight: 600; line-height: 1.2; }
    .onhold-card .onhold-note { font-size: .72rem; color: #8a7a55; }
    .onhold-card .onhold-sessions { font-size: .72rem; color: var(--ws-muted); list-style: none; margin: .2rem 0 .25rem; padding-left: 0; }
    .onhold-card .onhold-sessions li { padding: .05rem 0; }
    .onhold-card .onhold-hours { font-size: .72rem; font-weight: 700; color: #b9770f; white-space: nowrap; }
    .onhold-card .onhold-continue {
        font-size: .72rem;
        padding: .2rem .6rem;
        background-color: var(--ws-primary);
        border-color: var(--ws-primary);
        color: #fff;
        font-weight: 600;
    }
    .onhold-card .onhold-continue:hover,
    .onhold-card .onhold-continue:focus {
        background-color: #5e54d6;
        border-color: #5e54d6;
        color: #fff;
    }
    #onHoldPanel .card-header { font-size: .78rem; font-weight: 600; }

    /* On-hold checkbox: duidelijk paars kader */
    .onhold-toggle-box {
        display: flex;
        align-items: center;
        gap: .6rem;
        border: 1.5px solid var(--ws-primary);
        background: #f6f5ff;
        border-radius: 8px;
        padding: .55rem .75rem;
    }
    .onhold-toggle-box .form-check-input {
        width: 1.35em;
        height: 1.35em;
        margin: 0;
        border: 2px solid var(--ws-primary);
        cursor: pointer;
        flex-shrink: 0;
    }
    .onhold-toggle-box .form-check-input:checked {
        background-color: var(--ws-primary);
        border-color: var(--ws-primary);
    }
    .onhold-toggle-box .form-check-input:focus {
        box-shadow: 0 0 0 .2rem rgba(115, 103, 240, .25);
        border-color: var(--ws-primary);
    }
    .onhold-toggle-box .form-check-label { cursor: pointer; margin: 0; }

    /* Tabs in de tijdregistratie-popup */
    #timeRegTabs { border-bottom: 2px solid #ece9fd; gap: .25rem; }
    #timeRegTabs .nav-link {
        border: none;
        border-bottom: 2px solid transparent;
        margin-bottom: -2px;
        color: var(--ws-muted);
        font-weight: 600;
        font-size: .9rem;
        padding: .45rem .9rem;
        border-radius: 6px 6px 0 0;
        transition: color .15s, background-color .15s, border-color .15s;
    }
    #timeRegTabs .nav-link:hover { color: var(--ws-primary); background-color: #f6f5ff; }
    #timeRegTabs .nav-link.active {
        color: var(--ws-primary);
        background-color: transparent;
        border-bottom-color: var(--ws-primary);
    }
    #timeRegTabs .nav-link.active .badge.bg-onhold { background-color: #f3c969; }

    /* Knoppen in een paginakop: één maat voor het hele CRM.
       Elke pagina koos zijn eigen combinatie (px-3 py-1.5 naast
       px-4 py-2), waardoor de knop rechtsboven per scherm verschilde.
       Eigen klassen en geen utilities: die staan in deze build op
       !important en zijn dan niet meer te overschrijven. */
    .ws-btn {
        display: inline-flex;
        align-items: center;
        padding: .5rem 1rem;
        font-size: .875rem;
        font-weight: 500;
        line-height: 1.375rem;
        border-radius: 6px;
        border: 1px solid var(--ws-hair-blue);
        background: #fff;
        color: var(--ws-ink);
        white-space: nowrap;
        text-decoration: none;
        transition: background-color .15s ease, color .15s ease, border-color .15s ease;
    }

    .ws-btn:hover {
        background: var(--ws-primary-bg);
        border-color: var(--ws-primary);
        color: var(--ws-ink);
    }

    /* De hoofdactie is de zwarte knop van de site, met blauw bij hover.
       Zo staat "plan een gesprek" daar in de navigatie:
       `background #000`, en `:hover background var(--ws-primary)`. Zwart op
       wit haalt 21 staat tot 1, dus daar leest witte tekst altijd op. */
    .ws-btn--primary {
        background: var(--ws-ink);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--primary:hover {
        background: var(--ws-primary);
        border-color: transparent;
        color: #fff;
    }

    /* Bewerken is overal dezelfde knop, met het potlood
       (mdi-pencil-outline). In een tabelrij is het alleen het icoon in de
       huisstijlkleur, in een kop dezelfde gevulde knop als de hoofdactie:
       op een detailpagina ís bewerken de hoofdactie. */
    .ws-btn--edit {
        background: var(--ws-ink);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--edit:hover {
        background: var(--ws-primary);
        border-color: transparent;
        color: #fff;
    }

    /* Bekijken: hetzelfde omhulsel als bewerken en verwijderen, maar
       donkergrijs op hover. Kijken verandert niets, dus het krijgt geen
       eigen kleur zoals het blauw van bewerken of het rood van
       verwijderen. Stond overal op hover:text-primary-600, en dat is in
       onze build net zo grijs als de rusttoestand: je zag niets. */
    .ws-view {
        color: var(--ws-muted);
    }

    /* De hover staat alleen in websignaal.css: daar stond hij woord voor
       woord hetzelfde, en dat was de enige echte dubbeling tussen de twee
       bestanden. */

    /* In rust grijs als elke andere rij-actie, blauw zodra je erover
       gaat: dezelfde omgang als de prullenbak, die grijs is en rood
       wordt. */
    .ws-edit {
        color: var(--ws-muted);
    }

    .ws-edit:hover {
        color: var(--ws-primary);
        background: var(--ws-primary-bg);
    }

    /* De prullenbak in een rij: grijs in rust, rood zodra je erover
       gaat. Zelfde maatvoering als .ws-view en .ws-edit, zodat de drie
       rij-acties naast elkaar even groot zijn. */
    .ws-delete {
        color: var(--ws-muted);
    }

    .ws-delete:hover {
        color: var(--ws-danger);
        background: var(--ws-primary-bg);
    }

    /* AI-acties krijgen het paars van vóór de huisstijlwissel, met witte
       tekst en het sterretje (mdi-creation). Dat paars staat live nog op
       een deel van de knoppen en is wat mensen met AI associëren; cyaan
       stond te dicht bij het accent van de site. Wit op dit paars haalt
       6,5 staat tot 1.

       De knop was tot 3 nov 2026 zwart (dezelfde als de hoofdactie) of
       een rauwe Bootstrap-knop, afhankelijk van het scherm. */
    .ws-btn--ai {
        background: var(--ws-ai);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--ai:hover {
        background: var(--ws-ai-h);
        border-color: transparent;
        color: #fff;
    }

    /* Beoordelen, bekijken, een tweede mening vragen: de donkere knop uit
       de accentfamilie, met witte tekst. Niet het lichte --ws-accent zelf:
       wit daarop haalt 2,8 staat tot 1 en leest niet, deze 5,1. */
    .ws-btn--info {
        background: var(--ws-primary);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--info:hover {
        background: var(--ws-primary-h);
        border-color: transparent;
        color: #fff;
    }

    /* Akkoord: de knop die vastlegt dat iets doorgaat. Groen, want het is de
       tegenhanger van de rode ernaast en dat leest sneller dan twee witte
       knoppen met een woord erop. Dit is dezelfde groen als de badge
       (--ws-success); wit erop haalt 5,0 staat tot 1.

       Spaarzaam gebruiken: alleen waar een rode tegenhanger naast staat, zoals
       bij een offerte accepteren of afwijzen. Een gewone bevestiging is zwart. */
    .ws-btn--success {
        background: var(--ws-success);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--success:hover {
        background: var(--ws-badge-green);
        border-color: transparent;
        color: #fff;
    }

    /* Kopiëren maakt iets nieuws van iets bestaands: geen hoofdactie,
       maar ook niet onschuldig, want je houdt er een tweede record aan
       over. Geel met inkt erop (8,3 staat tot 1); wit zou 2,2 halen. */
    .ws-btn--copy {
        background: var(--ws-warning);
        border-color: transparent;
        color: var(--ws-ink);
    }

    .ws-btn--copy:hover {
        background: var(--ws-badge-amber);
        border-color: transparent;
        color: #fff;
    }

    /* Kerngetallen boven de tabbladen
       Zelfde blokken als op de klantenkaart, die ze als .kpi-block in zijn eigen
       style-block heeft staan. Hier zodat elke detailpagina ze kan gebruiken. */
    .kpi-blocks {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 1rem;
    }

    .kpi-blocks--6 {
        grid-template-columns: repeat(6, 1fr);
    }

    /* Zes naast elkaar past niet op een laptopscherm; dan twee rijen
       van drie in plaats van blokken die te smal worden voor hun
       label. */
    @media (max-width: 1400px) {
        .kpi-blocks--6 {
            grid-template-columns: repeat(3, 1fr);
        }
    }

    .kpi-block {
        background: #fff;
        border-radius: 8px;
        padding: 1.25rem;
        box-shadow: 0 1px 3px rgba(0,0,0,0.04);
        text-align: center;
    }

    /* Staat er in de rij iets hogers, zoals een grafiek, dan rekken de
       andere blokken mee. Met deze klasse blijft hun inhoud verticaal
       in het midden in plaats van bovenaan tegen de rand te plakken. */
    .kpi-blocks.kpi-blocks--centered .kpi-block {
        display: flex;
        flex-direction: column;
        justify-content: center;
    }

    /* Het pictogram boven het getal. Halfdoorzichtig wit: het moet de
       tegel herkenbaar maken, niet de aandacht van het getal afpakken. */
    /* Een blok dat ergens op wijst: een datum die verlopen is, een taak die te
       laat is. Stond in vier sjablonen los gedefinieerd met #dc3545, en op twee
       daarvan werd hij door de blauwe band overruled. */
    .kpi-block-danger {
        box-shadow: inset 0 0 0 2px var(--ws-danger);
    }

    .kpi-block-icon {
        display: block;
        font-size: 1.5rem;
        line-height: 1;
        margin-bottom: .35rem;
        color: rgba(255, 255, 255, .75);
    }

    .kpi-block-value {
        font-size: 1.75rem;
        font-weight: 600;
        color: #212529;
        line-height: 1;
    }

    /* Een kerngetal dat geen getal is, zoals een naam of een klant:
       die houdt zijn eigen maat in plaats van die van de cijfers. */
    .kpi-block-value .ws-user-tag {
        font-size: .85rem;
        font-weight: 600;
    }

    .kpi-block-value.kpi-block-value--tekst {
        font-size: 1rem;
        font-weight: 600;
        line-height: 1.3;
        padding: .25rem 0;
    }

    .kpi-block-value--tekst a {
        color: inherit;
        text-decoration: none;
    }

    .kpi-block-value--tekst a:hover {
        text-decoration: underline;
    }

    /* Een detail dat bij het kerngetal hoort maar er geen eigen vak waard
       is: de taak bij een project, het uurtarief bij een bedrag. */
    /* Content Sections */
    .content-section {
        background: #fff;
        border-radius: 8px;
        margin-bottom: 1rem;
        box-shadow: 0 1px 3px rgba(0,0,0,0.04);
    }

    .section-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 1rem 1.25rem;
        border-bottom: 1px solid #f0f0f0;
    }

    .section-title {
        font-size: 0.8rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.03em;
        color: var(--ws-ink);
    }

    .section-body {
        padding: 1.25rem;
    }

    /* Het kleine linkje rechts in een sectiekop ("Aanpassen", "Aanvullen").
       Stond alleen in het style-blok van de klantenkaart, waardoor hij op elke
       andere detailpagina terugviel op de standaardlink van Bootstrap: fel blauw
       en groter dan bedoeld. */
    .section-header-link {
        font-size: 0.75rem;
        font-weight: 500;
        color: var(--ws-primary);
        text-decoration: none;
    }

    .section-header-link:hover {
        text-decoration: underline;
    }

    /* Compacter op een smal scherm. */
    @media (max-width: 767.98px) {
        .content-section { border-radius: 6px; margin-bottom: .75rem; }
        .section-header { padding: .75rem 1rem; flex-wrap: wrap; gap: .5rem; }
        .section-title { font-size: .7rem; }
        .section-body { padding: 1rem; }
    }

    /* Twee kolommen naast elkaar even hoog: zet .ws-column op elke
       kolom van de rij. De onderste sectie van een kolom rekt dan mee
       tot de rijhoogte, zodat links en rechts onderaan gelijk
       eindigen, welke kant ook de langste is. Op een smal scherm
       vallen de kolommen onder elkaar en vervalt het rekken vanzelf. */
    .ws-column {
        display: flex;
        flex-direction: column;
    }

    .ws-column .content-section:last-child {
        flex: 1;
        margin-bottom: 0;
        display: flex;
        flex-direction: column;
    }

    /* Alleen de onderste sectie rekt mee, en binnen die sectie alleen een
       body die zelf onderaan staat. Staat er nog een tabel of een rij
       knoppen onder, dan zou het rekken een gat midden in de kaart
       maken in plaats van onderaan. */
    .ws-column .content-section:last-child .section-body:last-child {
        flex: 1;
        display: flex;
        flex-direction: column;
    }

    /* Gegevens in een sectie: label links, waarde rechts. */
    .info-row {
        display: flex;
        justify-content: space-between;
        padding: 0.5rem 0;
        border-bottom: 1px solid #f5f5f5;
    }

    .info-row:last-child {
        border-bottom: none;
    }

    .info-label {
        color: var(--ws-muted);
        font-size: 0.875rem;
    }

    .info-value {
        font-size: 0.875rem;
        color: #212529;
    }

    .info-value a {
        color: var(--ws-primary);
        text-decoration: none;
    }

    .info-value a:hover {
        text-decoration: underline;
    }

    /* De kwartierknoppen onder een urenveld, zie
       components/_hours_input.html.twig. Het zijn hulpknoppen, geen
       hoofdactie: opslaan staat in de voet van het venster en is daar de
       enige zwarte knop. Vier zwarte blokken ernaast vroegen evenveel
       aandacht als het opslaan zelf, dus hier de gewone witte knop.
       Opmerking Patrick, 5 november 2026.

       Geen btn-group meer: die plakt de knoppen aan elkaar en laat geen
       ruimte toe. Een flex-rij met een gap doet hetzelfde zonder dat. */
    .ws-hours-buttons {
        display: flex;
        flex-wrap: wrap;
        gap: .5rem;
        margin-top: .75rem;
    }

    /* Even hoog als het invoerveld erboven en ruimer dan een knop in een
       paginakop: deze worden met de muis aangeklikt, vaak een paar keer
       achter elkaar. */
    .ws-hours-buttons .ws-btn {
        min-height: 40px;
        padding: .5rem 1.25rem;
        justify-content: center;
    }

    /* Reset haalt als enige iets weg, maar is niet gevuld rood: naast
       witte knoppen trekt dat meer aandacht dan de knop verdient. De kleur
       zit in rand en tekst, de vulling komt pas bij hover.

       De naam moet met `ws-btn--` beginnen. websignaal.css geeft
       `.ws-btn:not([class*="ws-btn--"]):hover` een lichtblauwe vulling en
       laadt ná dit bestand, dus een knop zonder modifier wordt bij hover
       blauw en niet rood, hoe je het hier ook zet. */
    .ws-hours-buttons .ws-btn--reset {
        border-color: var(--ws-danger);
        color: var(--ws-danger);
        font-weight: 600;
    }

    .ws-hours-buttons .ws-btn--reset:hover {
        background: var(--ws-danger);
        border-color: var(--ws-danger);
        color: #fff;
    }

    .kpi-block-sub {
        font-size: .7rem;
        color: #9ca3af;
        margin-top: .25rem;
        line-height: 1.3;
    }

    /* Een tweede waarde naast het kerngetal, zoals het bedrag naast de
       uren: zelfde regel, maar rustiger zodat het getal voorop blijft. */
    .kpi-block-value--licht {
        font-size: 1.1rem;
        font-weight: 500;
        color: var(--ws-muted);
    }

    .kpi-block-label {
        font-size: 0.75rem;
        color: var(--ws-muted);
        margin-top: 0.5rem;
    }

    /* Een getal dat niet bekend is, bijvoorbeeld kosten zonder uurtarief. Grijs en
       kleiner, zodat het niet leest als een gemeten nul. */
    .kpi-block-value.kpi-block-value--unknown {
        font-size: 1rem;
        font-weight: 500;
        color: #adb5bd;
        padding: 0.35rem 0;
    }

    /* Tabbladen in dezelfde vorm als op een project (.project-tab in
       bootstrap.css): het icoon boven het label, de actieve tab met een lichte
       paarse vulling en een paarse onderstreping die uitklapt. */
    .view-tab {
        position: relative;
        display: block;
        margin-bottom: -1px;
        text-align: center;
        color: var(--ws-ink);
        background-color: transparent;
        border: none;
        transition: color .15s ease, background-color .15s ease;
        cursor: pointer;
    }

    .view-tab i {
        display: block;
        font-size: 20px;
        line-height: 1.2;
    }

    .view-tab::after {
        content: "";
        position: absolute;
        right: 0;
        /* Binnen de knop: de tabbalk scrollt horizontaal en knipt alles wat
           erbuiten valt, dus bottom: -1px maakte de streep onzichtbaar. */
        bottom: 0;
        width: 100%;
        height: 2px;
        /* De streep onder de actieve tab mag het felle accent zijn: die
           moet van een meter afstand te zien zijn, en op een lichte
           wash heeft het donkerblauw van de knoppen te weinig verschil. */
        background: var(--ws-accent);
        transform: scale(0);
        transition: all 250ms ease 0s;
    }

    .view-tab:hover {
        color: var(--ws-primary);
    }

    /* Twee namen voor dezelfde toestand: de pagina's met Alpine zetten
       view-tab--active zelf, en waar Bootstrap de tabs regelt (het project) zet
       zijn script .active. */
    .view-tab.view-tab--active,
    .view-tab.active {
        color: var(--ws-primary);
        background-color: var(--ws-primary-bg);
    }

    .view-tab.view-tab--active::after,
    .view-tab.active::after {
        transform: scale(1);
    }

    /* De balk met de tabs heeft geen eigen hoogte nodig: de knoppen bepalen hem.
       Zonder deze regel houdt de container zijn 2rem boven en onder uit
       base.html.twig, en loopt de vulling van de actieve tab niet door tot de rand
       zoals bij een project. De klasse staat er twee keer om het van die centrale
       regel te winnen. */
    .view-tabs-bar .container-fluid.container-fluid,
    .view-tabs-bar .container.container {
        padding-top: 0;
        padding-bottom: 0;
    }

    /* Verdeeld over de volle breedte, zoals .nav-justified bij een project. Zet
       de klasse op de <nav> om de tabs eronder gelijk te verdelen. */
    .view-tabs--justified {
        display: flex;
    }

    .view-tabs--justified .view-tab,
    .view-tabs--justified .acct-tab {
        flex: 1 1 0;
    }

    /* Tabbladen binnen een tabblad (components/_subtabs.html.twig).
       Bewust een andere vorm dan .view-tab hierboven: een grijze strook
       met de actieve tab als witte pil, icoon naast het label in plaats
       van erboven, en links uitgelijnd in plaats van over de volle
       breedte. Twee identieke balken onder elkaar lezen als twee
       gelijkwaardige rijen, en dan zie je niet meer welke bij welke
       hoort. Eigen CSS en geen Tailwind-klassen: de deploy bouwt de
       frontend niet, dus een klasse die nergens anders voorkomt haalt
       de build niet (zie stack.md). */
    .view-subtabs {
        display: inline-flex;
        gap: 0.25rem;
        max-width: 100%;
        margin-bottom: 1.25rem;
        padding: 0.25rem;
        background-color: var(--ws-primary-bg);
        border-radius: 0.5rem;
        overflow-x: auto;
    }

    .view-subtab {
        display: inline-flex;
        align-items: center;
        gap: 0.4rem;
        padding: 0.4rem 0.85rem;
        border: none;
        border-radius: 0.375rem;
        background: transparent;
        color: var(--ws-body);
        font-size: 0.8125rem;
        font-weight: 500;
        line-height: 1.4;
        white-space: nowrap;
        cursor: pointer;
        transition: color .15s ease, background-color .15s ease, box-shadow .15s ease;
    }

    .view-subtab i {
        font-size: 16px;
        line-height: 1;
    }

    .view-subtab:hover {
        color: var(--ws-primary);
    }

    /* Twee namen voor dezelfde toestand, net als bij .view-tab: Alpine
       zet view-subtab--active zelf, Bootstrap zet .active. */
    .view-subtab.view-subtab--active,
    .view-subtab.active {
        background-color: #fff;
        color: var(--ws-primary);
        box-shadow: 0 1px 2px rgba(36, 36, 60, 0.12);
    }

    /* De pil is al licht; een extra grijze badge erin wordt onleesbaar. */
    .view-subtab .status-badge {
        margin-left: 0.15rem;
    }

    @media (max-width: 575.98px) {
        .view-subtabs {
            display: flex;
            width: 100%;
        }
    }

    /* De klantenkaart gebruikt dezelfde tabs onder een eigen naam. */
    .acct-tab {
        position: relative;
        display: block;
        margin-bottom: -1px;
        text-align: center;
        color: var(--ws-ink);
        background-color: transparent;
        border: none;
        transition: color .15s ease, background-color .15s ease;
        cursor: pointer;
    }

    .acct-tab i {
        display: block;
        font-size: 20px;
        line-height: 1.2;
    }

    .acct-tab::after {
        content: "";
        position: absolute;
        right: 0;
        bottom: 0;
        width: 100%;
        height: 2px;
        /* De streep onder de actieve tab mag het felle accent zijn: die
           moet van een meter afstand te zien zijn, en op een lichte
           wash heeft het donkerblauw van de knoppen te weinig verschil. */
        background: var(--ws-accent);
        transform: scale(0);
        transition: all 250ms ease 0s;
    }

    .acct-tab:hover {
        color: var(--ws-primary);
    }

    .acct-tab.acct-tab--active {
        color: var(--ws-primary);
        background-color: var(--ws-primary-bg);
    }

    .acct-tab.acct-tab--active::after {
        transform: scale(1);
    }

    /* Status Badge */
    .status-badge {
        background: var(--ws-primary-bg);
        color: var(--ws-primary);
        font-size: 0.75rem;
        font-weight: 500;
        padding: 0.25rem 0.75rem;
        border-radius: 4px;
    }


    /* Varianten op de blauwe badge in de kop. Zelfde vorm, andere kleur, zodat
       twee soorten badges naast elkaar uit elkaar te houden zijn. */
    .status-badge.status-badge--muted {
        background: var(--ws-badge-muted-bg);
        color: var(--ws-muted);
    }

    .status-badge.status-badge--amber {
        background: var(--ws-badge-amber-bg);
        color: var(--ws-badge-amber);
    }

    .status-badge.status-badge--green {
        background: var(--ws-badge-green-bg);
        color: var(--ws-badge-green);
    }

    .status-badge.status-badge--red {
        background: var(--ws-badge-red-bg);
        color: var(--ws-badge-red);
    }

    /* Drie vakken op een rij, voor een scherm waar de gegevens in drie
       groepen vallen in plaats van vier losse getallen. */
    .kpi-blocks.kpi-blocks--3 {
        grid-template-columns: repeat(3, 1fr);
    }

    .kpi-block-value.kpi-block-value--positive { color: var(--ws-success); }
    .kpi-block-value.kpi-block-value--negative { color: var(--ws-danger-hover); }

    /* De kerngetallen passen niet naast elkaar op een smal scherm.
       Zelfde breekpunten als de klantenkaart hanteert. */
    @media (max-width: 991.98px) {
        .kpi-blocks { grid-template-columns: repeat(2, 1fr); }
    }

    @media (max-width: 575.98px) {
        .kpi-blocks { grid-template-columns: 1fr; }
    }

    /* De naam van een medewerker als chip in zijn eigen kleur, zodat je
       dezelfde persoon in een lijst, een week en een dag aan dezelfde
       kleur herkent. De kleur komt van user_color() en staat inline,
       want een klasse per kleur haalt de Tailwind-build niet. */
    .ws-user-tag {
        display: inline-flex;
        align-items: baseline;
        padding: .1rem .5rem;
        border-radius: 999px;
        font-size: .75rem;
        font-weight: 600;
    }

    /* Vastpinnen is altijd dezelfde zwarte knop; alleen het pin-icoon
       wisselt. Uit is het wit en open (mdi-pin-outline), aan is het geel
       en gevuld (mdi-pin), dezelfde tint als het pinnetje in het
       overzicht. Zo verspringt de knop niet van vorm als je hem aanzet. */
    .ws-btn--pin {
        background: var(--ws-ink);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--pin:hover {
        background: var(--ws-primary);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--pin i {
        color: #fff;
    }

    .ws-btn--pin.ws-btn--pinned i {
        color: var(--ws-warning);
    }

    /* Verwijderen is overal dezelfde knop: rood, met een prullenbak en
       het woord erbij. In tabelrijen blijft het een icoon, daar is geen
       ruimte voor tekst. */
    .ws-btn--danger {
        background: var(--ws-danger);
        border-color: transparent;
        color: #fff;
    }

    .ws-btn--danger:hover {
        background: var(--ws-danger-hover);
        color: #fff;
    }

    /* De terugknop was hier een vierkant blauw blokje van 40 bij 40 naast
       de titel. Sinds 31 okt 2026 is het een regel bóven de kop
       (websignaal.css, sectie 5), en die vaste breedte brak een langer
       label als "Terug naar het idee" over drie regels af. */

    /* Alles in de paginakop even hoog: een datumveld of keuzelijst naast
       de knoppen stond anders een paar pixels lager en kleiner. */
    .ws-page-header .ws-btn,
    .ws-page-header .form-control,
    .ws-page-header .form-select,
    .ws-page-header .btn {
        min-height: 40px;
        box-sizing: border-box;
    }

    .ws-page-header .form-control,
    .ws-page-header .form-select {
        font-size: .875rem;
        line-height: 1.375rem;
        padding: .5rem .75rem;
        border-radius: 6px;
    }

    /* Schakelaar tussen de schermen van een module (zie
       components/_view_switch.html.twig): knoppen tegen elkaar, met het
       scherm waar je staat gemarkeerd. */
    .ws-switch__btn {
        display: inline-flex;
        align-items: center;
        min-height: 40px;
        padding: .5rem .875rem;
        font-size: .875rem;
        font-weight: 500;
        line-height: 1.375rem;
        color: #374151;
        background: #fff;
        border: 1px solid var(--ws-hair-blue);
        border-right-width: 0;
        text-decoration: none;
        white-space: nowrap;
        transition: background-color .15s ease, color .15s ease;
    }

    .ws-switch__btn:first-child {
        border-top-left-radius: 6px;
        border-bottom-left-radius: 6px;
    }

    .ws-switch__btn:last-child {
        border-right-width: 1px;
        border-top-right-radius: 6px;
        border-bottom-right-radius: 6px;
    }

    .ws-switch__btn:hover {
        background: var(--ws-primary-bg);
        color: var(--ws-ink);
    }

    .ws-switch__btn--active,
    .ws-switch__btn--active:hover {
        background: #eef2ff;
        color: #3730a3;
        border-color: #c7d2fe;
    }

    /* Eén contentbreedte voor het hele CRM.

       Schermen gebruikten twee breedtes door elkaar: een template met
       `container` kreeg van Tailwind maximaal 1536 px, een met
       `container-fluid` 85% van het venster (1434 px op een scherm van
       1702). Bij het doorklikken sprong de inhoud dus 102 px heen en
       weer. Hier staat die breedte één keer, zodat het niet meer
       uitmaakt welke van de twee klassen een scherm toevallig gebruikt.

       De breedte is het hele venster min de eigen gutter van de container,
       zoals de tijdregistratie het als enige al deed: op een scherm van
       1702 px is dat 1655 in plaats van 1434. Dezelfde drempel als het
       thema zelf hanteert (app.scss); onder 1200 px blijven de bestaande
       regels gelden. Gemeten 29 okt 2026. */
    @media (min-width: 1200px) {
        /* Even specifiek als de themaregel die hier 85% zet
           (body[data-layout="horizontal"] .container-fluid), anders wint die. */
        body[data-layout="horizontal"] .container,
        body[data-layout="horizontal"] .container-fluid,
        .container,
        .container-fluid {
            max-width: 100%;
            /* Dezelfde marge rondom op elke pagina. Zonder dit plakt een
               scherm zonder eigen padding tegen de zijkant zodra de breedte
               op 100% staat: het dashboard hield 6 px over, de projectpagina
               11 en verlofaanvragen 15. */
            /* Los per kant, niet als `padding`-shorthand: de utility
               .px-4 zet padding-left en -right apart en wint het dan van
               een shorthand. */
            padding-top: 2rem;
            padding-right: 2rem;
            padding-bottom: 2rem;
            padding-left: 2rem;
        }
    }

/* ==== De tweede set, die in base.html.twig vlak na <body> stond ==== */

/* Lucht boven het topmenu — overal 12px (desktop + mobiel) */
/* Zonder dev-balk begint de pagina gewoon bovenaan. Met balk schuift
   alles 32px omlaag, precies de hoogte van die balk, want die staat
   fixed over de pagina heen. Eerder stond hier 12px voor iedereen, ook
   in productie; dat gaf daar een strook witruimte boven de header
   waar niets hoort te zitten. */
body { padding-top: 0; }
body.has-dev-banner { padding-top: 14px; }

/* Override de oude mobiele fixed-header padding (56px/88px) uit app.scss;
   de nieuwe header is in-flow (sticky), dus die ruimte is niet meer nodig. */
@media (max-width: 991.98px) {
    body { padding-top: 0 !important; }
    body.has-dev-banner { padding-top: 14px !important; }
}

/* De sticky header plakt onder de dev-balk in plaats van eronder te verdwijnen. */
#page-topbar { top: 0; }
body.has-dev-banner #page-topbar { top: 32px; }

/* Het filterpaneel begint onder de dev-balk, anders valt zijn kop met de
   titel en de sluitknop erachter. Alle lagen van het paneel staan fixed
   ten opzichte van het venster, dus die moeten alle vier mee; alleen de
   buitenste verschuiven laat de backdrop over de balk liggen.
   Zonder balk blijft alles op 0, zoals het hoort. */
body.has-dev-banner [data-filter-panel-target="panel"],
body.has-dev-banner [data-filter-panel-target="backdrop"],
body.has-dev-banner [data-filter-panel-target="panel"] .fixed {
    top: 32px;
}
    
