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); }

/* De AppKit-MainLayout heeft geen brand-logo-optie (AppKitOptions kent er geen), dus we vervangen het icoon
   hier: het DevExpress-SVG verbergen en de CleanOps-druppeltegel (favicon.svg) tonen - zelfde patroon als
   CreditSoft en Nimble. Kandidaat voor een echte brand-slot in de AppKit - bij ADM One gemeld. */
.topbar .brand > svg.adm-icon { display: none; }
.topbar .brand::before {
    content: "";
    width: 24px; height: 24px; flex: 0 0 auto;
    background: url("/favicon.svg") center / contain no-repeat;
}

.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); }
.nav-menu .nav-link.active { background: var(--bs-primary-bg-subtle); color: var(--bs-primary); 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)- en :has(.adm-page-fill)-regels 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; }

#blazor-error-ui {
    display: none; position: fixed; bottom: 0; left: 0; right: 0;
    padding: 10px 16px; z-index: 1100;
    /* Dark mode: Bootstrap danger-variabelen volgen licht/donker (fallback = de oude vaste kleuren). */
    background: var(--bs-danger-bg-subtle, #fee);
    border-top: 1px solid var(--bs-danger-border-subtle, #f5c2c7);
    color: var(--bs-danger-text-emphasis, #58151c);
}
#blazor-error-ui .reload, #blazor-error-ui .dismiss { margin-left: 12px; cursor: pointer; }

/* === 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` en `.adm-grid-fill .adm-grid-bar` STONDEN HIER, woordelijk gelijk aan
   adm-shell.css, en zijn weg op 09/09/2026 (playbook: "CSS van een fundering-component hoort IN de
   fundering"). De fundering zegt het zelf bij die regels: "Ships met het pakket zodat apps geen eigen
   .adm-grid-fill-hack in app.css meer nodig hebben — wie het element rendert, stijlt het."
   Gemeten vóór het weghalen: zelfde eigenschap én zelfde waarde (flex 1 · min-height 0 · display flex ·
   flex-direction column), dus de laadvolgorde doet er niet toe. */
.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;
}
.content:has(.adm-grid-fill) > .dxbl-btn {
    align-self: flex-start;
}

/* Vol-hoogte WERKSCHERM (bv. boom links + grid rechts). `.adm-grid-fill` regelt enkel de grid zelf; dit
   regelt de pagina eromheen, zodat de rij op de VIEWPORT eindigt in plaats van op zijn inhoud.
   Gebruik: `adm-page-fill` op de buitenste div, `adm-fill-row` op de rij, `adm-fill-panel` op een paneel
   dat zijn kolom moet vullen. Ontsnapt automatisch aan de 1100px-leescap.
   (Vorm overgenomen uit de Damc-sessie, 21/07 — zie de opmerkingen hieronder voor de valkuilen.) */
.content:has(.adm-page-fill) { display: flex; flex-direction: column; overflow: hidden; }
.content:has(.adm-page-fill) > .content-inner {
    flex: 1; min-height: 0; max-width: none;
    display: flex; flex-direction: column; overflow: hidden;
}

/* Enkel vanaf lg. Daaronder stapelen de kolommen en hoort de pagina gewoon te scrollen: twee panelen van
   elk een halve schermhoogte is op een telefoon onbruikbaar. */
@media (min-width: 992px) {
    .adm-page-fill { flex: 1; min-height: 0; display: flex; flex-direction: column; }

    /* Zet `adm-fill-row` op de rij die moet meerekken — bewust een eigen klasse en niet elke `.row`,
       zodat een gewone rij ergens op de pagina niet ongewild flex wordt.
       `nowrap` in plaats van een hoogte op de kolommen: met wrap rekken die op tot hun INHOUD (een grid
       van 296 rijen wordt dan 1345px hoog in een vak van 669px), en een expliciete hoogte zet de
       verticale gutter er 16px naast. */
    .adm-page-fill .adm-fill-row { flex: 1; min-height: 0; flex-wrap: nowrap; }
    .adm-page-fill .adm-fill-row > [class*="col-"] { display: flex; flex-direction: column; min-height: 0; }

    /* Paneel dat zijn kolom vult; de inhoud scrollt intern. */
    .adm-page-fill .adm-fill-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; }
    .adm-page-fill .adm-fill-panel > .card-body { flex: 1; min-height: 0; overflow: auto; }
}

/* Onder lg grijpt `adm-page-fill` niet: de kolommen stapelen en de pagina scrollt, en dat hoort zo.
   Maar een lang EERSTE paneel eet dan het halve scherm op vóór je het tweede ziet — een categorieboom met
   honderd takken duwt de lijst volledig onder de vouw. Vandaar een cap: het paneel scrollt intern, de
   pagina blijft bruikbaar. Is het paneel kort, dan doet deze regel niets (het is een maximum, geen hoogte).
   (Gemeten door de Damc-sessie op een boom met 117 takken.) */
@media (max-width: 991.98px) {
    .adm-page-fill .adm-fill-panel > .card-body { max-height: 40vh; overflow: auto; }
}

/* 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. */

/* Routes.razor focust bij elke navigatie de paginatitel-<h1> (FocusOnNavigate — de schermlezer leest de titel voor).
   De fundering onderdrukt de muis-focusrand enkel via `h1:focus:not(:focus-visible)` (adm-shell.css), maar bij een
   VOLLEDIGE paginalaad (bv. het startscherm net na login) telt die focus in sommige browsers toch als
   :focus-visible → zwart kader rond de titel. Een titel is niet-interactief → nooit een zichtbare focusrand
   (ook niet bij :focus-visible). App-eigen regel, niet in de fundering (per-app opgelost, zie CreditSoft). */
h1:focus,
h1:focus-visible { outline: none; }

/* Login-scherm (fundering-LoginPanel): stijl verhuisd naar de scoped LoginPanel.razor.css in Adm.AppKit.Web. */

/* Tweeluik-login (eigen layout, ADR-0004-override; zelfde patroon als CreditSoft/Nimble).
   Merkpaneel links (teal-verloop uit het logo) + het fundering-LoginPanel (.login-page) rechts. */
.co-login { display: flex; min-height: 100vh; }
.co-login-brand {
    flex: 1 1 46%;
    background: linear-gradient(150deg, #2dd4bf 0%, #0d9488 55%, #0f766e 100%);
    color: #fff;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 1.5rem; padding: 2rem; text-align: center;
}
.co-login-logo { width: 104px; height: 104px; }
.co-login-title { font-size: 2.4rem; font-weight: 600; letter-spacing: .01em; margin: 0; }
.co-login-tagline {
    font-size: .8rem; font-weight: 400; letter-spacing: .14em; text-transform: uppercase;
    color: rgba(255, 255, 255, .72); margin: 0; max-width: 24rem; line-height: 1.7;
}
/* .login-page (fundering) = de rechter helft; behoudt zijn eigen centrering van de kaart. */
.co-login .login-page { flex: 1 1 54%; background: var(--bs-body-bg); }

@media (max-width: 767.98px) {
    .co-login { flex-direction: column; }
    .co-login-brand { flex: 0 0 34vh; }
    .co-login .login-page { min-height: auto; }
}

/* 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") ============================================================ */
.rn-page-title { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rn-beta { font-size: .55em; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    padding: 3px 10px; border-radius: 12px; background: #ffb020; color: #241800; line-height: 1.4; }
.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; }

/* Help-lade: de "Volledige handleiding"-knop volle breedte + zelfde stijl als de Afmelden-knop
   (.prefs-logout). Enkel binnen het help-paneel, zodat de thema/taal-chips een pil blijven. */
.help-panel .prefs-footer .prefs-chip {
    display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%;
    padding: 8px; border-radius: 8px;
}
.help-panel .prefs-footer .prefs-chip:hover { background: var(--bs-secondary-bg); }

/* === Beta-welkompagina (tijdelijk startscherm) ================================================ */
.welcome { max-width: 880px; }
.welcome-intro { max-width: 720px; margin-bottom: 1.75rem; }
.welcome-cards { margin-bottom: 1.75rem; }
.welcome .card-title { margin-bottom: .75rem; }
.welcome-list { padding-left: 1.1rem; }
.welcome-list li { margin-bottom: .5rem; }
.welcome-list li:last-child { margin-bottom: 0; }
.welcome-actions { display: flex; flex-wrap: wrap; gap: 12px; }
/* ── Kopblok van een detailscherm: gegevens in twee kolommen ────────────────────────────────────────────
   De vijf detailschermen (klant, contract, factuur, offerte, werkorder) tonen hun gegevens in een `.row`
   met twee `col-md-6` binnen een max-width. Daar staat vrije tekst van de gebruiker in: een naam, een
   straat, een e-mailadres.

   ⚠️ Een e-mailadres is één ONONDERBROKEN woord en browsers breken niet op een @ of een punt. Een cel kan
   niet smaller worden dan haar langste woord. `anywhere` breekt alleen wanneer het moet en laat normale
   tekst met rust.

   GEMETEN op 24/08/2026 in de browser, tegen de echte Bootstrap en deze app.css, bij twee kolommen naast
   elkaar van 450 px:
     - positieve controle (één woord van 200 tekens): 1659 px overloop ZONDER, 0 MET  → de regel werkt
     - drempel voor een ononderbroken e-mailadres: 95 tekens
     - een realistisch lang adres van 62 tekens neemt 426 px en past dus ruim
   Mijn eerste inschatting van "~70 tekens" was fout; 70 past met 24 px over.

   Dit is dus verzekering tegen een ZELDZAAM geval, geen reparatie van iets waargenomen. Bewust toch gezet:
   het is één geërfde eigenschap, ze kost niets wanneer ze niet nodig is, en de AppKit repareerde op
   dezelfde dag drie keer exact dit patroon — telkens gevonden doordat iemand er toevallig tegenaan liep. De AppKit repareerde diezelfde dag drie keer exact dit patroon (bijlagentabel, journaalkaart,
   AdmLogList) — telkens gevonden door iemand die er toevallig tegenaan liep, niet door een controle. Zie
   0.281.0/0.282.0. */
.co-kopblok {
    overflow-wrap: anywhere;
}

/* Periodefilter op de opdrachtenlijst: twee datumvelden naast elkaar in de SubBar. Zonder vaste breedte
   nemen ze elk de volle kolom en duwen ze de statuskeuze van de balk. */
.ops-periodefilter { width: 130px; }

/* === Historiek-tab: één rij mag het scherm niet opeten ======================================== */
/* ⚠️ GEMETEN OP PRODUCTIE (09/09/2026), contract 6211: één cel van 909px hoog met 786 tekens, in een
   viewport van 1289 — zeventig procent van het scherm voor ÉÉN regel. De oorzaak is niet een lange
   waarde maar een AANMAAK-rij: die noteert alle 43 velden van het record onder elkaar, en dat is voor
   elk geconverteerd record de eerste regel van zijn historiek. Wie de fiche opent om te zien wat er
   veranderd is, scrolt eerst langs die muur.

   `adm-historie-velden` is een klasse van de fundering (AdmRecordHistorie), en die is bevroren. Dit is
   dus opmaak aan ONZE kant boven een component dat we verder ongemoeid laten — geen kopie van het
   component, alleen een leeshoogte eromheen.

   Waarom scrollen en niet afkappen: een historiek waarin een waarde stilletjes verdwijnt is erger dan
   een lijst die je moet doorlopen. Alles blijft bereikbaar, alleen niet meer allemaal tegelijk.

   ⚠️ Lost de fundering dit ooit zelf op, dan is deze regel drift. Ze staat daarom hier en niet in een
   eigen bestand, met de meting erbij zodat een volgende sessie kan nagaan of ze nog nodig is. */
.adm-historie-velden {
    max-height: 11rem;
    overflow-y: auto;
    margin-bottom: 0;
}

/* De scrollbalk pas tonen wanneer er echt iets te scrollen valt — anders staat er een grijze streep
   naast elke rij van één veld, en die suggereert inhoud die er niet is. */
.adm-historie-velden::-webkit-scrollbar { width: 6px; }
.adm-historie-velden::-webkit-scrollbar-thumb { background: var(--bs-border-color); border-radius: 3px; }
