/* ==========================================================================
   TodoIT Platform — designsystem
   Eget layout-sprog (app-shell, sidebar, page-header, bento) oven på en
   minimal Bootstrap-brug: Public Sans, bløde skygger, bolde overskrifter,
   pille-knapper — men i støvet blå.
   ========================================================================== */

@font-face {
    font-family: "Public Sans";
    src: url("fonts/public-sans-latin.woff2") format("woff2");
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
}

:root {
    --font: "Public Sans", "Segoe UI", system-ui, sans-serif;

    /* Accenten på det valgte punkt i menuen.
       Eget token og ikke --brass: brass skifter med temaet (mørkebrun i lyst tema), men MENUEN er
       marineblå i begge temaer. Brass ville derfor blive mørkebrunt på mørkeblåt, hver gang nogen
       slog lyst tema til — en fejl, der kun rammer halvdelen af brugerne, og som derfor kunne stå
       længe. Værdien er den lyse brass, der hører til en mørk flade. Efterregnet i
       tests/kontrastcheck mod --navy-950. */
    --side-accent: #e6bd7c;

    /* Støvet blå skala */
    --navy-950: #131c28;
    --navy-900: #1b2735;
    --navy-800: #243449;
    --navy-700: #33475f;
    --navy-600: #4a6485;
    --blue-500: #5c7fa8;
    --blue-400: #7c9bc0;
    --blue-300: #a5bcd5;
    --blue-200: #c8d8e7;
    --blue-100: #dfe9f2;
    --blue-50: #eff4f9;

    /* Varme neutraler */
    --paper: #ffffff;
    /* Fladen er varm, ikke kold. Paletten HAR haft varme neutraler hele tiden (--clay-*), men
       selve siden brugte dem ikke — den lå på en kold blågrå, og så trak alt på skærmen mod blåt.
       Retning A, 25. august 2026: papiret bliver varmt, og den blå bliver noget, man bruger, i
       stedet for noget, alting ligger i. */
    --shell: #f6f4f1;
    --clay-100: #f5efe8;
    --clay-200: #e6d8c8;

    /* Messing — den ENESTE accent.
       Værdien er ikke ny: den er --warn-ink, som allerede er efterregnet i tests/kontrastcheck.
       Den er bevidst genbrugt frem for opfundet, så paletten ikke vokser med endnu en tone.
       Bruges til eyebrow, gruppeoverskrifter og aktiv menupost — ALDRIG til status. Status har
       sine egne tre farver, og en accent, der også kan betyde «advarsel», er ikke en accent. */
    --brass: #7d5a24;

    --ink: #16202e;
    --ink-2: #3b4a5d;
    /* Aliaser: disse tokens blev refereret rundt i filen uden at være defineret, så de faldt
       tilbage på off-palette-farver (Tailwind-hex eller forkert tone). De peger nu på den
       rigtige palette-værdi ét sted. --ink-1 = primær, --ink-3 = tertiær (lysere end --ink-2);
       --brand = accent til fokus-ringe; --blue-600 = mørkere blå til link-hover. */
    --ink-1: var(--ink);
    --ink-3: var(--muted);
    --brand: var(--blue-400);
    --blue-600: var(--navy-700);
    /* Begge er TEKSTfarver, ikke pynt. --faint stod på #94a2b4 = 2,60:1 mod papiret og
       blev brugt som rigtig brødtekst 237 steder: tidsstempler, tomme tilstande, tal i
       diagrammer. --muted lå på 4,44:1 og faldt også, bare knap. Begge måles nu i
       tests/kontrastcheck mod både --paper og --shell, så det ikke kan ske igen.
       Rangordenen mellem dem er bevaret — faint er stadig den lyseste af de to. */
    --muted: #5d6c80;
    --faint: #627183;

    --line: rgba(19, 28, 40, 0.085);
    --line-2: rgba(19, 28, 40, 0.16);

    --shadow-xs: 0 1px 2px rgba(19, 28, 40, 0.05);
    --shadow-sm: 0 4px 14px rgba(19, 28, 40, 0.06);
    --shadow-md: 0 14px 34px rgba(19, 28, 40, 0.09);
    --shadow-lg: 0 26px 58px rgba(19, 28, 40, 0.14);

    --r-sm: 10px;
    --r-md: 14px;
    --r-lg: 20px;
    --r-xl: 28px;

    /* Knapper var pillefformede (999px). En pille er en etiket — den ser ud som noget, man læser,
       ikke som noget, man trykker på. Egen token, så den kan rulles tilbage alene, hvis den skurrer. */
    --r-btn: 8px;

    --good: #3f8a5c;
    --good-bg: #e8f2ec;
    --warn: #b07d33;
    --warn-bg: #f8f0e2;
    --crit: #ac4a41;
    --crit-bg: #f8eae8;

    /* Tekstfarver til brug PÅ de tre baggrunde ovenfor. --good og --warn er valgt
       som accentfarver og har ikke kontrast nok til at være tekst på deres egen
       lyse baggrund — --warn lander på 3,2:1, hvor kravet er 4,5. Disse er mørknet,
       til de holder. Verificeret i tests/kontrastcheck. */
    --good-ink: #2f6b46;
    --warn-ink: #7d5a24;
    --crit-ink: #8e3a32;
    /* Stjernevurdering (kundetilfredshed). Egen guld — de øvrige gule (--warn) er for brune til en stjerne. */
    --gold: #f5a623;

    --sidebar-w: 268px;

    /* Semantiske link-farver. Den blå/navy-skala er dobbeltarbejdende — den er BÅDE mørke
       flader (sidebar, knapper) OG tekst/links. Links kan derfor ikke bare bruge et
       skala-trin direkte, for så kan et mørkt tema ikke lysne linket uden også at lysne
       fladen. Links går nu gennem disse to, så det mørke tema flipper dem alene. */
    --link: var(--navy-700);
    --link-hover: var(--navy-950);

    color-scheme: light;

    /* Bootstrap-broer (kun det vi faktisk bruger) */
    --bs-body-bg: var(--shell);
    --bs-body-color: var(--ink);
    --bs-secondary-color: var(--muted);
    --bs-border-color: var(--line);
    --bs-border-color-translucent: var(--line);
    --bs-primary: var(--navy-800);
    --bs-primary-rgb: 36, 52, 73;
    --bs-link-color: var(--link);
    --bs-link-hover-color: var(--link-hover);
    --bs-success: var(--good);
    --bs-warning: var(--warn);
    --bs-danger: var(--crit);
    --bs-secondary: var(--muted);
    --bs-font-sans-serif: var(--font);
}

/* ==========================================================================
   Mørkt tema.
   Hele appen er bygget på de semantiske tokens ovenfor, så temaet er i alt
   væsentligt ét sæt omdefinerede tokens. Vi overskriver KUN det, der bærer
   lyshed: neutraler, status-tints, streger, skygger, de lyseste blå trin (der
   bruges som lyse baggrunde) og link-farven. De mørke navy-trin er allerede
   mørke og bruges til flader, der er mørke i BEGGE temaer (sidebar, topbar,
   knapper) — dem rører vi ikke.

   Temaet vælges af et lille script i <head> (tema.js), der sætter data-theme
   FØR første maling ud fra brugerens valg, ellers systemets indstilling — så
   der ikke blinker en lys side, før det mørke tema når frem. Derfor er der ingen
   @media-dublet her; CSS'en behøver kun [data-theme="dark"]. */
:root[data-theme="dark"] {
    /* Neutraler — hele flippen sker her */
    --paper: #1a2431;   /* kort og paneler — en anelse lysere end siden */
    --shell: #10161f;   /* side-baggrund, mørkest */
    --clay-100: #221d18; /* varme neutraler, mørk udgave (bruges sjældent) */
    --clay-200: #33291f;

    --ink: #e8eef5;     /* primær tekst — næsten hvid */
    --ink-2: #b4c1d1;   /* sekundær tekst */
    --muted: #96a5b8;   /* dæmpet tekst — lysnet, så kontrasten holder på mørkt */
    --faint: #8494a7;   /* svag tekst */

    --line: rgba(255, 255, 255, 0.10);
    --line-2: rgba(255, 255, 255, 0.19);

    /* Skygger skal være sorte og dybere på mørkt — de blålige forsvinder. */
    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.40);
    --shadow-sm: 0 4px 14px rgba(0, 0, 0, 0.45);
    --shadow-md: 0 14px 34px rgba(0, 0, 0, 0.50);
    --shadow-lg: 0 26px 58px rgba(0, 0, 0, 0.62);

    /* Status: accenten løftes en smule; -bg bliver en mørk tint; -ink en lys tekst. */
    --good: #4c9d6d;   --good-bg: #16241b;  --good-ink: #83cf9f;
    --warn: #cc9a48;   --warn-bg: #26200f;  --warn-ink: #e6bd7c;
    --crit: #cf5f55;   --crit-bg: #291715;  --crit-ink: #ec938a;
    --gold: #f5b73f;

    /* Messing bærer lyshed og skal derfor flippe. Samme greb som i det lyse tema: værdien er
       temaets egen --warn-ink, altså allerede efterregnet mod den mørke flade. */
    --brass: #e6bd7c;

    /* Kun --blue-50 flipper — det bruges UDELUKKENDE som lys hover-/panel-baggrund og
       ville ellers stå som lyse pletter. --blue-100 og opefter er lyse nok til tekst på
       mørk bund (bl.a. sidemenuens tekst = var(--blue-100)) og beholdes; de få steder,
       der bruger dem som lys BAGGRUND, får en målrettet mørk regel nedenfor. */
    --blue-50: #1c2836;   /* subtil hover-baggrund */

    /* Links lysner alene (mørke navy-flader er urørte). */
    --link: var(--blue-300);
    --link-hover: var(--blue-200);

    color-scheme: dark;

    /* Bootstrap-broer, der pegede på mørke navy-værdier og skal lysne på mørkt. */
    --bs-primary: var(--blue-500);
    --bs-primary-rgb: 92, 127, 168;
    --bs-link-color: var(--link);
    --bs-link-hover-color: var(--link-hover);
}

/* --- Mørkt tema: komponenter, der hardkoder en lys værdi (pastel, hvid, mørk navy-tekst)
   og derfor ikke flipper med tokens. Hver får en målrettet mørk variant. --- */

/* Topbar-knapper og bruger-pillen: den halvhvide flade ville stå som en lys plet på den
   nu mørke topbar. Giv dem en mørk flade, så tekst og ikon (nu lyse) træder frem. */
:root[data-theme="dark"] .topbar__user { background: var(--paper); }
:root[data-theme="dark"] .notif__btn,
:root[data-theme="dark"] .topbar__signout { background: var(--paper); }
:root[data-theme="dark"] .notif__btn:hover,
:root[data-theme="dark"] .topbar__signout:hover { background: var(--blue-50); color: var(--ink); }
:root[data-theme="dark"] .brugermenu__knap:hover { background: var(--blue-50); }

/* Dokument-type-badges: lyse pasteller → mørke tints med lys tekst. */
:root[data-theme="dark"] .doc__ext--pdf   { background: #3a2320; color: #f0a79e; }
:root[data-theme="dark"] .doc__ext--doc   { background: #21304a; color: #a9c3ea; }
:root[data-theme="dark"] .doc__ext--sheet { background: #1c3326; color: #8fd3a9; }
:root[data-theme="dark"] .doc__ext--img   { background: #2e2440; color: #cba9e2; }
:root[data-theme="dark"] .doc__ext--zip   { color: #e2c69c; }

/* «Se som kunde»-banner: varm lys amber → mørk amber. */
:root[data-theme="dark"] .viewas {
    background: linear-gradient(90deg, #2a2314, #211d10);
    border-bottom-color: #4a3d1f;
    color: #e6c98a;
}
:root[data-theme="dark"] .viewas__exit {
    background: rgba(255, 255, 255, 0.06);
    border-color: #6a5628;
    color: #e6c98a;
}
:root[data-theme="dark"] .viewas__exit:hover { background: rgba(255, 255, 255, 0.12); }

/* Blazor-fejl-toast: egen lys amber → mørk. */
:root[data-theme="dark"] #blazor-error-ui {
    color-scheme: dark;
    background: #2a2114;
    color: #e6c98a;
    border-top-color: #4a3d1f;
}

/* Info-boks: mørk navy-tekst ville forsvinde på den nu mørke blå baggrund. */
:root[data-theme="dark"] .alert-info { color: var(--blue-200); border-color: var(--line-2); }

/* Sags-chip: lys blå flade + mørk tekst → mørk flade + lys tekst. */
:root[data-theme="dark"] .tkt-chip { background: var(--shell); color: var(--ink-2); }
:root[data-theme="dark"] .tkt-chip:hover { background: var(--blue-50); }

/* Opfølger- og vidensbase-links bruger mørk navy som tekst → lysnes. */
:root[data-theme="dark"] .tkt-opfoelger a,
:root[data-theme="dark"] .kb-article a { color: var(--link); }

/* Vidensbasens kode/citat brugte lyseblå (blue-100) som flade/kant. */
:root[data-theme="dark"] .kb-article code { background: var(--shell); color: var(--ink); }
:root[data-theme="dark"] .kb-article pre { background: var(--shell); }
:root[data-theme="dark"] .kb-article blockquote { border-left-color: var(--line-2); }
:root[data-theme="dark"] .kb-article hr { border-top-color: var(--line-2); }
:root[data-theme="dark"] .kb-article th,
:root[data-theme="dark"] .kb-article td { border-bottom-color: var(--line-2); }
:root[data-theme="dark"] .kb-article .kb-opgave input { accent-color: var(--link); }

/* Valgt afsender-filter bruger var(--ink) som BAGGRUND med hvid tekst — --ink flipper til
   lyst, så gør teksten mørk på den nu lyse flade. */
:root[data-theme="dark"] .afsfilter__k.er-valgt { color: var(--shell); }

/* Mørk navy brugt som TEKST/ikon står ulæseligt på en nu mørk flade. Det ramte bl.a.
   outline-knapperne («Ny mappe», «Tjek alle», «Tjek de N vi måler udefra»), et par
   ikon-/link-farver og et par badges. Her lysnes de, så de kan læses. */
:root[data-theme="dark"] .btn-outline-primary,
:root[data-theme="dark"] .btn-outline-secondary { color: var(--ink); border-color: var(--line-2); }
:root[data-theme="dark"] .btn-outline-primary:hover,
:root[data-theme="dark"] .btn-outline-secondary:hover { color: var(--ink); border-color: var(--blue-400); }

:root[data-theme="dark"] .stat__dot { color: var(--blue-300); }
:root[data-theme="dark"] .mods__row .icon { color: var(--blue-300); }
:root[data-theme="dark"] .sscore__hvem > summary { color: var(--link); }
:root[data-theme="dark"] .notif__lyd { color: var(--ink-2); }
:root[data-theme="dark"] .form-check-input:checked { background-color: var(--blue-500); border-color: var(--blue-500); }

/* Badges med lys blå flade + mørk navy-tekst. */
:root[data-theme="dark"] .badge.bg-primary { background: var(--shell) !important; color: var(--ink) !important; }
:root[data-theme="dark"] .badge.bg-info { color: var(--blue-200) !important; }

* { box-sizing: border-box; }

html { height: 100%; }

body {
    margin: 0;
    min-height: 100%;
    font-family: var(--font);
    color: var(--ink);
    background: var(--shell);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 {
    font-family: var(--font);
    color: var(--ink);
    font-weight: 700;
    letter-spacing: -0.015em;
    margin: 0;
}

/* Blazor's enhanced navigation programmatically focuses the page's <h1> after each
   navigation (for screen readers). Det fokus er ikke noget en seende bruger nogensinde
   selv har tabbet sig til — h1 er ikke i tab-rækkefølgen — så vi skjuler ringen helt
   i stedet for bare at style den, ellers popper den grimt op ved hvert sideskift. */
h1:focus, h1:focus-visible {
    outline: none;
}

p { margin: 0; }

a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); }

/* ==========================================================================
   Scrollbars — diskrete i stedet for Windows' tykke grå standard, der især
   dominerer i den mørke sidemenu.

   To lag, fordi ingen browser kan begge: den moderne standard (scrollbar-width/
   -color, arves fra html) dækker Firefox; ::-webkit-scrollbar dækker Chromium/
   Edge/Safari. Thumben holdes tynd med en gennemsigtig kant + background-clip,
   så den flyder som en smal pille i stedet for at fylde hele sporet.
   ========================================================================== */
/* scrollbar-width arves ikke pålideligt til indre scroll-områder, så den sættes bredt
   (rammer kun elementer, der faktisk kan rulle). Gælder Firefox; Chromium/Edge/Safari
   styres af ::-webkit-scrollbar nedenfor. */
* {
    scrollbar-width: thin;
    scrollbar-color: rgba(19, 28, 40, 0.22) transparent;
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb {
    background: rgba(19, 28, 40, 0.22);
    border-radius: 999px;
    border: 3px solid transparent;
    background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(19, 28, 40, 0.36); }

/* Den mørke sidemenu: en mørk thumb ville forsvinde — lys, men stadig diskret. */
.side__nav { scrollbar-color: rgba(255, 255, 255, 0.24) transparent; }
.side__nav::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.24); }
.side__nav::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.42); }

/* ==========================================================================
   App shell
   ========================================================================== */

.app {
    display: flex;
    min-height: 100vh;
}

.app__main {
    flex: 1;
    min-width: 0;
    position: relative;
    background:
        radial-gradient(1100px 520px at 78% -8%, rgba(168, 192, 216, 0.28), transparent 65%),
        radial-gradient(760px 420px at 8% 108%, rgba(230, 216, 200, 0.32), transparent 62%),
        var(--shell);
}

.app__content {
    max-width: 1360px;
    padding: 2.25rem 2.5rem 3.5rem;
}

/* One vertical rhythm for stacked page blocks. .panel carried no bottom margin, so two panels — or a
   panel next to another card — sat flush against each other, while .hero/.bento/.status/.aftale each
   brought their own margin; the spacing between top-level cards was therefore uneven from page to page.
   This gives every top-level block the same gap above it. Adjacent vertical margins collapse in this
   block container, so the existing per-card margins are absorbed into this one value rather than doubling.
   IMPORTANT: keep .app__content a plain block — do NOT add display:flex/grid, overflow, or contain to it,
   or margin-collapse stops and every gap becomes additive (a header's 1.9rem + this 1.5rem = 3.4rem). */
.app__content > * + * { margin-top: 1.5rem; }

/* The same rhythm for the few page bodies that do NOT sit directly under .app__content, so their stacked
   panels/cards are grandchildren the rule above cannot reach: a page wrapped in one max-width column
   (.doc-col), the account-settings content column (.acct__col), the public pages under PublicLayout
   (.pub__inner) and the auth/receipt card (.auth__card). Same collapsing owl selector, so no doubling. */
.doc-col { max-width: 52rem; }
.doc-col > * + *,
.acct__col > * + *,
.pub__inner > * + * { margin-top: 1.5rem; }
.auth__card > .panel + .panel,
.auth__card > .panel + .alert { margin-top: 1.25rem; }

/* Two panels stacked inside one bento cell (e.g. the ticket-detail columns): the bento's own gap spaces
   the cells, not siblings within a cell, and .panel has no margin — match the bento gap between them. */
.bento .panel + .panel { margin-top: 1.15rem; }

/* ==========================================================================
   Sidebar
   ========================================================================== */

.side {
    width: var(--sidebar-w);
    flex-shrink: 0;
    background: linear-gradient(178deg, var(--navy-900) 0%, var(--navy-950) 100%);
    color: var(--blue-100);

    /* Menuen er navigation — ikke tekst man markerer. Uden dette markerer et dobbeltklik (eller et
       lille træk) på en sektionsoverskrift som «Administration» linjerne omkring den, og browserens
       markeringsfarve lægger sig som en bjælke hen over overskriften. Overskrifterne selv var allerede
       umarkerbare, men linkene rundt om var det ikke — så markeringen spændte hen over dem. */
    -webkit-user-select: none;
    user-select: none;

    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    transition: width 0.18s ease;
    /* Klip alt der stikker uden for de 100vh. .side__nav ruller selv indeni (overflow-y:auto), men de
       absolut-positionerede fold-checkbokse (checkbox-hacket for de sammenklappelige sektioner) lå ellers
       nederst i menu-flowet UDEN for højden og forlængede hele sidens rullehøjde — så man kunne rulle ned i
       tomt hvidt rum under indholdet på moduler, hvor menuen var højere end selve siden. */
    overflow: hidden;
}

/* ==========================================================================
   Test-/demo-miljøbanner (App.razor)
   Banneret ligger fast øverst i en 24px stribe. Når det er der (body.har-testbanner),
   skubbes hele app-shellen ned under det, så det ikke længere dækker top-baren eller
   sidemenuen. De top-forankrede sticky-elementer (.topbar, .side) klæber nu under
   banneret i stedet for op under det.
   ========================================================================== */
body.har-testbanner { padding-top: 24px; }
body.har-testbanner .app { min-height: calc(100vh - 24px); }
body.har-testbanner .topbar { top: 24px; }

@media (min-width: 901px) {
    /* Kun på desktop er .side sticky/100vh — på mobil er den relativ og flyder selv
       med under banneret via body-paddingen, så den må ikke røres her. */
    body.har-testbanner .side { top: 24px; height: calc(100vh - 24px); }
}

/* Menuen og topbaren bliver staaende, mens en dialog er aaben. Det haandteres i
   todoitModal i shortcuts.js — se klaebTilbage() dér. Det er med vilje ikke loest
   her i CSS: forskydningen maales paa det enkelte element frem for at blive regnet
   ud, saa den ogsaa passer for klaebende elementer laengere nede paa siden. */

.side__brand {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 1.4rem 1.35rem 1.25rem;
    color: #fff;
}

/* Den globale "a:hover" nedenfor slår ellers ordmærket mørkt (næsten usynligt på den mørke sidebar). */
.side__brand:hover { color: #fff; }

.side__mark {
    width: 34px;
    height: 34px;
    border-radius: 10px;
    background: linear-gradient(140deg, var(--blue-400), var(--navy-600));
    display: grid;
    place-items: center;
    font-weight: 800;
    font-size: 0.86rem;
    letter-spacing: -0.02em;
    color: #fff;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25);
    flex-shrink: 0;
}

.side__wordmark {
    font-weight: 800;
    font-size: 1rem;
    letter-spacing: -0.01em;
    line-height: 1.15;
}

.side__wordmark span {
    display: block;
    font-size: 0.66rem;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: var(--blue-400);
}

.side__nav {
    flex: 1;
    /* min-height:0 er nødvendig: uden den har et flex-barn min-height:auto og kan ikke krympe under
       sit indhold — så en menu, der er højere end skærmen (fx når «Administration» foldes ud), RULLER
       ikke indeni, men vokser i stedet forbi skærmen og skubber fold-knappen ned med et mørkt tomrum
       under sig. Med min-height:0 ruller .side__nav selv, og skinnen bliver stående nederst. */
    min-height: 0;
    overflow-y: auto;
    padding: 0.4rem 0.85rem 1rem;
}

.side__section {
    font-size: 0.64rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(165, 188, 213, 0.62);
    padding: 1.15rem 0.75rem 0.45rem;
}

.side__link {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0.75rem;
    border-radius: 11px;
    color: var(--blue-200);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.3;
    margin-bottom: 2px;
    transition: background-color 0.13s ease, color 0.13s ease;
}

.side__link:hover {
    background: rgba(255, 255, 255, 0.07);
    color: #fff;
}

.side__link.active {
    background: rgba(124, 155, 192, 0.22);
    color: #fff;
    box-shadow: inset 0 0 0 1px rgba(165, 188, 213, 0.2);
}

/* Et FASTGJORT punkt står to steder: som genvej i toppen og på sin egen plads i modullisten.
   Kun genvejen lyser. Originalen beholder sin «active» fra NavLink — den er bare ikke tegnet
   som aktiv her, så markeringen bliver ved med at betyde ét sted, ikke to.
   Sættes af pins.js; se side__row--dublet dér. */
.side__row--dublet > .side__link.active {
    background: transparent;
    color: var(--blue-200);
    box-shadow: none;
}

.side__row--dublet > .side__link.active:hover {
    background: rgba(255, 255, 255, 0.07);
    color: #fff;
}

.side__row--dublet > .side__link.active .icon { opacity: 0.85; }

.side__link .icon { flex-shrink: 0; opacity: 0.85; }

/* Ikonet tager accenten på det valgte punkt.
   Uden den var det aktive punkt kun en blågrå vask — samme familie som resten af menuen, så øjet
   skulle lede efter det. Accenten sidder på IKONET og ikke på teksten: teksten er allerede hvid og
   fed, og en farvet etiket oveni ville gøre punktet skrigende frem for tydeligt. */
.side__link.active .icon { opacity: 1; color: var(--side-accent); }

/* Dubletten skal heller ikke have accenten — ellers ville den lyse på anden vis end resten af
   listen og stadig se ud som «her er du». Se .side__row--dublet. */
.side__row--dublet > .side__link.active .icon { color: inherit; }

.side__toggle { display: none; }

/* Foldbare menu-sektioner. Selve foldningen er ren CSS: en skjult checkbox pr. sektion, hvis
   :checked-tilstand styrer, om gruppen under den vises. nav-fold.js husker blot valget pr. bruger. */
.side__fold {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.side__section--fold {
    display: flex;
    align-items: center;
    cursor: pointer;
    user-select: none;
    transition: color 0.12s ease;
}

.side__section--fold:hover { color: rgba(165, 188, 213, 0.92); }

/* Pilen: peger til højre når foldet, ned når åben. */
.side__section--fold::after {
    content: "";
    margin-left: auto;
    width: 5px;
    height: 5px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform 0.15s ease;
    opacity: 0.7;
}

.side__fold:checked ~ .side__section--fold::after { transform: rotate(45deg); }

.side__fold:not(:checked) ~ .side__group { display: none; }

/* Fastgør-knappen ligger over linkets højre ende og vises kun ved hover, så den ikke
   støjer. Er punktet fastgjort, står den gyldne stift fast — også som markering. */
.side__row { position: relative; }
.side__row .side__link { padding-right: 2.1rem; }

/* Tallet ved et menupunkt («3 åbne hændelser»).
   Tegnes fra data-tal på rækken og ikke som markup, fordi de fastgjorte genveje er KLONER — se
   menutal.js. Klonen arver attributtet og dermed mærket, uden at der skal gøres noget.

   Nul findes ikke: menutal.js fjerner attributtet i stedet for at skrive "0". Et menupunkt med et
   gråt 0 ved siden af ligner noget, der er gået i stå — er der ingenting, står der ingenting. */
.side__row[data-tal]:not([data-tal=""])::after {
    content: attr(data-tal);
    position: absolute;

    /* Til venstre for nålen, som sidder på 6px. Uden for redigeringstilstand er nålen usynlig,
       men pladsen er den samme — så tallet flytter sig ikke, når man slår rediger til. */
    right: 1.6rem;
    top: 50%;
    transform: translateY(-50%);

    font-size: 0.68rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    color: var(--crit);
    pointer-events: none;
}

/* Sammenklappet menu: der er ikke plads til et tal ved siden af ikonet, så det bliver til en
   prik oppe i hjørnet. Tallet er væk, men «her er noget» er det, der skal bæres videre — ellers
   ville en sammenklappet menu tie om et nedbrud. */
:root[data-rail="1"] .side__row[data-tal]:not([data-tal=""])::after {
    content: "";
    right: 8px;
    top: 7px;
    transform: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--crit);
}

.side__pin {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: none;
    color: var(--blue-300);
    cursor: pointer;
    padding: 4px;
    line-height: 0;
    border-radius: 6px;
    /* Skjult uden for rediger-tilstand: menuen er ren, og ét tryk navigerer — også på mobil,
       hvor en synlig nål før stjal det første tryk. Nålene vises kun i «rediger genveje». */
    display: none;
    opacity: 0.55;
    transition: opacity 0.12s ease, color 0.12s ease, background-color 0.12s ease;
}

.side--edit .side__pin { display: inline-flex; }
.side--edit .side__pin:hover { opacity: 1; background: rgba(255, 255, 255, 0.12); color: #fff; }
.side__pin--on { opacity: 1; color: var(--gold); }
.side__pin--on .icon { fill: currentColor; }

/* «Genveje»-sektionen bruger de samme rækker/links som resten af menuen — ingen særlig stil
   udover en anelse luft under sig. */
.side__genveje { margin-bottom: 0.35rem; }

/* Genveje kan omordnes ved træk-og-slip. Gribe-markøren er selve signalet om, at rækkerne kan
   trækkes; klik navigerer stadig. (pins.js håndterer trækket; kun desktop — touch har ikke HTML5-DND.) */
/* Genveje kan omordnes ved at trække håndtaget — kun i rediger-tilstand. */
.side--edit .side__genveje .side__row { cursor: grab; }
.side__row--traekker { opacity: 0.4; cursor: grabbing; }
/* Indsæt-streg, der viser hvor rækken lander — tegnet med en inderskygge, så den ikke flytter layout. */
.side__row--drop-foer { box-shadow: inset 0 2px 0 0 var(--gold); }
.side__row--drop-efter { box-shadow: inset 0 -2px 0 0 var(--gold); }

/* Trækhåndtag i Genveje — kun synligt i rediger-tilstand (nålen ligger til højre, håndtaget til
   venstre). I rediger fanger håndtaget selv trækket (pointer-events:auto) med touch-action:none,
   så en finger kan trække uden at rulle siden — virker med både mus og berøring (iPad/mobil).
   pins.js indsætter ⠿-tegnet i klonerne. */
.side--edit #side-genveje-list .side__row .side__link { padding-left: 1.75rem; }
.side__grip {
    position: absolute;
    left: 8px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--faint);
    font-size: 0.95rem;
    line-height: 1;
    user-select: none;
    display: none;
}
.side--edit .side__grip { display: block; cursor: grab; opacity: 0.75; pointer-events: auto; touch-action: none; }
.side--edit .side__grip:hover { opacity: 1; color: var(--muted); }
/* I skinne-tilstand er linkene kun ikoner og centreret — hverken plads til grebet eller
   den ekstra venstremargen. */
:root[data-rail="1"] .side__grip { display: none; }
:root[data-rail="1"] #side-genveje-list .side__row .side__link { padding-left: 0; }

/* I skinne-tilstand er der hverken plads til eller mening i fastgør-knapper. */
:root[data-rail="1"] .side__pin { display: none; }
:root[data-rail="1"] .side__row .side__link { padding-right: 0; }

/* ==========================================================================
   Ikon-skinne: sidemenuen foldet til kun ikoner.
   Tilstanden (data-rail på <html>) sættes af nav.js — før første maling, så
   bredden ikke hopper — og genanvendes efter Blazor-navigation, ligesom temaet.
   ========================================================================== */

/* Sidemenuens bund: «Rediger genveje» + «Fold sammen/ud», som en samlet fod frem for en
   løs knap, der før sad og flød nederst. */
.side__foot { margin: 0.35rem 0.7rem 0.7rem; flex-shrink: 0; }
.side__edit-hint {
    display: none;
    font-size: 0.72rem;
    color: var(--muted);
    line-height: 1.4;
    padding: 0 0.3rem 0.5rem;
}
.side--edit .side__edit-hint { display: block; }
.side__foot-row { display: flex; gap: 0.4rem; }
.side__foot-btn {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.5rem 0.7rem;
    border: 0;
    border-radius: 11px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--blue-300);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.13s ease, color 0.13s ease;
}
.side__foot-btn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.side__foot-btn .icon { flex-shrink: 0; }
/* «Rediger genveje» fylder bredden; «Fold sammen» er kun et ikon ved siden af. */
.side__edit { flex: 1 1 auto; }
.side__edit[aria-pressed="true"] { background: rgba(212, 175, 55, 0.16); color: var(--gold); }
.side__rail { flex: 0 0 auto; }

/* ==========================================================================
   Host-monitor picker («Overvåg en vært») — opdag → flueben → tærskel-dialogen.
   ========================================================================== */
.hm-sec { margin-top: 1rem; }
.hm-sec__title {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.35rem;
}
.hm-count { font-weight: 600; color: var(--gold); margin-left: 0.3rem; }
.hm-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.3rem;
    cursor: pointer;
    border-radius: 7px;
}
.hm-row:hover { background: rgba(127, 127, 127, 0.09); }
.hm-row input[type="checkbox"] { flex-shrink: 0; margin: 0; }
.hm-row__name { flex: 1 1 auto; min-width: 0; }
.hm-row__detail { color: var(--muted); font-size: 0.82rem; margin-left: 0.4rem; }
.hm-row__thr {
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--muted);
    display: flex;
    align-items: center;
    gap: 0.35rem;
}
.hm-num {
    width: 4.4rem;
    padding: 0.25rem 0.45rem;
    border-radius: 7px;
    border: 1px solid rgba(127, 127, 127, 0.35);
    background: var(--paper, transparent);
    color: inherit;
    font: inherit;
    font-size: 0.85rem;
}
.hm-num:disabled { opacity: 0.5; }
.hm-list {
    max-height: 260px;
    overflow-y: auto;
    margin-top: 0.45rem;
    border: 1px solid rgba(127, 127, 127, 0.22);
    border-radius: 9px;
    padding: 0.25rem 0.45rem;
}

/* Sensor management: one card per reading, thresholds that WRAP so nothing is ever clipped
   off the right edge of the modal (the old wide table hid "critical above"). */
.sensor-edit { display: flex; flex-direction: column; gap: 0.6rem; }
.sensor-edit__row {
    border: 1px solid rgba(127, 127, 127, 0.22);
    border-radius: 9px;
    padding: 0.55rem 0.7rem;
}
.sensor-edit__head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; }
.sensor-edit__name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.sensor-edit__thr { display: flex; flex-wrap: wrap; gap: 0.45rem 0.9rem; margin-top: 0.55rem; }
.sensor-edit__thr label {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--muted);
}
.sensor-edit__note { margin-top: 0.4rem; font-size: 0.78rem; color: var(--muted); }

:root[data-rail="1"] .side { width: 66px; }
:root[data-rail="1"] .side__brand { justify-content: center; padding-left: 0; padding-right: 0; }
:root[data-rail="1"] .side__wordmark { display: none; }
:root[data-rail="1"] .side__label { display: none; }
/* Skjuler både fold-overskrifterne og «Genveje»/«Konto»-overskrifterne. */
:root[data-rail="1"] .side__section { display: none; }
:root[data-rail="1"] .side__nav { padding-left: 0.5rem; padding-right: 0.5rem; }
:root[data-rail="1"] .side__link { justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }
/* Skinnen viser ALLE ikoner: fold-tilstanden ignoreres, så intet er skjult bag en foldet sektion. */
:root[data-rail="1"] .side__group { display: block !important; }
/* I skinne-tilstand stables fod-knapperne og vises kun som ikoner; hintet giver ingen mening der. */
:root[data-rail="1"] .side__foot { margin-left: 0.5rem; margin-right: 0.5rem; }
:root[data-rail="1"] .side__foot-row { flex-direction: column; }
:root[data-rail="1"] .side__foot-btn { justify-content: center; padding-left: 0; padding-right: 0; gap: 0; }
:root[data-rail="1"] .side__foot-label { display: none; }
:root[data-rail="1"] .side__edit-hint { display: none !important; }

/* ==========================================================================
   Topbar (bruger + notifikationer, øverst til højre)
   ========================================================================== */

/* Bliver stående i toppen. Klokken opdaterer sig selv nu, og en klokke, der ruller
   ud af skærmen, kan lyse så meget den vil uden at nogen ser det. Søgefeltet får
   den samme tur med — det er alligevel det, man rækker ud efter først.

   z-index under 900: hurtig tidsregistrering (900), modaler og notifikationspanelet
   (950/951) skal stadig ligge ovenpå. */
.topbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.85rem 2.5rem 0.85rem;

    position: sticky;
    top: 0;
    z-index: 800;

    border-bottom: 1px solid transparent;
}

/* Baggrunden og sløringen ligger i et pseudoelement, ikke på baren selv.

   Grunden er ikke kosmetisk: backdrop-filter gør elementet til holdeblok for
   efterkommere med position: fixed. Notifikationspanelet er på mobil et bundark
   med position: fixed og bottom: 0 — og det målte pludselig fra topbarens bund i
   stedet for skærmens. Panelet landede på y −426, altså over skærmkanten, og man
   kunne kun se den nederste stump. Meldt ind som sag #1016.

   Et pseudoelement har ingen efterkommere, så filteret kan ikke fange noget. */
.topbar::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;

    /* Sløringen lader farverne bag skinne igennem, så baren ikke bliver en kasse
       oven på den tonede baggrund. */
    background: color-mix(in srgb, var(--shell) 82%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

/* Kanten kommer først, når der faktisk er rullet — ellers ligger der en streg
   under baren på en side, der ikke kan rulle. */
.topbar--rullet {
    border-bottom-color: var(--line);
    box-shadow: 0 6px 18px -12px rgba(22, 32, 46, 0.35);
}

/* Global søgning. Ligger til venstre i topbaren, hvor øjet lander først. */
.topsearch {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    flex: 0 1 26rem;
    padding: 0.42rem 0.85rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 999px;
    color: var(--muted);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.topsearch:focus-within {
    border-color: var(--blue-400);
    box-shadow: 0 0 0 3px rgba(94, 129, 172, 0.14);
}

.topsearch__input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: transparent;
    font: inherit;
    font-size: 0.86rem;
    color: var(--ink);
    outline: none;
}

.topsearch__input::placeholder { color: var(--faint); }

/* Krydset i type="search" er browserens eget og passer ikke ind i feltet. */
.topsearch__input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* Tema-skifteren (sol/måne) i topbaren. Token-drevet, så den selv følger temaet:
   lys knap + dæmpet ikon på lyst, mørk knap + lyst ikon på mørkt. */
.themetoggle {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 0;
    background: var(--paper);
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--muted);
    display: grid;
    place-items: center;
    flex-shrink: 0;
    cursor: pointer;
    transition: color 0.15s ease, background 0.15s ease;
}

.themetoggle:hover { background: var(--blue-50); color: var(--ink); }

/* «Spørg platformen» — diskret ikon i topbaren, samme runde form som tema-skifteren,
   så AI'en ikke fylder et helt menupunkt. */
.topbar__ask {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--paper);
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--muted);
    display: grid;
    place-items: center;
    flex-shrink: 0;
    text-decoration: none;
    transition: color 0.15s ease, background 0.15s ease;
}

.topbar__ask:hover { background: var(--blue-50); color: var(--ink); }

/* Ikonet følger [data-theme] i CSS, så det aldrig kommer ud af sync med det faktiske tema.
   Lyst tema viser månen (klik → mørkt); mørkt tema viser solen (klik → lyst). */
.themetoggle__ikon { display: none; }
.themetoggle__ikon--maane { display: inline-flex; }
:root[data-theme="dark"] .themetoggle__ikon--maane { display: none; }
:root[data-theme="dark"] .themetoggle__ikon--sol { display: inline-flex; }

.topbar__right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.topbar__user {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.3rem 0.75rem 0.3rem 0.3rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: inset 0 0 0 1px var(--line);
}

.topbar__avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--blue-400), var(--navy-700));
    display: grid;
    place-items: center;
    font-size: 0.73rem;
    font-weight: 800;
    color: #fff;
    flex-shrink: 0;
}

.topbar__avatar:hover { color: #fff; }

.topbar__who { min-width: 0; line-height: 1.2; }

.topbar__who b {
    display: block;
    font-size: 0.79rem;
    font-weight: 700;
    color: var(--ink);
    max-width: 15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.topbar__who span {
    display: block;
    font-size: 0.68rem;
    color: var(--muted);
}

.topbar__signout {
    background: rgba(255, 255, 255, 0.7);
    border: 0;
    box-shadow: inset 0 0 0 1px var(--line);
    width: 34px;
    height: 34px;
    border-radius: 50%;
    color: var(--muted);
    cursor: pointer;
    display: grid;
    place-items: center;
}

.topbar__signout:hover { background: #fff; color: var(--ink); }

/* Topbaren giver allerede luft i toppen — undgå dobbelt padding på indholdet. */
.topbar ~ .app__content { padding-top: 1.25rem; }

/* Trykmål på telefon.
   Ikonerne i topbjælken måler 32–34 px, hvilket er fint at ramme med en mus og for
   småt til en tommelfinger. Apple og Google anbefaler begge 44. Cirklen vokser ikke
   — det er trykfeltet omkring den, der gør, via padding. Så ser den ens ud, men
   rammer bedre. */
@media (max-width: 700px) {
    .topbar__avatar,
    .topbar__signout,
    .notif__btn {
        min-width: 44px;
        min-height: 44px;
    }

    /* Avataren har sin egen baggrund og må ikke blive en stor firkant — den
       centreres i stedet inde i det større trykfelt. */
    .topbar__avatar {
        background-clip: content-box;
        padding: 6px;
    }
}

/* ==========================================================================
   "Se som kunde"-banner
   ========================================================================== */

.viewas {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.7rem 2.5rem;
    background: linear-gradient(90deg, #f3e6cd, #f8f0e2);
    border-bottom: 1px solid #e3cfa5;
    color: #6d4d16;
    font-size: 0.87rem;
    font-weight: 600;
}

.viewas__dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--warn);
    flex-shrink: 0;
    box-shadow: 0 0 0 3px rgba(176, 125, 51, 0.22);
}

.viewas form { margin-left: auto; }

.viewas__exit {
    border: 1px solid #d9bd8a;
    background: rgba(255, 255, 255, 0.75);
    color: #6d4d16;
    border-radius: 999px;
    padding: 0.3rem 0.9rem;
    font-size: 0.8rem;
    font-weight: 700;
    cursor: pointer;
}

.viewas__exit:hover { background: #fff; border-color: var(--warn); }

@media (max-width: 900px) {
    .viewas { padding: 0.7rem 1.25rem; }
}

/* ==========================================================================
   Page header
   ========================================================================== */

.ph {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.9rem;
}

.ph__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--brass);
    margin-bottom: 0.7rem;
}

/* Stregen er tyndere og uden opacity: 1 px i fuld farve læses skarpere end 2 px i 75 %,
   som bare bliver grumset. */
.ph__eyebrow::before {
    content: "";
    width: 22px;
    height: 1px;
    background: currentColor;
}

.ph__title {
    font-size: clamp(1.7rem, 2.6vw, 2.35rem);
    font-weight: 800;
    letter-spacing: -0.028em;
    line-height: 1.08;
}

.ph__help {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.45rem;
    height: 1.45rem;
    margin-left: 0.55rem;
    vertical-align: middle;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
    color: var(--muted);
    background: color-mix(in srgb, var(--ink) 6%, transparent);
    border-radius: 999px;
    text-decoration: none;
    transition: background 0.12s, color 0.12s;
}

.ph__help:hover,
.ph__help:focus-visible { color: #fff; background: var(--blue-500); }

.ph__lead {
    margin-top: 0.5rem;
    color: var(--muted);
    font-size: 1rem;
    max-width: 62ch;
}

.ph__actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }

/* På smal skærm bliver knapperne ÉN linje, man kan rulle i — ikke tre stablede.
   Målt på driftsovervågningen den 13. september 2026: fem knapper brød til tre rækker og fyldte
   151 px, alle sammen handlinger der OPRETTER noget, oven over den første måling — på den skærm
   der har mindst plads. Én rullelinje koster 47 px. Intet er skjult, og den afskårne kant på den
   sidste knap er selve signalet om, at der er mere. */
@media (max-width: 780px) {
    .ph__actions { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 0.2rem; }
    .ph__actions > * { flex: 0 0 auto; }
}

/* ==========================================================================
   Surfaces
   ========================================================================== */

/* Skygge er hierarki, ikke pynt.
   Hvert panel havde --shadow-sm, og når alt er løftet, er intet løftet — øjet får ingen hjælp til
   at finde det, der haster. Panelet står nu på en hårstreg, og elevationen er flyttet til
   .panel--haster, som må optræde ÉN gang pr. side. */
.panel {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    padding: 1.5rem 1.6rem;
}

/* Den ene forhøjede flade: det, der kræver handling nu.
   Venstrekanten bærer status-farven, så panelet siger hvad OG hvor slemt uden en overskrift.
   Sættes med --haster-farve; standard er kritisk, fordi det er den hyppigste brug. */
.panel--haster {
    --haster-farve: var(--crit);
    border-color: color-mix(in srgb, var(--haster-farve) 30%, var(--line));
    border-left: 3px solid var(--haster-farve);
    border-radius: 4px var(--r-lg) var(--r-lg) 4px;
    box-shadow: var(--shadow-md);
}

.panel--haster.panel--obs  { --haster-farve: var(--warn); }
.panel--haster.panel--ok   { --haster-farve: var(--good); }

/* Målestregen — signaturmotivet i retning A.
   En fin skala under et nøgletal, som på et måleinstrument. Den siger ingenting præcist, og det
   er meningen: den fortæller, at tallet ER en måling og ikke bare et tal, nogen har skrevet.
   Rent dekorativt, derfor aria-hidden i markup.
   Tegnet med gradienter frem for SVG, så farven følger currentColor og dermed temaet. */
.maalestreg {
    height: 9px;
    margin-top: 0.5rem;
    color: color-mix(in srgb, var(--ink) 22%, transparent);
    border-bottom: 1px solid currentColor;
    background:
        linear-gradient(currentColor, currentColor) left bottom / 1px 9px no-repeat,
        linear-gradient(currentColor, currentColor) right bottom / 1px 9px no-repeat,
        repeating-linear-gradient(to right, currentColor 0 1px, transparent 1px 20%) left bottom / 100% 5px no-repeat;
}

/* Nøgletal med målestreg. Tallet er helten, mærkatet er lille, noten er dæmpet — og stregen
   under fortæller, at tallet ER en måling. Bruges på forsiden og hører til overalt, hvor et
   tal skal læses frem for tælles. */
.noegletal {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 2.4rem;
    margin-bottom: 2.2rem;
}

.noegletal__mærkat {
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--muted);
}

.noegletal__tal {
    font-size: 2.5rem;
    font-weight: 800;
    letter-spacing: -0.04em;
    line-height: 1.05;
    margin-top: 0.4rem;
    font-variant-numeric: tabular-nums;
}

.noegletal__tal--obs  { color: var(--warn-ink); }
.noegletal__tal--krit { color: var(--crit-ink); }

.noegletal__note {
    font-size: 0.8rem;
    color: var(--muted);
    margin-top: 0.55rem;
}

.maalestreg--ok   { color: color-mix(in srgb, var(--good) 38%, transparent); }
.maalestreg--obs  { color: color-mix(in srgb, var(--warn) 38%, transparent); }
.maalestreg--krit { color: color-mix(in srgb, var(--crit) 38%, transparent); }

.panel--flush { padding: 0; overflow: hidden; }

.panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.15rem;
}

.panel__title {
    font-size: 1.02rem;
    font-weight: 700;
    letter-spacing: -0.012em;
}

.panel__sub {
    font-size: 0.83rem;
    color: var(--muted);
    margin-top: 0.15rem;
}

/* Hero band */
.hero {
    position: relative;
    overflow: hidden;
    border-radius: var(--r-xl);
    padding: 1.9rem 2.1rem;
    margin-bottom: 1.5rem;
    color: #fff;
    background: linear-gradient(128deg, var(--navy-900) 0%, var(--navy-800) 46%, var(--navy-600) 100%);
    box-shadow: var(--shadow-md);
}

.hero::after {
    content: "";
    position: absolute;
    right: -70px;
    top: -90px;
    width: 320px;
    height: 320px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(197, 217, 236, 0.24), transparent 68%);
    pointer-events: none;
}

.hero__eyebrow {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--blue-300);
}

.hero__title {
    font-size: clamp(1.75rem, 3vw, 2.5rem);
    font-weight: 800;
    letter-spacing: -0.03em;
    color: #fff;
    margin-top: 0.4rem;
    line-height: 1.05;
}

.hero__chips {
    display: flex;
    gap: 0.55rem;
    flex-wrap: wrap;
    margin-top: 1.2rem;
    position: relative;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 700;
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.16);
    backdrop-filter: blur(4px);
}

.chip--good { background: rgba(94, 186, 133, 0.2); border-color: rgba(94, 186, 133, 0.38); }
.chip--warn { background: rgba(226, 178, 96, 0.2); border-color: rgba(226, 178, 96, 0.4); }
.chip--crit { background: rgba(224, 130, 120, 0.2); border-color: rgba(224, 130, 120, 0.42); }

/* Statuspille på lys flade.
   .chip ovenfor har hvid tekst og er bygget til at ligge oven på en mørk hero —
   den har endda backdrop-filter. Bruges den på et almindeligt hvidt panel, bliver
   det hvid tekst på 20 % gennemsigtig farve, og så forsvinder den næsten.
   Denne bruger temaets lyse status-baggrunde med en mørknet tekstfarve, så
   kontrasten holder WCAG AA (4,5:1). Tallene er efterregnet i tests/kontrastcheck. */
.pil {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0;
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Prik og ord frem for fyldt pille.
   En række fyldte piller under hinanden bliver til et farvet gardin, hvor ingen enkelt skiller
   sig ud. Prikken bærer farven, ordet bærer betydningen, og fladen forbliver rolig — så er det
   den ENE røde, der springer i øjnene, og ikke alle tredive tilsammen.
   Prikken tegnes med ::before, så ingen markup skal røres. */
.pil::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 999px;
    background: currentColor;
    flex-shrink: 0;
}

.pil--good { color: var(--good-ink); }
.pil--warn { color: var(--warn-ink); }
.pil--crit { color: var(--crit-ink); }

/* Neutral = «vi ved det ikke». Den er åben frem for fyldt, fordi et hult mærke læses som et
   fravær af svar, hvor et fyldt læses som et svar. Det er præcis forskellen på «ukendt» og
   de tre andre. */
.pil--neutral { color: var(--muted); }
.pil--neutral::before {
    background: transparent;
    box-shadow: inset 0 0 0 1.5px currentColor;
}

/* ==========================================================================
   Bento grid
   ========================================================================== */

.bento {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 1.15rem;
    margin-bottom: 1.5rem;
}

/* Egne span-klasser — IKKE .col-N: Bootstraps .col-N sætter width:25% o.l.,
   hvilket vinder over grid-column og klemmer felterne sammen. */
.span-3 { grid-column: span 3; }
.span-4 { grid-column: span 4; }
.span-5 { grid-column: span 5; }
.span-6 { grid-column: span 6; }
.span-7 { grid-column: span 7; }
.span-8 { grid-column: span 8; }
.span-12 { grid-column: span 12; }

@media (max-width: 1180px) {
    .span-3, .span-4 { grid-column: span 6; }
    .span-5, .span-7, .span-8 { grid-column: span 12; }
}

@media (max-width: 640px) {
    /* span-6 er store paneler og skal have hele bredden.
       span-3 er nøgletalsfelter — dem beholder vi to og to.

       De stod før i fuld bredde hver for sig, og fire felter fyldte omkring 600 px:
       tre skærmfulde rulning på en telefon, før man overhovedet nåede indholdet. Et
       felt med ét tal har ikke brug for 375 px. */
    .span-6 { grid-column: span 12; }

    /* span-4 manglede. Den blev til span 6 ved 1180 px, og der stoppede den — så
       sidepanelet med sagens detaljer stod i halv bredde på en telefon, med felter
       klemt ned i 160 px. Det så ud som en fejl, fordi det var en. */
    .span-4 { grid-column: span 12; }
}

/* ==========================================================================
   Stat tile
   ========================================================================== */

.stat {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm);
    padding: 1.3rem 1.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    position: relative;
    min-height: 100%;
    transition: box-shadow 0.16s ease, transform 0.16s ease;
}

.stat:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }

.stat__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 0.15rem;
}

.stat__label {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
}

.stat__dot {
    width: 30px;
    height: 30px;
    border-radius: 9px;
    display: grid;
    place-items: center;
    background: var(--blue-50);
    color: var(--navy-700);
    flex-shrink: 0;
}

.stat--good .stat__dot { background: var(--good-bg); color: var(--good); }
.stat--warn .stat__dot { background: var(--warn-bg); color: var(--warn); }
.stat--crit .stat__dot { background: var(--crit-bg); color: var(--crit); }

.stat__value {
    font-size: 2.15rem;
    font-weight: 800;
    letter-spacing: -0.035em;
    line-height: 1.05;
    color: var(--ink);
}

.stat__meta {
    font-size: 0.81rem;
    color: var(--faint);
}

/* ==========================================================================
   Meter / progress
   ========================================================================== */

.meter {
    height: 10px;
    border-radius: 999px;
    background: var(--blue-50);
    overflow: hidden;
    box-shadow: inset 0 0 0 1px var(--line);
}

.meter__fill {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--navy-700), var(--blue-500));
}

.meter__fill--warn { background: linear-gradient(90deg, #a06f28, var(--warn)); }
.meter__fill--crit { background: linear-gradient(90deg, #8f3a33, var(--crit)); }

.bigfig {
    font-size: 2.9rem;
    font-weight: 800;
    letter-spacing: -0.04em;
    line-height: 1;
    color: var(--ink);
}

.bigfig small {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--faint);
    letter-spacing: -0.01em;
}

/* ==========================================================================
   Module list (dashboard)
   ========================================================================== */

.mods { display: flex; flex-direction: column; gap: 0.45rem; }

.mods__row {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--r-sm);
    background: var(--blue-50);
    font-size: 0.87rem;
    font-weight: 600;
    color: var(--ink-2);
}

.mods__row .icon { color: var(--navy-700); flex-shrink: 0; }
.mods__row span { margin-left: auto; font-size: 0.75rem; font-weight: 700; color: var(--good); }

/* ==========================================================================
   Aftalekort
   ========================================================================== */

.agr-list { display: flex; flex-direction: column; gap: 1rem; }

.agr {
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: 1.1rem 1.2rem;
    background: linear-gradient(180deg, var(--blue-50), var(--paper));
}

.agr__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.agr__name { font-weight: 700; font-size: 0.98rem; color: var(--ink); }

.agr__bill {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.9rem;
    padding-top: 0.75rem;
    border-top: 1px dashed var(--line-2);
    font-size: 0.83rem;
    color: var(--warn);
}

.agr__outside {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin-top: 0.85rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--r-sm);
    background: var(--paper);
    border: 1px dashed var(--line-2);
    font-size: 0.83rem;
    color: var(--ink-2);
}

.agr__outside span { display: flex; flex-direction: column; }
.agr__outside .icon { margin-top: 2px; color: var(--blue-500); }

/* ==========================================================================
   Domænekort (Domænesikkerhed) — grupperet pr. kunde i stedet for én flad tabel,
   så det stadig er overskueligt med flere domæner pr. kunde og flere checks.
   ========================================================================== */

.dgroup {
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--paper);
    box-shadow: var(--shadow-sm);
    margin-bottom: 1rem;
    overflow: hidden;
}

.dgroup__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 1rem 1.2rem;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

.dgroup__summary::-webkit-details-marker { display: none; }

.dgroup__summary::before {
    content: "";
    width: 8px;
    height: 8px;
    border-right: 2px solid var(--ink-2);
    border-bottom: 2px solid var(--ink-2);
    transform: rotate(-45deg);
    transition: transform 0.15s ease;
    margin-right: 0.5rem;
    flex-shrink: 0;
}

.dgroup[open] > .dgroup__summary::before { transform: rotate(45deg); }

.dgroup__name { font-weight: 700; font-size: 0.95rem; }

/* ── Dmarc-afsendere ──────────────────────────────────────────────────────
   Tre bunker: fejl på egne systemer, ukendte afsendere, og alt der er i orden.
   Farven bæres af en venstrekant, så alvoren kan skimmes lodret uden at læse. */
.afs-gruppe { margin-top: 1.2rem; }
.afs-gruppe:first-of-type { margin-top: 0.4rem; }

.afs-gruppe__titel { font-weight: 800; font-size: 0.92rem; cursor: default; }
.afs-gruppe__titel--crit { color: var(--crit); }
.afs-gruppe__titel--warn { color: var(--warn); }
.afs-gruppe__titel--ok { color: var(--good); cursor: pointer; }

.afs-gruppe__sub { font-size: 0.82rem; color: var(--muted); margin: 0.15rem 0 0.7rem; max-width: 48rem; }

/* Ét kort pr. SYSTEM, ikke pr. IP. Hviletilstanden er én linje: prik, navn, tal, bjælke.
   Alt andet — råd, serveradresser, godkendelsesknap — hænger under og fylder kun, når
   der faktisk er noget at sige. */
.afs {
    border: 1px solid var(--line);
    border-left: 3px solid var(--line-2);
    border-radius: var(--r-md);
    padding: 0.6rem 0.85rem;
    margin-bottom: 0.4rem;
    background: var(--paper);
}

.afs--crit { border-left-color: var(--crit); }
.afs--warn { border-left-color: var(--warn); }
.afs--ok { border-left-color: var(--good); }

.afs__hd { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.afs__flex { flex: 1 1 2rem; }

.afs__prik { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--faint); }
.afs__prik--crit { background: var(--crit); }
.afs__prik--warn { background: var(--warn); }
.afs__prik--ok { background: var(--good); }

.afs__navn { font-weight: 700; font-size: 0.9rem; }

/* Antallet af servere hører til navnet, ikke til tallene: det forklarer, hvorfor
   der står ét kort, hvor der før stod tyve. */
.afs__badge {
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--muted);
    background: color-mix(in srgb, var(--ink) 6%, transparent);
    border-radius: 999px;
    padding: 0.1rem 0.45rem;
}

.afs__tal { font-size: 0.82rem; white-space: nowrap; }

/* Bjælken gør andelen skimbar. Den er lille med vilje — tallet er svaret, bjælken er formen. */
.afs__bar {
    flex: none;
    width: 72px;
    height: 6px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--crit) 55%, transparent);
    overflow: hidden;
}

.afs__bar > i { display: block; height: 100%; background: var(--good); }

/* Rådet er det, siden findes for — derfor mere fremtrædende end tallene. */
.afs__raad { font-size: 0.84rem; color: var(--ink-2); margin-top: 0.4rem; line-height: 1.5; }
.afs__raad code { background: color-mix(in srgb, var(--ink) 7%, transparent); padding: 0.05rem 0.3rem; border-radius: 4px; }

.afs__handling { margin-top: 0.5rem; }
.afs__knap { margin-top: 0; }

/* IP'en sidst og småt: den er dokumentation, ikke svaret. Før stod den som overskrift,
   og så skulle man selv være detektiv. */
.afs__ip { font-size: 0.74rem; color: var(--faint); margin-top: 0.35rem; }

.afs__kilder { margin-top: 0.35rem; }
.afs__kilder > summary { font-size: 0.74rem; color: var(--muted); cursor: pointer; }
.afs__kilder > summary:hover { color: var(--ink-2); }

.afs__kildeliste { margin-top: 0.4rem; border-top: 1px solid var(--line); }

.afs__kilde {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.28rem 0;
    font-size: 0.76rem;
    border-bottom: 1px solid var(--line);
}

.afs__kilde-ip { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; color: var(--ink-2); }
.afs__kilde-tal { white-space: nowrap; }

/* ── Dmarc: kunde-chip og tværgående tabel ────────────────────────────────
   Medarbejderens indgang. Uden kunde-chippen kunne man ikke se, hvis tal man
   stod og kiggede på — og tallene på tværs af kunder er ikke nogens tal. */
.dm-kunde-chip {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-weight: 700;
    font-size: 0.88rem;
    color: var(--ink);
    margin-bottom: 0.75rem;
}

.dm-kunde-chip svg { width: 16px; height: 16px; color: var(--muted); }

.dm-kunder__row { cursor: pointer; }
.dm-kunder__row:hover { background: var(--blue-50); }
.dm-kunder__row:focus-visible { outline: 2px solid var(--brand, var(--ink-2)); outline-offset: -2px; }
.dm-kunder__navn { font-weight: 700; }

/* Den valgte kunde bliver stående markeret, så man kan se hvis postkasse
   panelet nedenunder hører til, mens man arbejder i den. */
.dm-kunder__row.er-valgt { background: var(--blue-50); }
.dm-kunder__row.er-valgt td:first-child { box-shadow: inset 3px 0 0 var(--ink-2); }

.dm-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 0.5rem; background: var(--faint); }
.dm-dot--ok { background: var(--good); }
.dm-dot--warn { background: var(--warn); }
.dm-dot--crit { background: var(--crit); }

/* Ingen rapporter modtaget. Hul frem for fyldt, saa den ikke kan forveksles med en
   maalt tilstand — hverken den groenne eller den roede. */
.dm-dot--tom {
    background: transparent;
    box-shadow: inset 0 0 0 1.5px var(--faint);
}

.dm-rate { font-variant-numeric: tabular-nums; }

.dm-bar {
    display: block;
    width: 80px;
    height: 5px;
    margin-left: auto;
    margin-top: 0.25rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--crit) 55%, transparent);
    overflow: hidden;
}

.dm-bar > i { display: block; height: 100%; background: var(--good); }

.txt-crit { color: var(--crit); }
.txt-warn { color: var(--warn); }
.txt-faint { color: var(--faint); }
.txt-muted { color: var(--muted); }

/* Klik-for-at-rette-markør: prikket understregning, så inline-redigering er synlig som
   redigerbar uden at man skal hovere. Samlet cue for de steder, der før kun havde cursor+title. */
.editcue { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.editcue:hover { text-decoration-color: var(--blue-400); }

/* Klikbar række UDEN ugyldig ARIA-nesting. Før var rækken selv role="button" med rigtige
   <button>-handlinger indeni — en knap i en knap. Nu er rækken ikke interaktiv; «hit»-elementet
   (et <a> eller en <button>) dækker hele rækken via ::after (stretched link), og handlingsknapper
   løftes over med z-index, så de stadig kan klikkes hver for sig. Tastatur: hit-elementet er
   tab-stoppet. Bruges på Vidensbase-rækker og notifikationsrækker. */
.stretchrow { position: relative; }
.stretchrow__hit { text-decoration: none; color: inherit; }
.stretchrow__hit::after { content: ""; position: absolute; inset: 0; }
/* Når hit er en <button>: nulstil knap-look, så den ligner den tekst, den dækker. */
button.stretchrow__hit { border: 0; background: transparent; padding: 0; margin: 0; font: inherit; text-align: inherit; cursor: pointer; }
.stretchrow__over { position: relative; z-index: 1; }

/* .muted som alias, ikke som tyve omdøbninger.
   Klassen står 20 steder — Agents, Maintenance, NetworkScan — uden nogensinde at være
   skrevet, så de linjer blev tegnet i fuld brødtekstfarve i stedet for dæmpet. Det er
   værst dér, hvor den bruges til «vi ved det ikke»-sætninger som «adresse ukendt endnu»:
   en usikker oplysning så lige så bestemt ud som en målt. Samme aliasteknik som .tbl. */
.muted { color: var(--muted); }

/* ── Indstillinger ────────────────────────────────────────────────────────
   Kategorier til venstre, tætte rækker til højre, søgning øverst.

   Det afgørende skifte er fra kort til rækker. Et kort pr. indstilling fylder som en
   reklame og gav fire pr. skærm; en række giver tolv. Når man leder efter noget, er
   antallet man kan se på én gang næsten hele oplevelsen. */
.settings__top {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.4rem;
}

.setsearch {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 0.6rem 1rem;
    color: var(--muted);
    min-width: min(24rem, 100%);
}

.setsearch:focus-within { border-color: var(--blue-300); box-shadow: 0 0 0 3px color-mix(in srgb, var(--blue-300) 20%, transparent); }

.setsearch__felt {
    flex: 1;
    min-width: 0;
    border: 0;
    background: none;
    font: inherit;
    color: var(--ink);
    outline: none;
}

/* Genvejen vises, indtil man skriver — så bliver den til en ryd-knap. Feltet skifter
   altså aldrig bredde, og der er ingen knap, der dukker op og skubber til noget. */
.setsearch__kbd {
    font-size: 0.7rem;
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 0.05rem 0.35rem;
    color: var(--faint);
}

.setsearch__ryd {
    display: inline-flex;
    border: 0;
    background: none;
    color: var(--muted);
    cursor: pointer;
    padding: 0;
}

.setsearch__ryd:hover { color: var(--ink); }

/* Emne-rækken øverst på en enkelt indstillingsside. Vandret og kompakt: den skal
   kunne skimmes på én linje, ikke konkurrere med sidens indhold om opmærksomheden.
   Ruller vandret på mobil frem for at brække i tre rækker. */
.setnav {
    display: flex;
    gap: 0.3rem;
    overflow-x: auto;
    padding-bottom: 0.4rem;
    margin-bottom: 1.1rem;
    scrollbar-width: thin;
}

/* Emnevælgeren. To udgaver af samme navigation, fordi en vandret fanerække og en
   telefonskærm ikke kan forliges: otte faner fylder 1192 px, og den aktive kan ligge
   helt uden for skærmen. Målt, ikke gættet. */
.setnav-mobil { display: none; margin-bottom: 1.1rem; }
.setnav-mobil label { display: block; margin-bottom: 0.3rem; }

@media (max-width: 700px) {
    .setnav { display: none; }
    .setnav-mobil { display: block; }
}

.setnav__link {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex-shrink: 0;
    padding: 0.42rem 0.7rem;
    border-radius: 999px;
    border: 1px solid var(--line);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--muted);
    text-decoration: none;
    white-space: nowrap;
}

.setnav__link:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); color: var(--ink); }

.setnav__link--aktiv {
    background: color-mix(in srgb, var(--blue-300) 16%, transparent);
    border-color: color-mix(in srgb, var(--blue-300) 45%, transparent);
    color: var(--ink);
}

/* ==========================================================================
   Endpoint-rækker (Driftsovervågning)

   Kort til alt gav 16 enheder samme vægt, uanset om noget var galt. Det, man
   åbner siden for at vide, druknede i det, man ikke spurgte om. Nu: fuld visning
   kun til det, der kræver noget, og tætte rækker til resten — med detaljerne ét
   klik væk via <details>, så det virker uden JavaScript og med tastatur.
   ========================================================================== */

.eptools { display: flex; gap: 0.4rem; flex-wrap: wrap; justify-content: flex-end; margin-top: 1rem; }

/* «Vis 4 konti» på et sikkerhedsfund. Foldet sammen, fordi anbefalingen er det, man
   skal læse først — navnene er det, man skal bruge bagefter. */
.sscore__hvem { margin-top: 0.5rem; font-size: 0.82rem; }

.sscore__hvem > summary {
    cursor: pointer;
    /* --blue-600 findes ikke; farven faldt derfor tilbage til arvet brødtekst, og
       «Vis 4 konti» så ud som almindelig tekst frem for noget, man kan klikke på.
       --navy-700 er husets linkfarve (--bs-link-color). */
    color: var(--navy-700);
    font-weight: 700;
    list-style: none;
    display: inline-block;
    padding: 0.2rem 0;
}

.sscore__hvem > summary::-webkit-details-marker { display: none; }
.sscore__hvem > summary::before { content: "▸ "; }
.sscore__hvem[open] > summary::before { content: "▾ "; }
.sscore__hvem > summary:hover { text-decoration: underline; }

.sscore__hvem ul {
    margin: 0.4rem 0 0;
    padding-left: 1.1rem;
    line-height: 1.7;
    color: var(--ink-2);
}

/* Et panel uden indhold. Beholder sin overskrift, så strukturen kan ses, men holder op
   med at fylde som om der stod noget i det — årshjulets fire kvartaler brugte ellers
   hele skærmen på fire gange «Intet planlagt». */
.panel--tom {
    padding-bottom: 0;
    background: transparent;
    box-shadow: none;
    border-style: dashed;
}

.panel--tom .panel__head { margin-bottom: 0; padding-bottom: 0.9rem; border-bottom: 0; }
.panel--tom .panel__title { color: var(--muted); }

.epsek { margin-top: 1.4rem; }

.epsek__titel {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.82rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.6rem;
}

.epsek__antal {
    font-weight: 600;
    color: var(--faint);
    font-variant-numeric: tabular-nums;
    text-transform: none;
    letter-spacing: 0;
}

.eprows {
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--paper);
    overflow: hidden;
}

.eprow { border-bottom: 1px solid var(--line); }
.eprow:last-child { border-bottom: 0; }
.eprow[open] { background: color-mix(in srgb, var(--ink) 3%, transparent); }

.eprow__sum {
    display: grid;
    grid-template-columns: 0.6rem minmax(0, 2fr) minmax(0, 1.2fr) 4.5rem 7rem 5rem 4rem;
    align-items: center;
    gap: 0.75rem;
    padding: 0.62rem 0.9rem;
    cursor: pointer;
    list-style: none;
    font-size: 0.86rem;
}

/* Kolonneoverskrifter over de tætte rækker. Samme gitter som .eprow__sum — ellers
   står etiketterne ikke over deres egne kolonner, og så er de værre end ingen. */
.eprows__hoved {
    display: grid;
    grid-template-columns: 0.6rem minmax(0, 2fr) minmax(0, 1.2fr) 4.5rem 7rem 5rem 4rem;
    gap: 0.75rem;
    padding: 0 0.9rem 0.4rem;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Tal højrestilles i rækkerne, så overskrifterne skal følge med. */
.eprows__hoved span:nth-child(5),
.eprows__hoved span:nth-child(6) { text-align: right; }

/* Domænevarianten. Modifier på selve elementet, ikke en efterkommer-selektor: mobil-
   reglen nedenfor rammer .eprow__sum med samme specificitet og skal kunne vinde, fordi
   den står senere. En `.eprows--dom .eprow__sum` ville stille tabe det opgør. */
.eprow__sum--dom { grid-template-columns: 0.6rem minmax(0, 2fr) minmax(0, 1.4fr) 4.5rem 5.5rem; }

.eprow__sum::-webkit-details-marker { display: none; }
.eprow__sum:hover { background: color-mix(in srgb, var(--blue-300) 8%, transparent); }

.eprow__prik { width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--faint); }
.eprow__prik--oppe { background: var(--good); }
.eprow__prik--langsom { background: var(--warn); }
.eprow__prik--nede { background: var(--crit); }
.eprow__prik--kritisk { background: var(--crit); }

.eprow__navn { font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eprow__kunde,
.eprow__type,
.eprow__svar,
.eprow__tid { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eprow__score { color: var(--muted); }
.eprow__svar,
.eprow__tid,
.eprow__score { font-variant-numeric: tabular-nums; text-align: right; }

.eprow__krop { padding: 0 0.7rem 0.7rem; }

/* ── The ticket queue ────────────────────────────────────────────────────────────────────
   The same family as .eprow, with one difference: the row is a LINK to the case, not an
   expander. So .eprow and .eprow__sum sit on the SAME element — .eprow contributes only a
   bottom border, and a wrapper per row would be an element with no job.

   Eight columns in the order you triage in: mark, urgency, what, who, which kind, how far,
   when, whose. Category is the first to give up space on a narrow window — it is something you
   filter by, not something you scan. */
.eprow__sum--sag {
    grid-template-columns: 1.1rem 0.6rem minmax(0, 2.2fr) minmax(0, 1.1fr) minmax(0, 0.8fr) 9.2rem 6rem 3.4rem;
}

/* The headings live inside the frame with the rows, not floating above it: a column label
   detached from its column does not read as a heading. The grid must stay identical to
   .eprow__sum--sag above — tests/sagsgittercheck compares the two, because nothing else would
   notice them drifting apart. */
.eprows__hoved--sag {
    grid-template-columns: 1.1rem 0.6rem minmax(0, 2.2fr) minmax(0, 1.1fr) minmax(0, 0.8fr) 9.2rem 6rem 3.4rem;
    padding: 0.45rem 0.9rem;
    border-bottom: 1px solid var(--line);
    background: color-mix(in srgb, var(--ink) 2%, transparent);
    align-items: center;
}

.eprow--sag { text-decoration: none; color: inherit; }
.eprow--sag:focus-visible { outline: 2px solid var(--blue-400); outline-offset: -2px; }
.eprow--sag.tkt--done { opacity: 0.55; }

/* Priority: only High and Critical are drawn. «Normal» on every single row says nothing, and
   the difference between two shades of blue four pixels wide could only be seen by somebody who
   already knew it was there. The same decision the customer-facing list reached first. */
.sagprio {
    width: 4px;
    height: 1.1rem;
    border-radius: 999px;
    align-self: center;
}
.sagprio--hoej { background: var(--warn); }
.sagprio--kritisk { background: var(--crit); }

/* Status: dot plus word. A filled badge per row turned into a curtain of colour — the house's
   own argument sits at the .badge rules. The dot carries the colour, the word the meaning. */
.sagstatus {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--ink-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sagstatus .eprow__prik { flex-shrink: 0; }

.eprow__prik--ny { background: var(--blue-400); }
.eprow__prik--aaben { background: var(--warn); }
.eprow__prik--venter-kunde { background: var(--faint); }
.eprow__prik--venter-lev { background: var(--blue-300); }
.eprow__prik--loest { background: var(--good); }
.eprow__prik--lukket { background: var(--line-2); }

/* Number and title in one cell. The number is muted: it is an address, not information. */
.sagnavn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650; }
.sagnavn__nr { color: var(--faint); font-variant-numeric: tabular-nums; font-weight: 600; }
.sagnavn__mail { color: var(--faint); margin-left: 0.3rem; vertical-align: -1px; }

/* Deadline or age. A missed deadline is the one thing in the row that has to be visible without
   reading it — hence colour and not only text. */
.sagtid { font-variant-numeric: tabular-nums; text-align: right; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sagtid--frist { color: var(--ink-2); font-weight: 650; }
.sagtid--over { color: var(--crit-ink, var(--crit)); font-weight: 700; }

/* Initials or «take». The column is deliberately narrow: it is scanned for «is this anybody's?»,
   not read. */
.sagejer { display: flex; justify-content: flex-end; }

/* Domænesikkerhed — kompakt listevisning. Samme tæthed og farvesprog som .eprow, men med
   en statusprik pr. tjek (SPF/DMARC/DKIM/DNSSEC …), så mange domæner kan skimmes på én skærm.
   Rækken foldes ud til det fulde kort ved klik; kun den udfoldede række tegner kortet. */
.dsp-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.55rem 0.9rem;
    border-bottom: 1px solid var(--line);
    cursor: pointer;
    font-size: 0.86rem;
}
.dsp-row:hover { background: color-mix(in srgb, var(--blue-300) 8%, transparent); }
.dsp-row__sev { flex: 0 0 auto; width: 0.6rem; height: 0.6rem; border-radius: 50%; background: var(--faint); }
.dsp-row__navn { flex: 1 1 38%; min-width: 0; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsp-row__kunde { flex: 1 1 22%; min-width: 0; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dsp-row__checks { flex: 0 0 auto; display: flex; gap: 0.35rem; }
.dsp-row__score { flex: 0 0 auto; min-width: 2.6rem; text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
.dsp-row__chev { flex: 0 0 auto; width: 1rem; text-align: center; color: var(--muted); }
.dsp-row__krop { padding: 0.3rem 0.5rem 1rem; }

.dsp-dot { flex: 0 0 auto; width: 0.56rem; height: 0.56rem; border-radius: 50%; background: var(--faint); }
.dsp-dot--ok { background: var(--good); }
.dsp-dot--warn { background: var(--warn); }
.dsp-dot--crit { background: var(--crit); }

/* Filterstriben «Mangler pr. type» over listen. */
.dsp-strip { margin: -0.35rem 0 1rem; align-items: center; }
.dsp-strip__label { margin-right: 0.15rem; }

/* Mobil: kundenavnet viger, så domæne + prikker + score bliver på linjen. */
@media (max-width: 700px) {
    .dsp-row__kunde { display: none; }
}

/* Mobil: seks kolonner kan ikke stå ved siden af hinanden på 375 px. Navn og
   tidspunkt bliver på første linje — det er dem, man skanner efter — og kunden
   lægger sig under som én dæmpet linje.

   Placeringen er eksplicit med vilje. Type og svartid skjules her, og skjulte
   celler deltager ikke i auto-placeringen: klokkeslættet endte i prik-kolonnen
   på 0,6 rem og blev klippet til "0", hvilket lignede en måling, ikke et ur. */
@media (max-width: 700px) {
    .eprow__sum {
        grid-template-columns: 0.6rem minmax(0, 1fr) auto;
        row-gap: 0.15rem;
        padding: 0.7rem 0.8rem;
    }

    .eprow__prik { grid-column: 1; grid-row: 1; }
    .eprow__navn { grid-column: 2; grid-row: 1; }
    .eprow__tid { grid-column: 3; grid-row: 1; text-align: right; font-size: 0.78rem; }
    .eprow__kunde { grid-column: 2 / -1; grid-row: 2; font-size: 0.78rem; }

    .eprow__type,
    .eprow__svar,
    .eprow__score { display: none; }

    /* Rækken folder sig til to linjer her, så der findes ingen kolonner at sætte
       overskrifter over. */
    .eprows__hoved { display: none; }
}

.settings__body { display: grid; grid-template-columns: 13rem 1fr; gap: 2rem; align-items: start; }

/* Klæber, så kategorierne følger med ned gennem en lang side. */
.settings__rail { position: sticky; top: 1.5rem; display: flex; flex-direction: column; gap: 0.1rem; }

.settings__raillink {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    border-radius: var(--r-md);
    font-size: 0.84rem;
    font-weight: 700;
    color: var(--ink-2);
    text-decoration: none;
}

.settings__raillink:hover { background: color-mix(in srgb, var(--ink) 5%, transparent); color: var(--ink); }

.settings__railtal { font-size: 0.72rem; font-weight: 600; color: var(--faint); font-variant-numeric: tabular-nums; }

.setgroup { margin-bottom: 2.2rem; scroll-margin-top: 1.5rem; }
.setgroup__titel { font-size: 1.02rem; font-weight: 800; margin: 0 0 0.15rem; }
.setgroup__sub { font-size: 0.84rem; color: var(--muted); margin: 0 0 0.8rem; max-width: 46rem; }

.setrows {
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--paper);
    overflow: hidden;
}

.setrow {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.8rem 1rem;
    text-decoration: none;
    color: inherit;
    border-bottom: 1px solid var(--line);
}

.setrow:last-child { border-bottom: 0; }
.setrow:hover { background: color-mix(in srgb, var(--blue-300) 8%, transparent); }

.setrow__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: var(--r-md);
    background: color-mix(in srgb, var(--blue-300) 16%, var(--paper));
    color: var(--ink-2);
    flex-shrink: 0;
}

.setrow__main { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.setrow__titel { font-weight: 700; font-size: 0.9rem; }
.setrow__sub { font-size: 0.8rem; color: var(--muted); }

.setrow__pil { color: var(--faint); font-size: 1.2rem; flex-shrink: 0; }
.setrow:hover .setrow__pil { color: var(--ink-2); }

/* Under 900 px falder kategorilisten væk — der er ikke plads til to spalter, og
   søgefeltet er alligevel den hurtigste vej på en telefon. */
@media (max-width: 900px) {
    .settings__body { grid-template-columns: 1fr; }
    .settings__rail { display: none; }
}

/* Egne SNMP-målinger i redigeringsformularen. */
.oid-liste {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: 0.5rem 0.6rem;
}

.oid-række {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.82rem;
}

.oid-række__navn { font-weight: 700; min-width: 7rem; }

/* OID'er er lange og må gerne klippes — det er navnet, man leder efter. */
.oid-række__oid {
    color: var(--muted);
    font-size: 0.76rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
    min-width: 0;
}

/* Kundebilledet på staff-forsiden. Tæt med vilje: den skal kunne skimmes lodret,
   så man ser hvem der kalder, uden at læse hver celle. */
.kb tbody td { padding: 0.55rem 0.9rem; font-size: 0.84rem; white-space: nowrap; }
.kb tbody tr:hover { background: var(--blue-50, rgba(0,0,0,0.02)); }

/* Hele rækken fører ind til kunden. position:relative gør rækken til udgangspunkt
   for det udstrakte link i sidste celle, så klik hvor som helst på linjen åbner. */
.kb__row { position: relative; cursor: pointer; }
.kb__open { font-weight: 600; }
.kb__row:hover .kb__open { text-decoration: underline; }

/* Venstrekant frem for baggrundsfarve på hele rækken: farven skal pege på, hvor
   man skal kigge, ikke overdøve tallene i cellerne. */
.kb--crit td:first-child { box-shadow: inset 3px 0 0 var(--crit); }
.kb--warn td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

.kb__ok { color: var(--good); font-weight: 700; }
.kb__warn { color: var(--warn); font-weight: 700; }
.kb__crit { color: var(--crit); font-weight: 800; }
.kb__mut { color: var(--muted); }

/* ── Kundens forside ───────────────────────────────────────────────────────
   Statuslinjen er sidens vigtigste element: den skal kunne læses på et halvt
   sekund fra den anden side af skrivebordet. Derfor stor skrift og farve som
   bærende signal — ikke et tal i et felt. */
/* Status siges med en streg, ikke med et farvet felt.
   Det fyldte felt tog hele sidens bredde og gjorde ét forhold til sidens dominerende flade,
   uanset hvor alvorligt det var — «alt kører» råbte lige så højt som «noget er galt». Nu bærer
   venstrekanten farven, fladen forbliver papir, og tinten er skruet ned til en antydning
   (4 %), der stadig kan ses, men ikke overtager.
   Farven sættes ét sted, --status-farve, så streg, tint, kant og ikon ikke kan komme i utakt. */
.status {
    --status-farve: var(--good);
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 1.15rem 1.3rem;
    border-radius: 4px var(--r-lg) var(--r-lg) 4px;
    border: 1px solid color-mix(in srgb, var(--status-farve) 22%, var(--line));
    border-left: 3px solid var(--status-farve);
    background: color-mix(in srgb, var(--status-farve) 4%, var(--paper));
    margin-bottom: 1.1rem;
}

.status--ok   { --status-farve: var(--good); }
.status--obs  { --status-farve: var(--warn); }
.status--krit { --status-farve: var(--crit); }

/* Tom er ikke det samme som i orden.
   Et bibliotek uden dokumenter, en side uden agenter, en overvågning uden endpoints —
   ingen af dem har noget galt, men ingen af dem gør heller noget. Et grønt flueben dér
   er den fejlklasse, platformen er blevet ramt af flest gange: den ser sund ud uden at
   have udført sit arbejde. Neutral grå siger det rigtige: der er ikke noget endnu. */
/* Tomtilstanden har ingen status at melde og skal derfor heller ikke have en farvet kant —
   den arver ellers den grønne standard og ville sige «alt kører» om ingenting. */
.status--tom { --status-farve: var(--line-2); background: var(--paper); }
.status--tom .status__ikon { color: var(--muted); }

.status__ikon { display: flex; flex-shrink: 0; }
.status--ok .status__ikon { color: var(--good-ink); }
.status--obs .status__ikon { color: var(--warn-ink); }
.status--krit .status__ikon { color: var(--crit-ink); }

.status__linje { font-size: 1.32rem; font-weight: 800; letter-spacing: -0.01em; color: var(--ink); line-height: 1.25; }
/* --ink-2, ikke --muted. Underlinjen bærer selve tallene — hvor mange der er overvåget,
   hvor mange der er i orden — og står på en tonet flade, hvor --muted lander på 3,9:1.
   Målt af kontrastcheck; --ink-2 klarer kravet på alle tre banner-toner. */
.status__under { font-size: 0.82rem; color: var(--ink-2); margin-top: 0.25rem; line-height: 1.4; }

/* På 375 px bryder sætningen i to, og en overskrift på 1,32 rem med brødtekstens
   linjeafstand river de to linjer fra hinanden. Mindre og tættere — den skal stadig
   være det første, øjet lander på, men den skal læses som én sætning. */
@media (max-width: 700px) {
    .status { padding: 1rem 1.05rem; gap: 0.7rem; align-items: flex-start; }
    .status__ikon { margin-top: 0.15rem; }
    .status__linje { font-size: 1.1rem; line-height: 1.3; }
}

/* "Det har vi lavet for jer" — sætninger, ikke felter.
   To spalter fra 900 px: på en bred skærm står seks korte linjer i én kolonne som en
   halvtom liste, og resten af skærmen er tom. */
.gjort {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem 2rem;
}

@media (min-width: 900px) {
    .gjort { grid-template-columns: 1fr 1fr; }
}

.gjort li {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--ink-2);
}

.gjort li > :first-child { color: var(--good); flex-shrink: 0; margin-top: 0.15rem; }

/* Aftalen: én linje, der kun vokser når den er ved at være brugt op. */
.aftale {
    display: block;
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--paper);
    padding: 0.8rem 1rem;
    margin-bottom: 1.1rem;
}

.aftale:hover { border-color: var(--blue-300); }
.aftale--pres { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }
.aftale--over { border-color: color-mix(in srgb, var(--crit) 45%, var(--line)); }

.aftale__top { display: flex; align-items: baseline; justify-content: space-between; gap: 0.7rem; }
.aftale__tekst { font-size: 0.9rem; color: var(--ink-2); }
.aftale__navn { color: var(--muted); }
.aftale__pct { font-size: 0.85rem; font-weight: 800; color: var(--muted); font-variant-numeric: tabular-nums; }

.aftale__bar {
    display: block;
    height: 6px;
    border-radius: 999px;
    background: var(--line);
    margin-top: 0.55rem;
    overflow: hidden;
}

.aftale__fill { display: block; height: 100%; background: var(--good); border-radius: 999px; }
.aftale--pres .aftale__fill { background: var(--warn); }
.aftale--over .aftale__fill { background: var(--crit); }

.aftale__note { display: block; font-size: 0.82rem; color: var(--ink-2); margin-top: 0.55rem; }

/* Kvittér og udsæt på et enhedskort. Egen række over handlingsknapperne, så det er
   tydeligt, at de hører til alarmen og ikke til enheden. */
.hnd {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.8rem;
    padding: 0.5rem 0.6rem;
    border: 1px dashed var(--line);
    border-radius: var(--r-md);
}

.hnd__tekst {
    font-size: 0.78rem;
    color: var(--muted);
}

/* Gruppefilter over enhedskortene. Knapper og ikke en dropdown: antallet pr. gruppe er
   halvdelen af pointen, og det kan man ikke se i en lukket liste. */
.gfilter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.2rem 0 0.9rem;
}

.gchip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--paper);
    color: var(--ink-2);
    padding: 0.32rem 0.75rem;
    font-size: 0.78rem;
    font-weight: 700;
    cursor: pointer;
}

.gchip:hover { border-color: var(--blue-300); }

/* --accent findes ikke i :root. En var() uden fallback til en ukendt variabel er
   ugyldig efter kaskaden, og outline arves ikke — reglen gav derfor slet INGEN
   fokusring, ikke bare en forkert farve. Den globale :where()-regel kunne ikke
   redde den: :where() tæller nul, så .gchip:focus-visible vandt med tomme hænder.
   Gruppefiltret på kundens driftsovervågning kunne dermed tabbes igennem uden at
   man kunne se hvor man var. */
.gchip:focus-visible { outline: 2px solid var(--blue-400); outline-offset: 2px; }

.gchip--valgt {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
}

/* Fremhæver den gruppe-chip, en enhed pt. trækkes hen over, så det er tydeligt, hvor
   slippet lander. Sættes kun, når slippet faktisk ville flytte enheden (se
   KanSætteGruppe i Noc.razor) — ellers ville en chip love en flytning, der ikke sker. */
.gchip--sigte {
    border-color: var(--blue-400);
    background: color-mix(in srgb, var(--blue-400) 14%, transparent);
    box-shadow: 0 0 0 2px var(--blue-300);
}

.gchip__antal {
    font-weight: 600;
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
}

/* «+ Ny gruppe» og den netop oprettede, endnu tomme gruppe. Stiplet kant = «her kan der
   komme noget»: knappen inviterer til at oprette en gruppe, den ventende chip til at trække
   en enhed ind. En ventende gruppe lever kun i browseren, til den får sin første enhed —
   så bliver den en almindelig (massiv) chip. Se nyeGrupper i Noc.razor. */
.gchip--ny {
    border-style: dashed;
    background: transparent;
    color: var(--ink-2);
}
.gchip--ny:hover { border-color: var(--blue-400); color: var(--ink); }

.gchip--venter { border-style: dashed; }

/* Lille rund «×» til at fjerne en tom, netop oprettet gruppe. Sidder som søskende lige efter
   sin ventende chip (ikke inde i den — en knap i en knap er ugyldig markup). Negativ venstre-
   margin trækker den ind mod chippen, så de læses som ét. */
.gchip--fjern {
    margin-left: -0.25rem;
    padding: 0.32rem 0.5rem;
    line-height: 1;
    border-style: dashed;
    color: var(--ink-2);
    font-weight: 700;
}
.gchip--fjern:hover { border-color: var(--crit); color: var(--crit-ink); }

.gchip-input {
    border: 1px solid var(--blue-400);
    border-radius: 999px;
    background: var(--paper);
    color: var(--ink);
    padding: 0.32rem 0.75rem;
    font-size: 0.78rem;
    font-weight: 700;
    font-family: inherit;
    width: 9.5rem;
    max-width: 45vw;
    outline: none;
}
.gchip-input::placeholder { color: var(--ink-2); font-weight: 500; }
.gchip-input:focus-visible { outline: 2px solid var(--blue-400); outline-offset: 2px; }

.dgroup__body {
    padding: 0 1.2rem 1.2rem;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
    gap: 0.9rem;

    /* Kortene i samme række bliver lige høje. Uden dette bestemte den enhed med flest
       målinger højden for hele rækken, og naboerne stod med et stort tomrum nedenunder. */
    align-items: stretch;
}

.dcard {
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    padding: 0.95rem 1.05rem;
    background: var(--paper);
    /* Farvet kant i venstre side gør det muligt at skimme hvilke domæner der har problemer. */
    border-left: 3px solid var(--blue-300);

    /* Knapperne nederst skal stå i bund uanset hvor meget indhold der er over dem,
       så "Rediger" og "Slet" sidder samme sted på alle kort i rækken. */
    display: flex;
    flex-direction: column;
}

.dcard .dcard__actions { margin-top: auto; }

/* Målingerne fylder det, der er plads til, og rulles derefter.
   En printer har let femten målinger; uden loftet blev dens kort tre gange så højt
   som naboernes, og hele rækken fulgte med. */
.dmetrics {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    max-height: 12rem;
    overflow-y: auto;
    /* Plads til rullepanelet, så teksten ikke ligger klods op ad det. */
    padding-right: 0.15rem;
}

.dcard--sev0 { border-left-color: var(--good); }
.dcard--sev1 { border-left-color: var(--warn); }
.dcard--sev2 { border-left-color: var(--crit); }

.dcard__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.8rem;
}

.dcard__name { font-weight: 700; font-size: 0.95rem; }

/* Kort "3/5"-score, så man ser sundhedstilstanden uden at læse alle rækker. */
.dcard__score {
    font-size: 0.78rem;
    font-weight: 800;
    padding: 0.2rem 0.5rem;
    border-radius: 999px;
    flex-shrink: 0;
    background: var(--blue-50);
    color: var(--ink-2);
}

.dcard__score--sev0 { background: var(--good-bg); color: var(--good); }
.dcard__score--sev1 { background: var(--warn-bg); color: var(--warn); }
.dcard__score--sev2 { background: var(--crit-bg); color: var(--crit); }

.dcard__badges {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    margin-bottom: 0.85rem;
}

.dcheck {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.78rem;
    min-width: 0;
}

.dcheck__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--faint);
    flex-shrink: 0;
}

.dcheck--ok .dcheck__dot { background: var(--good); }
.dcheck--warn .dcheck__dot { background: var(--warn); }
.dcheck--crit .dcheck__dot { background: var(--crit); }

/* Bredden er sat efter det længste navn, ikke efter det korteste.
   3,6rem passede til «SPF», «DKIM» og «CAA». Da tjekkene «Registrering»,
   «Navneservere», «Mailmodtagelse» og «Subdomæner» kom til, løb de ud over deres
   plads og landede oven i statussen ved siden af — nøjagtig samme fejl som med
   målingsnavnene et par regler nede, og med kommentaren allerede skrevet.

   nowrap og ellipsis er sikkerhedsnettet: kommer der en dag et endnu længere navn,
   bliver det klippet frem for at vælte rækken. */
.dcheck__name {
    font-weight: 700;
    color: var(--ink-2);
    letter-spacing: 0.02em;
    width: 7.4rem;
    flex-shrink: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Statussen maa heller ikke kunne ombryde. «Ikke tjekket» er to ord og brød til to
   linjer paa smalle kort, hvilket gjorde raekken dobbelt saa hoej og skubbede
   nabolinjen ind under sig. */
.dcheck__status {
    white-space: nowrap;
    flex-shrink: 0;
}

/* Målingsnavne er længere end "Ping" og "Cert.", som den faste bredde ovenfor er sat
   efter. "Toner sort" ombrød til to linjer og gjorde hver række dobbelt så høj, og
   "Printerstatus" løb ud over sin plads og oven i værdien ved siden af. */
.dcheck__name--metric {
    width: 6.4rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Værdien kan være alt fra "32 %" til en hel enhedsbeskrivelse fra en printer.
   Én linje, og resten klippes af — hele teksten står i title. */
.dcheck__status--metric {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dcheck__status { font-weight: 600; color: var(--muted); }
.dcheck--ok .dcheck__status { color: var(--good); }
.dcheck--warn .dcheck__status { color: var(--warn); }
.dcheck--crit .dcheck__status { color: var(--crit); }

/* «Ikke tjekket» skal tegnes dæmpet, fordi vi VÆLGER det — ikke fordi klassen mangler og
   den arver grundfarven. Forskellen er ikke synlig i dag, men den var det: DomainCheckStatus.Fejl
   pegede også på dcheck--muted og blev derfor tegnet som «vi kunne ikke måle», selv om Fejl
   er husets ord for et målt og udnytteligt problem. */
.dcheck--muted .dcheck__dot { background: var(--faint); }
.dcheck--muted .dcheck__status { color: var(--muted); }

.dcheck__detail {
    color: var(--faint);
    font-size: 0.73rem;
    margin-left: auto;
    max-width: 11rem;

    /* Uden den nægter flexbox at lade teksten krympe under sit indhold, og saa
       skubber den navn og status sammen i stedet for selv at blive klippet. */
    min-width: 0;
}

/* Domænekortet specifikt: detaljen flød før helt ud til højre (margin-left:auto) og
   efterlod et stort tomt mellemrum i midten. Giv status en fast kolonnebredde og lad
   detaljen flyde ind lige efter status og fylde resten af rækken — så pladsen bruges,
   og detaljerne flugter under hinanden. Scopet til .dcard__badges, så måle-/NOC-rækkerne,
   der deler .dcheck, er urørte. */
.dcard__badges .dcheck__status { min-width: 5.5rem; }
.dcard__badges .dcheck__detail {
    margin-left: 0;
    flex: 1 1 auto;
    max-width: none;
    text-align: left;
}

/* Tap-to-expand for the per-check help on the domain card. The row is a <details>; its <summary>
   carries the same flex layout the old .dcheck div had, so the inner .dcheck__* spans keep their
   colours and widths. The help text (previously only in the title= hover) drops down below on tap,
   so touch users can read it too. Scoped to .dchk — the .dcheck rows in the metric/NOC modules are
   untouched. */
.dchk { display: block; }
.dchk__sum {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.78rem;
    min-width: 0;
    cursor: pointer;
    list-style: none;
}
.dchk__sum::-webkit-details-marker { display: none; }
.dchk__sum::marker { content: ""; }
.dchk__more {
    margin-left: auto;
    flex: 0 0 auto;
    width: 1.05rem;
    height: 1.05rem;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--muted);
    border: 1px solid var(--line-2);
}
.dchk[open] .dchk__more { background: var(--faint); color: var(--ink-2); }
.dchk__help {
    font-size: 0.75rem;
    color: var(--muted);
    line-height: 1.4;
    padding: 0.2rem 0 0.5rem 1.15rem;
}
/* Comfortable tap target on touch. */
@media (max-width: 640px) {
    .dchk__more { width: 1.3rem; height: 1.3rem; }
}

.dsp-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.15rem 0.9rem;
    margin: 0.2rem 0 0.7rem;
}
.dsp-legend__intro { margin-right: 0.15rem; }
.dsp-legend__item strong {
    color: var(--ink-2);
    font-weight: 700;
    letter-spacing: 0.02em;
    margin-right: 0.15rem;
}

.dcard__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding-top: 0.7rem;
    border-top: 1px dashed var(--line-2);
}

/* Mini-historik ("sparkline") over de seneste målinger på et endpoint. */
/* Ét sammenhængende bånd, ikke et søjlediagram.
   To px mellemrum fik striben til at læses som 24 selvstændige målinger, man skulle tælle. Det er
   ikke det, den er til for — den er en TIDSLINJE, og den skal kunne aflæses i ét blik. En px er
   nok til, at bjælkerne stadig kan skelnes, hvis man ser efter.

   Højden bliver. Se .spark__bar--up/slow/down: den bærer alvoren sammen med farven, så striben
   også kan læses i gråtoner og af den, der ikke skiller rødt fra grønt — og grøn/gul/rød er
   præcis den akse, det går galt på. Et ensartet fuldhøjt bånd ville se pænere ud og fortælle
   mindre. */
.spark {
    display: flex;
    align-items: flex-end;
    gap: 1px;
    height: 22px;
    margin-bottom: 0.3rem;

    /* Svag bund under båndet: viser hvor langt vinduet rækker, også hvor bjælkerne er lave.
       Uden den svævede en stribe med idel korte bjælker uden nogen linje at hvile på. */
    border-bottom: 1px solid var(--line);
    padding-bottom: 1px;
}

.spark__spænd {
    font-size: 0.72rem;
    color: var(--muted);
    margin-bottom: 0.85rem;
    font-variant-numeric: tabular-nums;
}

.spark__bar {
    flex: 1;
    min-width: 3px;
    border-radius: 2px;
    background: var(--blue-200);
}

/* Højden bærer alvoren sammen med farven, så striben også kan læses i gråtoner og af den,
   der ikke skelner rødt fra grønt. Rækkefølgen er en trappe: oppe lavest, nede højest. */
.spark__bar--up { background: var(--good); height: 55%; }
.spark__bar--slow { background: var(--warn); height: 75%; }
.spark__bar--down { background: var(--crit); height: 100%; }

/* Kritisk er IKKE nede.
   De to var samme farve og samme højde før — men «fuld disk» og «svarer ikke» kræver hver sit
   opkald. Kritisk får derfor sin egen form: fuld højde som nede, men hul i midten, så den
   svarer-men-fejler-tilstand kan ses uden at læse et værktøjstip. */
.spark__bar--critical {
    height: 100%;
    background: linear-gradient(var(--crit) 0 35%, color-mix(in srgb, var(--crit) 30%, var(--paper)) 35% 65%, var(--crit) 65% 100%);
}

/* «Vi kunne ikke måle den» — typisk fordi noget foran den er nede. Hul frem for fyldt: et
   fravær af svar skal se ud som et fravær, ikke som endnu en tilstand. */
.spark__bar--unknown {
    height: 45%;
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--line-2);
}

/* Ingen måling, og ingen tæt nok bagved til at tale for spanden. Den laveste og svageste
   markering på striben — den siger «her ved vi ingenting», og det skal man kunne se. */
.spark__bar--notmeasured {
    height: 18%;
    background: var(--line);
}

/* Båret frem tegnes som alt andet.
   Den havde halv dækkraft, så en enhed målt hver time ikke lignede en målt hvert femte minut.
   Men i det normale tilfælde — alt grønt — gav det en stribe i to grønne, der flimrede uden at
   betyde noget, og som fik folk til at spørge hvad forskellen var. Svaret er ikke noget, man
   skal bruge, når det hele virker.
   Forskellen står stadig i værktøjstippet («målt» kontra «uændret siden sidste måling»), og det
   ene tilfælde, hvor den betyder noget — at vi ikke VED det — har sin egen markering i
   .spark__bar--notmeasured. */

/* Enkeltstående afvigelse — en måling, flapbeskyttelsen slog fra, fordi den ikke gentog
   sig. Værd at kunne se, men den er ikke et nedbrud og skal ikke ligne et.

   To signaler, ikke ét: skravering OG halv højde. Skraveringen alene forsvinder ved
   nedskalering, og højden alene kunne forveksles med "langsom". Sammen er de entydige.

   Rækkefølgen er ikke tilfældig: den skal stå EFTER farvereglerne ovenfor, som bruger
   background-genvejen. Placeret før blev background-image nulstilt af genvejen, og
   skraveringen blev aldrig tegnet — hvilket man ikke kan se på et skærmbillede, kun
   ved at måle den beregnede stil. */
.spark__bar--blip {
    height: 55%;
    background-image: repeating-linear-gradient(
        135deg,
        rgba(255, 255, 255, 0.6) 0 2px,
        rgba(255, 255, 255, 0) 2px 5px);
}

/* Signaturen til pulsstriben.
   Farverne stod indtil nu kun i et værktøjstip pr. bjælke — altså kun for den, der allerede gættede,
   at der var noget at holde musen over, og slet ikke for den på en telefon. Prikkerne genbruger
   bjælkernes former, ikke bare deres farver: den hule «kunne ikke måles» og den gennemskårne
   «kritisk» skal kunne genkendes igen nede i striben. */
.spark-sig {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem 1.1rem;
    padding: 0.75rem 0.2rem 0.1rem;
    font-size: 0.72rem;
    color: var(--muted);
}

.spark-sig__punkt {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    white-space: nowrap;
}

.spark-sig__prik {
    width: 4px;
    border-radius: 2px;
    flex-shrink: 0;
}

/* Samme trappe som i striben: oppe lavest, nede højest. Så bærer signaturen også højdens
   betydning, uden at skulle skrive den. */
.spark-sig__prik--up { height: 9px; background: var(--good); }
.spark-sig__prik--slow { height: 12px; background: var(--warn); }
.spark-sig__prik--down { height: 16px; background: var(--crit); }

.spark-sig__prik--critical {
    height: 16px;
    background: linear-gradient(var(--crit) 0 35%, color-mix(in srgb, var(--crit) 30%, var(--paper)) 35% 65%, var(--crit) 65% 100%);
}

.spark-sig__prik--unknown {
    height: 8px;
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--line-2);
}

.spark-sig__prik--notmeasured { height: 4px; background: var(--line); }

/* ==========================================================================
   Hurtig tidsregistrering (Alt+T)
   ========================================================================== */

.qte__launch {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    z-index: 900;
    display: inline-flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.7rem 1.15rem;
    border: 0;
    border-radius: 999px;
    background: var(--navy-800);
    color: #fff;
    font-weight: 700;
    font-size: 0.87rem;
    box-shadow: var(--shadow-md);
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.qte__launch:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); background: var(--navy-950); }

.qte__launch kbd {
    background: rgba(255, 255, 255, 0.16);
    border: 0;
    border-radius: 5px;
    padding: 0.1rem 0.35rem;
    font-size: 0.72rem;
    font-family: inherit;
    font-weight: 700;
    color: #fff;
}

.qte__backdrop {
    position: fixed;
    inset: 0;
    z-index: 950;
    background: rgba(19, 28, 40, 0.42);
    backdrop-filter: blur(2px);
}

/* ==========================================================================
   Dokumentbibliotek
   ========================================================================== */

.doc-search { margin-bottom: 1rem; }

.fgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 0.5rem;
    margin-bottom: 1.15rem;
}

.fcard {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.7rem 0.85rem;
    border-radius: var(--r-md);
    background: var(--clay-100);
    box-shadow: inset 0 0 0 1px var(--line);
    cursor: pointer;
    transition: box-shadow 0.13s ease, transform 0.13s ease;
}

.fcard:hover {
    box-shadow: inset 0 0 0 1px var(--line-2), var(--shadow-sm);
    transform: translateY(-1px);
}

.fcard__icon {
    color: var(--warn);
    display: grid;
    place-items: center;
    flex-shrink: 0;
}

.fcard__main { min-width: 0; flex: 1; }

.fcard__name {
    font-weight: 700;
    font-size: 0.87rem;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Filtype-badge i dokumentlisten — erstatter prioritetsstriben fra ticket-kortene. */
.doc__ext {
    width: 40px;
    flex-shrink: 0;
    align-self: center;
    text-align: center;
    font-size: 0.6rem;
    font-weight: 800;
    letter-spacing: 0.03em;
    padding: 0.3rem 0;
    border-radius: 6px;
    background: var(--blue-100);
    color: var(--navy-800);
}

.doc__ext--pdf { background: #f6e2e0; color: #96382f; }
.doc__ext--doc { background: #dfe7f5; color: #2f4d80; }
.doc__ext--sheet { background: #dff0e4; color: #2c6b42; }
.doc__ext--img { background: #f1e6f5; color: #6b3d80; }
.doc__ext--zip { background: var(--clay-200); color: #6d4d16; }

/* ==========================================================================
   Tidsforbrug-historik (måned for måned)
   ========================================================================== */

.mhist { display: flex; flex-direction: column; gap: 0.35rem; }

.mhist__month {
    border-radius: var(--r-md);
    background: var(--paper);
    box-shadow: inset 0 0 0 1px var(--line);
}

.mhist__month[open] { box-shadow: inset 0 0 0 1px var(--line-2); }

.mhist__summary {
    display: grid;
    grid-template-columns: 9rem 1fr 4rem 9rem;
    align-items: center;
    gap: 0.9rem;
    padding: 0.7rem 1rem;
    cursor: pointer;
    list-style: none;
}

.mhist__summary::-webkit-details-marker { display: none; }
.mhist__summary:hover { background: var(--blue-50); border-radius: var(--r-md); }

/* Pil, der viser at rækken kan foldes ud.
   Browserens egen trekant er slået fra ovenfor, og uden en erstatning var der ingen
   antydning overhovedet — en kunde gætter ikke på, at «August 2026» kan klikkes.

   Kun på details-varianten. Microsoft 365-siden genbruger de samme klasser på en
   <div>, der ikke kan foldes ud, og dér ville en pil love noget, der ikke sker. */
details.mhist__month > .mhist__summary {
    grid-template-columns: 9rem 1fr 4rem 9rem 1.25rem;
}

details.mhist__month > .mhist__summary::after {
    content: "";
    width: 0.45rem;
    height: 0.45rem;
    border-right: 2px solid var(--ink-3, var(--ink-2));
    border-bottom: 2px solid var(--ink-3, var(--ink-2));
    border-radius: 1px;
    transform: rotate(45deg) translateY(-0.1rem);
    transform-origin: center;
    transition: transform 0.15s ease;
    justify-self: end;
}

details.mhist__month[open] > .mhist__summary::after {
    transform: rotate(-135deg) translateY(-0.1rem);
}

@media (max-width: 900px) {
    /* Mobilgitteret er to kolonner. Pilen får sin egen plads i stedet for at
       presse tallene sammen. */
    details.mhist__month > .mhist__summary { grid-template-columns: 1fr auto 1.25rem; }
}

@media (prefers-reduced-motion: reduce) {
    details.mhist__month > .mhist__summary::after { transition: none; }
}

.mhist__label {
    font-weight: 700;
    font-size: 0.86rem;
    color: var(--ink);
    text-transform: capitalize;
}

.mhist__bar {
    position: relative;
    display: block;
    height: 12px;
    border-radius: 999px;
    background: var(--blue-50);
    overflow: hidden;
}

/* Puljen tegnes som en svag baggrundsmarkering, så man kan se hvor grænsen går. */
.mhist__allowance {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--clay-200);
    opacity: 0.55;
}

.mhist__fill {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    background: var(--good);
    border-radius: 999px;
}

.mhist__fill--over { background: var(--warn); }
.mhist__fill--billable { background: var(--blue-400); }

.mhist__hours {
    font-weight: 800;
    font-size: 0.86rem;
    color: var(--ink);
    text-align: right;
}

.mhist__status { text-align: right; }

.mhist__detail {
    padding: 0 1rem 0.9rem;
    border-top: 1px solid var(--line);
    margin-top: 0.15rem;
    padding-top: 0.8rem;
}

.mhist__legend {
    display: flex;
    gap: 1.1rem;
    flex-wrap: wrap;
    margin-top: 1rem;
    font-size: 0.76rem;
    color: var(--muted);
}

.mhist__legend span { display: inline-flex; align-items: center; gap: 0.4rem; }

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

.mhist__key--allowance { background: var(--clay-200); }
.mhist__key--used { background: var(--good); }
.mhist__key--over { background: var(--warn); }
.mhist__key--billable { background: var(--blue-400); }

@media (max-width: 900px) {
    .mhist__summary { grid-template-columns: 1fr auto; row-gap: 0.5rem; }
    .mhist__bar { grid-column: 1 / -1; }
}

/* ==========================================================================
   Tickets
   ========================================================================== */

.tkt-filters { margin-bottom: 1.15rem; }

.tkt-chips { display: flex; gap: 0.4rem; flex-wrap: wrap; }

.tkt-chip {
    border: 0;
    background: var(--blue-50);
    color: var(--ink-2);
    font-size: 0.8rem;
    font-weight: 700;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    cursor: pointer;
}

.tkt-chip:hover { background: var(--blue-100); }
.tkt-chip--active { background: var(--navy-800); color: #fff; }
.tkt-chip--active:hover { background: var(--navy-950); color: #fff; }

.tkt-filters__row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
}

.tkt-filters__row .form-select { width: auto; }
.tkt-filters__search { flex: 1; min-width: 12rem; }

.tkt-list { display: flex; flex-direction: column; gap: 0.5rem; }

/* Massevalg-bjælken over triage-listen. Klæber til toppen, så «Tag N» bliver ved med at være
   inden for rækkevidde, mens man ruller gennem en lang liste og vælger flere sager. */
.tktbulk {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.55rem 0.85rem;
    margin-bottom: 0.8rem;
    background: var(--paper);
    border-radius: var(--r-md);
    box-shadow: inset 0 0 0 1px var(--line-2);
    position: sticky;
    /* Below the topbar, which is itself sticky at top:0 with z-index 800. At top:0.5rem this bar
       slid in UNDER it — so «Tag N» disappeared at the moment it was being used. The value tracks
       .topbar's height (0.85rem padding twice plus its content). */
    top: 4.8rem;
    z-index: 3;
}

/* Afkrydsningen sidder først på sagskortet uden at skubbe prioritetsstriben ud af flugt. */
.tkt__check { flex-shrink: 0; margin: 0; cursor: pointer; }

/* Synligt trækhåndtag på kort, der kan omarrangeres (fx årshjulet, plan-skabeloner) — så
   «kan trækkes» ikke kun afsløres af grab-cursoren ved et tilfældigt hover. Dæmpet, men
   tydeligere når man er ved kortet. Hele kortet er stadig trækfladen; grebet er blot cue'en. */
.tkt__grip {
    flex-shrink: 0;
    color: var(--faint);
    font-size: 1.05rem;
    line-height: 1;
    cursor: grab;
    user-select: none;
    opacity: 0.5;
    transition: opacity 0.12s, color 0.12s;
}
.tkt:hover .tkt__grip { opacity: 1; color: var(--muted); }

.tkt {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.85rem 1rem;
    border-radius: var(--r-md);
    background: var(--paper);
    box-shadow: inset 0 0 0 1px var(--line);
    cursor: pointer;
    /* Mange .tkt-rækker er <a>. Uden dette hånd-tilføjede hvert kaldested style="text-decoration:none"
       (og arvede link-blå på titlen). Sat på basen én gang, så rækkerne ser ens ud som links og ikke. */
    text-decoration: none;
    color: inherit;
    transition: box-shadow 0.13s ease, transform 0.13s ease;
}

/* Tint, not lift. The queue reloads itself every couple of minutes and the mouse travels down eighty
   rows; a 1px hop under the cursor on each one is motion the eye has to discount. The house says so
   itself further down, in the rule about hover on dense rows. */
.tkt:hover {
    box-shadow: inset 0 0 0 1px var(--line-2);
    background: var(--blue-50, color-mix(in srgb, var(--ink) 3%, var(--paper)));
}

/* Rene informationskort er ikke klikbare. Uden denne modifier løftede de sig på hover
   som et ægte klikbart .tkt (kun cursoren var rettet inline), så hover holdt op med at
   betyde «her kan klikkes». Flad hover: behold rammen, drop løftet og den ekstra skygge. */
.tkt--static { cursor: default; }
.tkt--static:hover {
    box-shadow: inset 0 0 0 1px var(--line);
    transform: none;
}

.tkt--done { opacity: 0.62; }

.tkt__prio {
    width: 4px;
    align-self: stretch;
    border-radius: 999px;
    background: var(--blue-300);
    flex-shrink: 0;
}

.tkt__prio--lav { background: var(--blue-200); }
.tkt__prio--normal { background: var(--blue-400); }
.tkt__prio--hoej { background: var(--warn); }
.tkt__prio--kritisk { background: var(--crit); }

.tkt__main { flex: 1; min-width: 0; }

.tkt__title {
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Same three as .tkt__title. Without them a long customer name wraps the meta line and that one row
   grows ~18px, so the list looks untidy without anything you can point at. */
.tkt__meta {
    font-size: 0.76rem;
    color: var(--muted);
    margin-top: 0.15rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tkt__side {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}

/* «Kvittér» på en sikkerhedsadvarsel: en diskret pille, der ikke skal tage opmærksomhed
   fra selve advarslen — men bliver tydelig, når man er ved den. */
.tkt__kvit {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    border: 1px solid var(--line-2, var(--line));
    background: transparent;
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color .12s, background .12s, border-color .12s;
}

.tkt__kvit:hover,
.tkt__kvit:focus-visible {
    color: #fff;
    background: var(--blue-500);
    border-color: var(--blue-500);
    outline: none;
}

/* Modul-adgang som klikbare fliser i stedet for en tabel med knapper. */
.mods-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
    gap: 0.5rem;
}

.mtile {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.65rem 0.75rem;
    border: 0;
    border-radius: var(--r-md);
    background: var(--blue-50);
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--muted);
    cursor: pointer;
    text-align: left;
    transition: background-color 0.13s ease, color 0.13s ease, box-shadow 0.13s ease;
}

.mtile:hover { box-shadow: inset 0 0 0 1px var(--line-2); }

.mtile--on {
    background: var(--good-bg);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--good) 28%, transparent);
    color: var(--ink);
}

.mtile__icon { display: grid; place-items: center; flex-shrink: 0; opacity: 0.7; }
.mtile--on .mtile__icon { color: var(--good); opacity: 1; }

.mtile__name {
    flex: 1;
    min-width: 0;
    font-size: 0.8rem;
    font-weight: 700;
    line-height: 1.2;
}

.mtile__state {
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    flex-shrink: 0;
}

.mtile--on .mtile__state { color: var(--good); }

/* Tynd forbrugsbjælke under en aftale i listen. */
.agr-bar {
    position: relative;
    height: 5px;
    border-radius: 999px;
    background: var(--blue-50);
    overflow: hidden;
    margin-top: 0.45rem;
    max-width: 22rem;
}

.agr-bar__fill {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--good);
    border-radius: 999px;
}

.agr-bar__fill--over { background: var(--warn); }

/* Rund avatar i venstre side af et listekort (kunder, medarbejdere). */
.tkt__avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--blue-400), var(--navy-700));
    color: #fff;
    font-size: 0.74rem;
    font-weight: 800;
    display: grid;
    place-items: center;
    flex-shrink: 0;
}

.tkt__assignee {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--blue-400), var(--navy-700));
    color: #fff;
    font-size: 0.66rem;
    font-weight: 800;
    display: grid;
    place-items: center;
}

.tkt-actions {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.tkt-actions__spacer { flex: 1; }

/* Samtaletråd */

.thread { display: flex; flex-direction: column; gap: 1rem; }

.thread__item { display: flex; gap: 0.75rem; }

/* Samtalen læses som en samtale: modparten til venstre, én selv til højre — samme
   konvention som enhver beskedapp. Siden afhænger af, hvem der kigger: kunden ser
   sig selv til højre, vi ser os selv til højre. Det er ikke to designs, men det
   samme design set fra hver sin ende, og det er dét, der gør «hvem sagde hvad»
   læsbart uden at læse navnet over hver boble.

   Boblen får et loft på bredden. Uden det ville en lang besked fylde hele linjen,
   og så er der ingen venstre og højre at se forskel på. */
.thread__body { max-width: 78%; flex: 0 1 auto; }

/* Hjørnet nærmest afsenderen er skarpt — den ene kode, enhver beskedapp bruger, og
   den eneste, der stadig virker, når boblen fylder næsten hele bredden. På en telefon
   er forskydningen på 44 px ikke nok til at se forskel, og farven alene er svag, hvis
   begge parter tilfældigvis hedder det samme. Hjørnet peger. */
.thread__item .thread__body { border-bottom-left-radius: 5px; }
.thread__item--mig .thread__body {
    border-bottom-left-radius: var(--r-md);
    border-bottom-right-radius: 5px;
}

/* Den lyse boble ligger på en næsten lige så lys flade. Uden kanten flyder den ud i
   panelet og ligner brødtekst frem for en replik. */
.thread__item .thread__body { box-shadow: inset 0 0 0 1px var(--line); }
.thread__item--mig .thread__body { box-shadow: none; }

.thread__item--mig { flex-direction: row-reverse; }
.thread__item--mig .thread__head { flex-direction: row-reverse; }

.thread__item--mig .thread__body {
    background: var(--navy-800);
    color: #fff;
}

/* Tid og navn i en mørk boble. --muted ville lande på ~2,5:1 mod navy-800; hvid med
   nedsat gennemsigtighed holder sig over kravet og læses stadig som sekundært. */
.thread__item--mig .thread__head .stat__meta,
.thread__item--mig .thread__head strong { color: rgba(255, 255, 255, 0.86); }

/* «Redigér» (og anden btn-link) i den mørke boble: link-farven er valgt til lys baggrund og
   forsvinder næsten på navy-800. Lys, understreget tekst her — mørk/blå alle andre steder. */
.thread__item--mig .thread__body .btn-link {
    color: rgba(255, 255, 255, 0.9);
    text-decoration: underline;
}
.thread__item--mig .thread__body .btn-link:hover { color: #fff; }

.thread__item--mig .thread__avatar {
    background: linear-gradient(140deg, var(--navy-700), var(--navy-950));
}

/* Interne noter er ikke en replik i samtalen — de er noget, vi skriver til os selv
   midt i den. Derfor hverken venstre eller højre, men fuld bredde, så de tydeligt
   ligger uden for det, kunden nogensinde ser. */
.thread__item--internal .thread__body {
    background: var(--warn-bg);
    box-shadow: inset 0 0 0 1px rgba(176, 125, 51, 0.22);
    max-width: 100%;
    flex: 1;
    color: var(--ink);
}

/* Den interne note peger ingen steder hen — den er ikke en replik i samtalen, så
   den beholder runde hjørner hele vejen rundt. */
.thread__item--internal .thread__body {
    border-radius: var(--r-md);
}

.thread__item--internal { flex-direction: row; }
.thread__item--internal .thread__head { flex-direction: row; }
.thread__item--internal .thread__head strong { color: var(--ink); }
.thread__item--internal .thread__head .stat__meta { color: var(--ink-2); }

.thread__item--internal .thread__avatar {
    background: linear-gradient(140deg, var(--blue-400), var(--navy-700));
}


.thread__avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: linear-gradient(140deg, var(--blue-400), var(--navy-700));
    color: #fff;
    font-size: 0.7rem;
    font-weight: 800;
    display: grid;
    place-items: center;
    flex-shrink: 0;
}

.thread__body {
    flex: 1;
    min-width: 0;
    background: var(--blue-50);
    border-radius: var(--r-md);
    padding: 0.7rem 0.9rem;
}

.thread__head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.82rem;
}

/* Telefonen. Blokken står her og ikke længere oppe: den skal komme EFTER
   .thread__avatar og .thread__body, ellers vinder grundreglerne på lige specificitet,
   og reglerne herunder ser ud til at virke uden at gøre noget. Første forsøg stod
   ovenfor, og avataren blev pænt stående — målt, ikke antaget. */
@media (max-width: 640px) {
    /* Avataren er 32 px plus 12 px afstand — plads, der er dyr på en smal skærm, og
       den fortæller ikke mere, end boblen gør. Navnet står i hovedet ovenfor. */
    .thread__avatar { display: none; }
    .thread__item { gap: 0; }

    /* Uden avataren skal boblen selv skabe forskydningen. 14 % tomrum i den ene ende
       er nok til at siden kan ses på et øjeblik, uden at teksten bliver en smal søjle. */
    .thread__item--mig { padding-left: 14%; }
    .thread__item:not(.thread__item--mig):not(.thread__item--internal) { padding-right: 14%; }

    .thread__body { max-width: 100%; }

    /* Den interne note er ikke en replik og skal have hele bredden. */
    .thread__item--internal { padding: 0; }
}

/* Svar-boks */

.reply {
    margin-top: 1.25rem;
    padding-top: 1.15rem;
    border-top: 1px solid var(--line);
}

.reply__tabs { display: flex; gap: 0.35rem; margin-bottom: 0.6rem; }

.reply__tab {
    border: 0;
    background: none;
    color: var(--muted);
    font-size: 0.82rem;
    font-weight: 700;
    padding: 0.35rem 0.7rem;
    border-radius: 8px;
    cursor: pointer;
}

.reply__tab:hover { background: var(--blue-50); color: var(--ink); }
.reply__tab--active { background: var(--navy-800); color: #fff; }
.reply__tab--active:hover { background: var(--navy-950); color: #fff; }

.reply__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 0.6rem;
}

/* Fristen på en løst sag. --ink-2 og ikke --muted: teksten står på en tonet flade,
   og --muted rammer 3,9:1 dér — under de 4,5:1, WCAG kræver. Målt, ikke skønnet. */
.reply__loest {
    margin: 0 0 0.7rem;
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    background: var(--blue-50);
    color: var(--ink-2);
    font-size: 0.85rem;
    line-height: 1.45;
}

/* Henvisningen tilbage til den lukkede sag. Står mellem sidehoved og handlinger,
   hvor den læses før man begynder at svare — ikke nede i en detaljeliste. */
.tkt-opfoelger {
    margin: 0 0 0.9rem;
    padding: 0.55rem 0.8rem;
    border-left: 3px solid var(--navy-800);
    background: var(--blue-50);
    color: var(--ink-2);
    font-size: 0.85rem;
    border-radius: 0 10px 10px 0;
}

.tkt-opfoelger a { color: var(--navy-950); font-weight: 700; }

/* «Hænger sammen med» — de linjer, opgavelistens oprulning lagde ind under en anden, fordi de
   handler om den samme enhed eller forklares af den. Indrykket og dæmpet: rækken ovenover er
   stadig den, der skal læses, men de underordnede beholder hver sit link ind i sit eget modul.
   Kun tokens der selv vender i mørkt tema — ellers ville blokken kræve sin egen dark-regel. */
.tkt-group { display: flex; flex-direction: column; }

.tkt-linked {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    margin: 0.3rem 0 0 2.1rem;
    padding: 0.1rem 0 0.1rem 0.75rem;
    border-left: 2px solid var(--line-2);
}

.tkt-linked__label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.15rem;
}

.tkt-linked__row {
    display: flex;
    align-items: baseline;
    gap: 0.45rem;
    min-width: 0;
    padding: 0.2rem 0.35rem;
    border-radius: var(--r-sm);
    font-size: 0.8rem;
    color: var(--ink-2);
    text-decoration: none;
}

.tkt-linked__row:hover { background: var(--blue-50); color: var(--ink); }

.tkt-linked__source,
.tkt-linked__detail { flex-shrink: 0; color: var(--muted); font-size: 0.72rem; }

.tkt-linked__source { font-weight: 700; }

.tkt-linked__title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.notif { position: relative; }

.notif__btn {
    position: relative;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 0;
    background: rgba(255, 255, 255, 0.7);
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--muted);
    display: grid;
    place-items: center;
    flex-shrink: 0;
    cursor: pointer;
}

.notif__btn:hover { background: #fff; color: var(--ink); }

.notif__badge {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 3px;
    border-radius: 999px;
    background: var(--crit);
    color: #fff;
    font-size: 0.62rem;
    font-weight: 800;
    display: grid;
    place-items: center;
    line-height: 1;
}

.notif__backdrop {
    position: fixed;
    inset: 0;
    z-index: 950;
}

.notif__panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 951;
    width: 340px;
    max-height: 24rem;
    overflow-y: auto;

    /* Panelet må aldrig kunne rulles sidelæns. Det er ikke pynt: en vandret
       scrollbar nederst spiser en linje af den nederste notifikation og får
       samtidig den lodrette til at se forkert ud. Overskriften var årsagen —
       fem knapper i en space-between uden ombrydning presser indholdet bredere
       end panelet — men hidden her sikrer, at den næste knap, nogen tilføjer,
       ikke gør det samme igen. */
    overflow-x: hidden;
    background: var(--paper);
    color: var(--ink);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-lg);
    padding: 0.75rem;
}

.notif__head {
    display: flex;
    align-items: center;
    justify-content: space-between;

    /* Ombrydning frem for at klemme. Antallet af knapper her afhænger af
       tilstanden — «Markér alle som læst» og «Ryd læste» kommer og går — så
       rækken kan ikke få en bredde, der passer i alle tilfælde. Uden dette
       skubbede den panelet bredere end sig selv. */
    flex-wrap: wrap;
    gap: 0.35rem 0.6rem;

    margin-bottom: 0.5rem;
    font-size: 0.85rem;
}

/* Knapperne må gerne bryde indbyrdes og lægge sig under titlen, når der er
   mange af dem. De holder sammen som gruppe, så «Indstillinger» ikke ender
   alene på en linje for sig. */
.notif__handlinger {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem 0.6rem;
    min-width: 0;
}

/* Bootstrap giver link-knapper en linjehøjde beregnet til en knaprække. Her står
   de som tekst blandt tekst, og uden dette bliver de ombrudte linjer for luftige. */
.notif__handlinger .btn-link {
    line-height: 1.3;
    white-space: nowrap;
}

.notif__item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.55rem 0.4rem;
    border-radius: 8px;
    cursor: pointer;
    font-size: 0.85rem;
}

.notif__tekst { flex: 1; min-width: 0; }

/* Fjern-krydset. Dæmpet indtil man er ved rækken — det skal kunne findes, men ikke
   konkurrere med selve beskeden om opmærksomheden. */
.notif__ryd {
    flex-shrink: 0;
    border: 0;
    background: none;
    color: var(--faint);
    font-size: 1.15rem;
    line-height: 1;
    padding: 0.15rem 0.3rem;
    border-radius: 6px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.12s, color 0.12s, background 0.12s;
}

.notif__item:hover .notif__ryd,
.notif__ryd:focus-visible { opacity: 1; }

.notif__ryd:hover { color: var(--crit-ink); background: var(--crit-bg); }

/* Touch har ingen hover. Var krydset kun synligt ved musen over, kunne man ikke
   fjerne noget på en telefon overhovedet. */
@media (hover: none) {
    .notif__ryd { opacity: 1; padding: 0.4rem 0.55rem; }
}

.notif__item:hover { background: rgba(60, 110, 180, 0.08); }

.notif__item--unread { font-weight: 700; background: rgba(60, 110, 180, 0.06); }

/* Mobil: bundark i stedet for et hængende panel.
   Panelet var forankret til klokkens højrekant med en fast bredde på 340 px, og klokken
   sidder inde midt i topbaren. Målt ved 375 px lå 109 px uden for skærmen til venstre —
   en tredjedel af hver overskrift var klippet af, så man kunne læse «68.1.50 er oppe
   igen» uden at vide hvilken enhed det var.

   En bundark kan ikke løbe ud over kanten, uanset hvor klokken sidder, og den kræver
   ikke at vi kender topbarens højde — den ændrer sig med safe-area og brugerens
   tekststørrelse. Den ligger samtidig, hvor tommelfingeren er. */
@media (max-width: 700px) {
    .notif__panel {
        position: fixed;
        top: auto;
        right: 0;
        bottom: 0;
        left: 0;
        width: auto;
        max-height: 70vh;
        border-radius: var(--r-lg) var(--r-lg) 0 0;
        padding: 0.9rem 1rem calc(1rem + env(safe-area-inset-bottom, 0px));
        box-shadow: 0 -12px 32px rgba(19, 28, 40, 0.22);
    }

    .notif__head { font-size: 0.95rem; padding-bottom: 0.35rem; }

    /* Trykmål frem for musemål. */
    .notif__item { padding: 0.8rem 0.5rem; font-size: 0.9rem; }
}

.qte {
    position: fixed;
    z-index: 951;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(520px, calc(100vw - 2rem));
    max-height: calc(100vh - 3rem);
    overflow-y: auto;
    background: var(--paper);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-lg);
    border: 1px solid var(--line);
}

.qte__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1.35rem 1.5rem 0.9rem;
    border-bottom: 1px solid var(--line);
}

.qte__close {
    border: 0;
    background: none;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--faint);
    cursor: pointer;
    padding: 0 0.25rem;
}

.qte__close:hover { color: var(--ink); }

.qte__body { padding: 1.25rem 1.5rem; display: flex; flex-direction: column; gap: 1rem; }

.qte__row { display: flex; flex-direction: column; gap: 0.35rem; }

.qte__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.9rem; }

/* På en telefon er to kolonner for smalt til datovælger + Område/Type-selects — de blev
   klemt til ~157 px hver. Fald til én kolonne, som alle de andre grids i filen gør. */
@media (max-width: 640px) {
    .qte__grid { grid-template-columns: 1fr; }
}

.qte__grid > div { display: flex; flex-direction: column; gap: 0.35rem; }

/* .preset-row/.preset er den generelle udgave. .qte__* er den oprindelige fra hurtig
   tidsregistrering og deler reglerne, så de to sæt ikke kan komme til at se forskellige ud. */
.qte__presets, .preset-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    margin-top: -0.4rem;
}

.qte__preset, .preset {
    padding: 0.35rem 0.75rem;
    border-radius: 999px;
    border: 1px solid var(--line-2);
    background: var(--paper);
    color: var(--ink-2);
    font-size: 0.8rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.qte__preset:hover, .preset:hover { border-color: var(--blue-400); color: var(--ink); }

.qte__preset--active, .qte__preset--active:hover,
.preset--on, .preset--on:hover {
    background: var(--navy-800);
    border-color: var(--navy-800);
    color: #fff;
}

/* Målerække der kan klikkes for at se forløbet. Skal se ud som de øvrige rækker —
   knappen er en affordance, ikke et nyt formsprog. */
/* A metric row is a <button> (click for the trend). Reset the browser's default button
   chrome — the grey fill + border made the rows look like foreign boxes glued onto the
   card — down to a clean, subtle row that matches the plain rows above it, with only a
   soft hover to say it is clickable. */
.dcheck--btn {
    font: inherit;
    text-align: left;
    cursor: pointer;
    background: transparent;
    border: 0;
    border-radius: 7px;
    padding: 0.3rem 0.4rem;
    width: 100%;
    color: inherit;
    transition: background 0.12s ease;
}

.dcheck--btn:disabled { cursor: default; }

.dcheck--btn:not(:disabled):hover { background: rgba(127, 127, 127, 0.10); }

.dcheck--btn:focus-visible {
    outline: 2px solid var(--blue-400);
    outline-offset: 1px;
}

/* Push the value (and its bar) to the right edge, so the rows read "name … value" like
   the plain rows, instead of the value crowding up against the name. */
.dcheck--btn .dcheck__status--metric { margin-left: auto; padding-left: 0.5rem; }

/* Forløbsgraf for én måling. */
.chart { padding: 0.5rem 0 0; }

.chart svg {
    width: 100%;
    height: 180px;
    display: block;
    overflow: visible;
}

.chart__line {
    fill: none;
    stroke: var(--navy-800);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
    /* Uden dette skaleres stregtykkelsen med viewBox og bliver tynd på brede skærme. */
    vector-effect: non-scaling-stroke;
}

.chart__dot { fill: var(--navy-800); }

.chart__limit {
    stroke-width: 1;
    stroke-dasharray: 5 4;
    vector-effect: non-scaling-stroke;
}

.chart__limit--warn { stroke: var(--warn); }
.chart__limit--crit { stroke: var(--crit); }

.chart__axis {
    display: flex;
    justify-content: space-between;
    margin-top: 0.4rem;
    font-size: 0.75rem;
    color: var(--ink-3, var(--ink-2));
}

.chart__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin-top: 0.9rem;
    padding-top: 0.8rem;
    border-top: 1px solid var(--line);
    font-size: 0.8rem;
    color: var(--ink-2);
}

.chart__key::before {
    content: "";
    display: inline-block;
    width: 14px;
    height: 0;
    margin-right: 0.4rem;
    vertical-align: middle;
    border-top: 2px dashed currentColor;
}

.chart__key--warn { color: var(--warn); }
.chart__key--crit { color: var(--crit); }

/* Skal sætte width — ikke kun max-width — for base-.dlg låser width til min(560px,…),
   så en ren max-width aldrig kunne udvide dialogen (Noc-metrikdialogen stod 160px for smal). */
.dlg--wide { width: min(720px, calc(100vw - 2rem)); }

/* Hændelsesforløb: ét kort pr. hændelse med spor nedenunder. */
.inc {
    padding: 1rem 1.25rem;
    border-top: 1px solid var(--line);
    border-left: 3px solid var(--line-2);
}

/* Kunden på en hændelse. Dæmpet — enhedens navn er stadig overskriften; kunden er
   den oplysning, man skal bruge for at vide, hvem man ringer til. */
.inc__kunde {
    margin-left: 0.5rem;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--muted);
}

.inc--crit { border-left-color: var(--crit); }
.inc--warn { border-left-color: var(--warn); }

.inc__head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
}

.inc__name { font-weight: 700; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.inc__sub { font-size: 0.82rem; color: var(--ink-2); margin-top: 0.15rem; }
.inc__actions { display: flex; gap: 0.4rem; flex-shrink: 0; }

.inc__tag {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--line-2);
    color: var(--ink-2);
}

.inc__tag--ok { background: var(--good); color: #fff; }

/* Sporet. Tallene til venstre gør det læsbart som et forløb frem for en punktliste. */
.inc__trail {
    list-style: none;
    margin: 0.85rem 0 0;
    padding: 0.75rem 0 0;
    border-top: 1px dashed var(--line);
    font-size: 0.82rem;
    color: var(--ink-2);
}

.inc__trail li { display: flex; gap: 0.6rem; padding: 0.15rem 0; }

.inc__time {
    font-variant-numeric: tabular-nums;
    color: var(--ink-3, var(--ink-2));
    flex-shrink: 0;
    min-width: 3.2rem;
}

.inc__by { opacity: 0.75; font-style: italic; }

/* Lille bjælke ved en procentmåling — toner, batteri. Kun visuel: tallet står ved siden
   af, så bjælken behøver ikke kunne aflæses præcist. */
.metric-bar {
    display: inline-block;
    width: 44px;
    height: 5px;
    border-radius: 999px;
    background: var(--line-2);
    overflow: hidden;
    vertical-align: middle;
    margin-left: 0.15rem;
}

.metric-bar__fill {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: currentColor;
    opacity: 0.75;
}

/* Afsnitsoverskrift inde i en dialog. Uden den bliver en lang formular til én
   uafbrudt væg af felter, hvor man ikke kan se hvad der hører sammen. */
.dlg__sect {
    margin: 1.5rem 0 0.85rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--line);
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-2);
}

.qte__check {
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    padding: 0.8rem 0.9rem;
    border: 1px solid var(--line-2);
    border-radius: var(--r-sm);
    cursor: pointer;
    font-size: 0.88rem;
}

.qte__check span { display: flex; flex-direction: column; }

.qte__foot {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    padding: 1rem 1.5rem 1.35rem;
    border-top: 1px solid var(--line);
}

kbd {
    background: var(--blue-50);
    border: 1px solid var(--line-2);
    border-radius: 5px;
    padding: 0.1rem 0.4rem;
    font-size: 0.78rem;
    font-family: inherit;
    font-weight: 700;
    color: var(--ink-2);
}

/* ==========================================================================
   Generisk modal/dialog (opret/rediger-formularer på tværs af siderne)
   ========================================================================== */

.dlg__backdrop {
    position: fixed;
    inset: 0;
    z-index: 950;
    background: rgba(19, 28, 40, 0.42);
    backdrop-filter: blur(2px);
}

.dlg {
    position: fixed;
    z-index: 951;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(560px, calc(100vw - 2rem));
    max-height: calc(100vh - 3rem);
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--paper);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-lg);
    border: 1px solid var(--line);
    /* .dlg er "position: fixed", men er stadig et DOM-barn af hvor <Modal> bliver brugt — fx en
       tabelcelle med "white-space: nowrap" til handlingsknapper. Uden dette arver dialogen den
       nowrap uanset at den visuelt er løsrevet fra tabellen, og teksten scroller i stedet for at ombryde. */
    white-space: normal;
}

.dlg--lg { width: min(860px, calc(100vw - 2rem)); }

.dlg__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: 1.35rem 1.5rem 0.9rem;
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    background: var(--paper);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
}

.dlg__close {
    border: 0;
    background: none;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--faint);
    cursor: pointer;
    padding: 0 0.25rem;
}

.dlg__close:hover { color: var(--ink); }

.dlg__body { padding: 1.25rem 1.5rem; overflow-wrap: break-word; }

/* Fodrækken i en modal — knapperne.
   Den ligger inde i .dlg__body, fordi submit-knapper skal være inde i <EditForm>.
   Derfor sticky mod bunden af selve dialogen, som er det element, der scroller:
   uden det lå Gem og Annullér 192 px under folden på en telefon i «Opret aftale»,
   og man skulle scrolle for at finde ud af, at man overhovedet kunne gemme.

   De negative margener trækker rækken ud over kroppens vandrette luft, så stregen
   går fra kant til kant og baggrunden dækker det, der scroller under den. */
.dlg__foot {
    position: sticky;
    bottom: 0;
    z-index: 1;
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
    margin: 1.25rem -1.5rem -1.25rem;
    padding: 1rem 1.5rem 1.25rem;
    border-top: 1px solid var(--line);
    background: var(--paper);
}

/* ==========================================================================
   Kommandopaletten (⌘K / Ctrl+K) — en launcher over hele appen.
   Token-drevet hele vejen, så den følger et kommende mørkt tema af sig selv.
   ========================================================================== */

/* Altid-synligt indgangspunkt: en flydende pille, der ligger lige over
   hjørneknappen (tid/opret sag), så genvejen kan opdages uden at kende den. */
.cmdhint {
    position: fixed;
    right: 1.5rem;
    bottom: calc(1.5rem + 3.6rem);
    z-index: 899;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.85rem;
    border: 1px solid var(--line-2);
    border-radius: 999px;
    background: var(--paper);
    color: var(--ink-2);
    font-size: 0.85rem;
    font-weight: 600;
    box-shadow: var(--shadow-md);
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, transform 0.15s, box-shadow 0.15s;
}

.cmdhint:hover {
    color: var(--ink);
    border-color: var(--blue-400);
    transform: translateY(-1px);
    box-shadow: var(--shadow-lg);
}

.cmdhint__kbd {
    font-family: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--faint);
    background: var(--shell);
    border: 1px solid var(--line);
    border-radius: 6px;
    padding: 0.05rem 0.4rem;
}

.cmd__backdrop {
    position: fixed;
    inset: 0;
    z-index: 970;
    background: rgba(19, 28, 40, 0.46);
    backdrop-filter: blur(2px);
}

.cmd {
    position: fixed;
    z-index: 971;
    top: 10vh;
    left: 50%;
    transform: translateX(-50%);
    width: min(640px, calc(100vw - 2rem));
    max-height: min(72vh, calc(100vh - 4rem));
    display: flex;
    flex-direction: column;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.cmd__search {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.9rem 1.1rem;
    border-bottom: 1px solid var(--line);
    color: var(--muted);
    flex: 0 0 auto;
}

.cmd__input {
    flex: 1 1 auto;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--ink);
    font-size: 1.05rem;
    font-weight: 500;
    padding: 0.15rem 0;
}

.cmd__input::placeholder { color: var(--faint); font-weight: 400; }

.cmd__x {
    border: 0;
    background: none;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--faint);
    cursor: pointer;
    padding: 0 0.2rem;
}

.cmd__x:hover { color: var(--ink); }

.cmd__results {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 0.5rem 0.55rem 0.7rem;
}

.cmd__group { padding: 0.35rem 0 0.15rem; }

.cmd__grouphead {
    padding: 0.35rem 0.6rem 0.3rem;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--faint);
}

.cmd__row {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.5rem 0.6rem;
    border-radius: var(--r-md, 10px);
    text-decoration: none;
    color: var(--ink);
    scroll-margin: 0.5rem;
}

/* Markering (pil op/ned) og musehover ser ens ud, så tastatur og mus peger på det
   samme sted. Markeringen sættes fra JS (palette.js), hover fra browseren. */
.cmd__row--active,
.cmd__row:hover {
    background: var(--blue-50);
}

.cmd__row--active .cmd__ico,
.cmd__row:hover .cmd__ico { color: var(--brand); }

.cmd__ico {
    flex: 0 0 auto;
    display: inline-flex;
    color: var(--muted);
}

.cmd__main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.3;
}

.cmd__label {
    font-size: 0.92rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cmd__sub {
    font-size: 0.78rem;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cmd__note {
    padding: 0.9rem 0.7rem;
    font-size: 0.88rem;
    color: var(--ink-2);
}

.cmd__note--muted { color: var(--muted); }

.cmd__foot {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.55rem 1rem;
    border-top: 1px solid var(--line);
    background: var(--shell);
    font-size: 0.75rem;
    color: var(--muted);
}

.cmd__tip { display: inline-flex; align-items: center; gap: 0.3rem; }

.cmd__foot kbd {
    font-family: inherit;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--ink-2);
    background: var(--paper);
    border: 1px solid var(--line-2);
    border-radius: 5px;
    padding: 0.02rem 0.35rem;
    min-width: 1.1rem;
    text-align: center;
}

@media (max-width: 640px) {
    /* På en telefon fylder pillen for meget — vis kun ikonet, som en lille FAB
       lige over hjørneknappen. */
    .cmdhint {
        right: 0.9rem;
        bottom: calc(0.9rem + 3.2rem);
        padding: 0.6rem;
    }
    .cmdhint__txt, .cmdhint__kbd { display: none; }

    .cmd {
        top: 4vh;
        width: calc(100vw - 1.2rem);
        max-height: calc(100vh - 6vh);
    }

    /* Foden med tastatur-hints er ligegyldig uden et tastatur. */
    .cmd__foot { display: none; }
}

/* ==========================================================================
   Chart (Dmarc pass/fail)
   ========================================================================== */

/* Bar-chart-legenden (Dmarc). Egen klasse — den delte .chart__legend ovenfor er linje-grafens,
   og et fælles navn fik de to til at overskrive hinandens gap/farve/kant på kryds. */
.chart__legend--bars {
    display: flex;
    gap: 1.2rem;
    margin-bottom: 1.1rem;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--muted);
}

.chart__legend--bars i {
    width: 10px; height: 10px; border-radius: 3px;
    display: inline-block; margin-right: 0.4rem;
}

.chart__row {
    display: grid;
    grid-template-columns: 6rem 1fr 9.5rem;
    align-items: center;
    gap: 0.9rem;
    padding: 0.35rem 0;
    font-size: 0.85rem;
}

.chart__label { color: var(--ink-2); font-weight: 700; white-space: nowrap; }

.chart__track {
    height: 14px;
    display: flex;
    gap: 2px;
    border-radius: 5px;
    overflow: hidden;
    background: var(--blue-50);
}

.chart__seg { height: 100%; min-width: 3px; }
.chart__seg--good { background: var(--good); }
.chart__seg--crit { background: var(--crit); }

.chart__val {
    color: var(--faint);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    text-align: right;
}

.empty {
    padding: 1.75rem 0;
    text-align: center;
    color: var(--faint);
    font-size: 0.9rem;
}

/* Den todelte tomme tilstand: en linje der siger hvad der mangler, og en der siger
   hvad man kan gøre. Begge klasser stod 17 steder uden at være skrevet, så de to
   linjer fik samme størrelse og samme farve — og så var opdelingen usynlig. */
.empty__title {
    color: var(--ink-2);
    font-size: 1rem;
    font-weight: 700;
    margin-bottom: 0.35rem;
}

.empty__text {
    color: var(--faint);
    font-size: 0.88rem;
    line-height: 1.6;
}

/* ==========================================================================
   Bootstrap-komponenter i vores sprog
   ========================================================================== */

.btn {
    font-weight: 600;
    border-radius: var(--r-btn);
    padding: 0.55rem 1.25rem;
    font-size: 0.88rem;
    transition: background 0.13s ease, border-color 0.13s ease, color 0.13s ease;
}

.btn-primary {
    background: var(--navy-800);
    border-color: var(--navy-800);
    color: #fff;
}

/* Ingen løft ved hover.
   translateY(-1px) + voksende skygge fik knappen til at hoppe, og på en side, der opdaterer sig
   selv, er hver bevægelse noget, øjet skal bortse fra. Farven alene er svar nok. */
.btn-primary:hover, .btn-primary:focus {
    background: var(--navy-950);
    border-color: var(--navy-950);
    color: #fff;
}

.btn-outline-primary, .btn-outline-secondary {
    background: var(--paper);
    border-color: var(--line-2);
    color: var(--navy-800);
}

.btn-outline-primary:hover, .btn-outline-secondary:hover {
    background: var(--blue-50);
    border-color: var(--blue-300);
    color: var(--navy-950);
}

.btn-sm {
    padding: 0.32rem 0.85rem;
    font-size: 0.79rem;
    white-space: nowrap;
}

.btn-link { font-weight: 700; text-decoration: none; }

/* Trykmål på touch.
   btn-sm er 31 px høj, og målingsrækkerne 30 — fint med en musemarkør, for lidt med en
   tommelfinger. Både Apple og Google anbefaler mindst 44 px, og på Driftsovervågning stod
   der 44 elementer under grænsen på ét kort: Tjek nu, Rediger, Slet og hver enkelt måling.

   pointer: coarse rammer rigtige touch-enheder uanset skærmbredde, og max-width tager
   det smalle vindue på en bærbar. Bredden røres ikke — kun højden, så knapperne ikke
   pludselig fylder linjen op. */
@media (max-width: 720px), (pointer: coarse) {
    .btn-sm {
        min-height: 44px;
        padding-top: 0.6rem;
        padding-bottom: 0.6rem;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .btn { min-height: 44px; }

    /* Målingsrækken er også en knap — den åbner forløbet. */
    .dcheck--btn { min-height: 44px; }

    /* Luft mellem knapper, så man ikke rammer naboen. */
    .dcard__actions { gap: 0.55rem; }

    /* Bare tekstlinks i tabelceller — typisk "Åbn" — er 25x16 px. Trykfeltet udvides
       med polstring, og den negative margen trækker layoutet tilbage på plads, så
       rækkerne ikke bliver høje af det. Man rammer altså et større felt end det,
       man kan se, hvilket er præcis meningen. */
    .table td a:not(.btn) {
        display: inline-block;
        padding: 0.75rem 0.6rem;
        margin: -0.75rem -0.6rem;
    }

    /* Filterchips — sagsfiltre og gruppefiltre — står på 32 px. De er blandt de
       hyppigst trykkede elementer på siden og skal derfor være blandt de nemmeste
       at ramme, ikke de sværeste. */
    .tkt-chip,
    .gchip {
        min-height: 44px;
        padding-top: 0.6rem;
        padding-bottom: 0.6rem;
    }
}

/* Felter må gerne vise ringen ved klik — den fortæller hvor man skriver. Knapper må
   ikke, for så bliver den hængende efter hvert museklik; de får den via :focus-visible
   i tastatur-afsnittet nederst. */
.form-control:focus, .form-select:focus, .form-check-input:focus {
    box-shadow: 0 0 0 3px rgba(92, 127, 168, 0.25);
    outline: none;
}

.btn:focus, .btn:active:focus { outline: none; box-shadow: none; }

.form-control, .form-select {
    /* background-COLOR, not the background shorthand. The shorthand resets background-image, and that
       is where Bootstrap draws the chevron on a <select> — so every dropdown in the platform lost its
       arrow and read as a text field. The house already knows this trap; it is written out at the
       .spark__bar--blip rule, where the same shorthand erased a hatch pattern. */
    background-color: var(--paper);
    border: 1px solid var(--line-2);
    border-radius: var(--r-sm);
    color: var(--ink);
    padding: 0.55rem 0.85rem;
    font-size: 0.9rem;
}

/* Room for the chevron, so a long option does not run underneath it. */
.form-select { padding-right: 2.25rem; }

/* The -sm variants were dead. app.css loads AFTER bootstrap (App.razor) and the rule above wins on
   equal specificity, so every .form-control-sm in the platform rendered at full size — the ticket
   queue asks for five of them. Restated here, after the rule that was overriding them. */
.form-control-sm, .form-select-sm {
    padding: 0.3rem 0.6rem;
    font-size: 0.82rem;
}

.form-select-sm { padding-right: 1.9rem; }

.form-control:focus, .form-select:focus { border-color: var(--blue-400); }
.form-control::placeholder { color: var(--faint); }

/* A disabled or read-only field (e.g. a closed ticket's Status/Priority/Kunde) must stay READABLE. Bootstrap's
   :disabled reverts the background to a light colour, which hides our light text on the dark theme — so the value
   vanished. Keep our own tokens and just dim it to signal it cannot be edited. -webkit-text-fill-color stops
   WebKit from greying out the disabled text on top of that. */
.form-control:disabled, .form-select:disabled,
.form-control[readonly], .form-select[readonly] {
    background-color: var(--paper);
    color: var(--ink);
    -webkit-text-fill-color: var(--ink);
    opacity: 0.6;
    cursor: not-allowed;
}

.form-check-input:checked { background-color: var(--navy-700); border-color: var(--navy-700); }

/* .tbl, .tbl-wrap og .num står som aliasser og ikke som egne regler.
   Femten tabeller rundt om i løsningen bruger de korte navne, men de blev aldrig
   skrevet — så de tabeller stod uden .table-wrap'ens overflow-x og gled hele siden
   sidelæns på en telefon. Aliasser frem for at omdøbe femten steder: én rettelse, og
   ingen af de femten kan glemmes. */
.table,
.tbl {
    --bs-table-bg: transparent;
    --bs-table-color: var(--ink);
    --bs-table-border-color: var(--line);
    --bs-table-hover-bg: var(--blue-50);
    margin: 0;
    vertical-align: middle;
    font-size: 0.89rem;

    /* Bredden kom fra Bootstraps egen .table-regel, som .tbl ikke står i — så de
       femten .tbl-tabeller krympede til indholdsbredde og lå smalt i et bredt panel,
       synligt anderledes end de ~20 .table-tabeller ved siden af. */
    width: 100%;
}

/* Reboot nulstiller cellernes border-width til 0, og den eneste regel, der giver dem
   bredde igen, er Bootstraps '.table > :not(caption) > * > *' — som .tbl heller ikke
   står i. Rækkerne løb derfor sammen uden stregar, selv om .tbl tbody td satte en
   border-color. Beviset for at det ikke var meningen stod på næste regel: en
   sidste-række-undtagelse, der fjernede en kant, som aldrig blev tegnet. */
.tbl > :not(caption) > * > * { border-bottom-width: var(--bs-border-width, 1px); }

/* Taljusteret højrestilling. Tal, der skal sammenlignes lodret, skal stå på samme
   cifferbredde — ellers hopper kolonnen, og man kan ikke se hvilket tal der er størst. */
.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.table thead th,
.tbl thead th {
    color: var(--muted);
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.11em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--line);
    padding: 0.7rem 0.9rem;
    white-space: nowrap;
}

.table tbody td,
.tbl tbody td { padding: 0.8rem 0.9rem; border-color: var(--line); }
.table tbody tr:last-child td,
.tbl tbody tr:last-child td { border-bottom: 0; }

/* Sorterbar kolonneoverskrift.
   En rigtig <button> og ikke et klikbart <th>: så kan man tabbe hen til den og
   trykke mellemrum, og en skærmlæser fortæller af sig selv, at den kan aktiveres. */
.th-sort {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    cursor: pointer;
    color: inherit;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
}

/* Samme fejl som .gchip ovenfor: hverken --fg eller --accent er erklæret, så
   overskriften skiftede ikke farve ved hover, den aktive sorteringskolonne kunne
   ikke skelnes fra de øvrige, og der var ingen fokusring at tabbe efter. */
.th-sort:hover { color: var(--ink); }
.th-sort:focus-visible { outline: 2px solid var(--blue-400); outline-offset: 3px; border-radius: 3px; }

.th-sort.aktiv { color: var(--ink); }

.table-wrap,
.tbl-wrap { overflow-x: auto; max-width: 100%; border-radius: var(--r-lg); }

/* Lange tekniske værdier (DNS-records o.l.) må ikke sprænge tabelbredden */
.truncate {
    display: block;
    max-width: 13rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* stat__meta bruges også som sekundærlinje i tabelceller */
td .stat__meta { display: block; margin-top: 0.2rem; }

.badge {
    border-radius: 999px;
    font-weight: 800;
    font-size: 0.68rem;
    letter-spacing: 0.05em;
    padding: 0.36em 0.72em;
    border: 1px solid transparent;
}

/* Badges får samme behandling som .pil: lys baggrund og en mørknet tekstfarve.
   Hvid tekst på accentfarverne holdt ikke WCAG AA ved 0,68 rem — hvid på --warn giver
   3,60:1, på --good 4,20:1 og på --muted 4,44:1, hvor kravet er 4,50. Kun bg-danger
   klarede den. Det ene sted, nogen havde forsøgt at rette det med .text-dark, kunne
   ikke virke: .text-dark er (0,1,0) mod .badge.bg-warning (0,2,0), og begge sætter
   !important, så teksten blev hvid alligevel. Badges står bl.a. på den offentlige
   statusside, hvor de er det, en kunde læser først.

   --good-ink / --warn-ink / --crit-ink er de samme efterprøvede værdier som .pil
   bruger; de er regnet igennem i tests/kontrastcheck. */
.badge.bg-success {
    background: var(--good-bg) !important;
    color: var(--good-ink) !important;
    border-color: color-mix(in srgb, var(--good) 28%, transparent) !important;
}

.badge.bg-warning {
    background: var(--warn-bg) !important;
    color: var(--warn-ink) !important;
    border-color: color-mix(in srgb, var(--warn) 30%, transparent) !important;
}

.badge.bg-danger {
    background: var(--crit-bg) !important;
    color: var(--crit-ink) !important;
    border-color: color-mix(in srgb, var(--crit) 30%, transparent) !important;
}

.badge.bg-secondary {
    background: color-mix(in srgb, var(--ink) 6%, transparent) !important;
    color: var(--ink-2) !important;
    border-color: color-mix(in srgb, var(--ink) 14%, transparent) !important;
}

/* Bootstraps egen bg-primary er solid og hvid — den ville stå tilbage som det eneste
   fyldte mærke mellem lutter lyse. */
.badge.bg-primary {
    background: var(--blue-100) !important;
    color: var(--navy-800) !important;
    border-color: color-mix(in srgb, var(--navy-600) 25%, transparent) !important;
}

/* bg-info og bg-dark manglede samme behandling som resten — de faldt tilbage på Bootstraps
   mættede cyan/næsten-sort fyld, som hverken er efterprøvet mod WCAG eller passer paletten.
   «Kundevendt»-mærket (info) og «Arkiveret»-mærket (dark) i Vidensbasen bruger dem. */
.badge.bg-info {
    background: var(--blue-50) !important;
    color: var(--navy-700) !important;
    border-color: color-mix(in srgb, var(--blue-400) 34%, transparent) !important;
}

.badge.bg-dark {
    background: color-mix(in srgb, var(--ink) 10%, transparent) !important;
    color: var(--ink) !important;
    border-color: color-mix(in srgb, var(--ink) 22%, transparent) !important;
}

.alert {
    border-radius: var(--r-md);
    border-width: 1px;
    font-size: 0.9rem;
    padding: 0.85rem 1.1rem;
}

/* Kompakt variant — erstatter de per-side inline padding/font-size-overrides på små infobjælker. */
.alert--sm { padding: 0.5rem 0.75rem; font-size: 0.82rem; }

.alert-info { background: var(--blue-50); border-color: var(--blue-200); color: var(--navy-800); }
/* Tekst- og kantfarver var hånd-plukkede hex tæt på — men ikke lig med — de efterprøvede
   *-ink-tokens. Bruger nu tokenerne + color-mix-kanter som .badge, så kontrasten er den samme
   validerede værdi ét sted. */
.alert-danger { background: var(--crit-bg); border-color: color-mix(in srgb, var(--crit) 30%, transparent); color: var(--crit-ink); }
.alert-warning { background: var(--warn-bg); border-color: color-mix(in srgb, var(--warn) 30%, transparent); color: var(--warn-ink); }
.alert-success { background: var(--good-bg); border-color: color-mix(in srgb, var(--good) 28%, transparent); color: var(--good-ink); }

.text-secondary { color: var(--muted) !important; }
.text-danger { color: var(--crit) !important; }

/* Validering / Blazor-fejl */
.valid.modified:not([type=checkbox]) { outline: 1px solid var(--good); }
.invalid { outline: 1px solid var(--crit); }
.validation-message { color: var(--crit); font-size: 0.83rem; }

.blazor-error-boundary {
    background: var(--crit);
    padding: 1rem 1.25rem;
    color: #fff;
    border-radius: var(--r-md);
}

.blazor-error-boundary::after { content: "Der opstod en fejl."; }

.darker-border-checkbox.form-check-input { border-color: var(--line-2); }

/* --------------------------------------------------------------------------
   Detaljer om mailopsætning på et domænekort — dybden der før var tænkt som
   selvstændige SPF- og DKIM-moduler. Foldet sammen, så oversigten kan skimmes.
   -------------------------------------------------------------------------- */

.ddetail { margin-top: 0.9rem; border-top: 1px solid var(--line); padding-top: 0.7rem; }

.ddetail > summary {
    cursor: pointer;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--blue-500);
    list-style: none;
}

.ddetail > summary::-webkit-details-marker { display: none; }
.ddetail > summary::before { content: "▸ "; }
.ddetail[open] > summary::before { content: "▾ "; }
.ddetail > summary:hover { color: var(--ink); }

.ddetail__block { margin-top: 0.9rem; }
.ddetail__block + .ddetail__block { padding-top: 0.9rem; border-top: 1px dashed var(--line); }

.ddetail__title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--ink);
    margin-bottom: 0.5rem;
}

.ddetail__label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 0.7rem 0 0.25rem;
}

/* --wash findes ikke i :root, og background arves ikke — feltet stod derfor helt
   gennemsigtigt, så en DNS-record lå direkte på panelet uden at se ud som en værdi,
   der kan kopieres. --blue-50 er husets lyseste flade. */
.ddetail__code {
    display: block;
    background: var(--blue-50);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    padding: 0.55rem 0.7rem;
    font-size: 0.8rem;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    color: var(--ink-2);
    /* Lange SPF-poster og DKIM-nøgler må bryde frem for at sprænge kortet. */
    white-space: pre-wrap;
    word-break: break-all;
    margin: 0;
}

/* Udførelsesnote på en årshjuls-aktivitet — dokumentationen, ikke bare et flueben. */
.done-note {
    display: flex;
    align-items: flex-start;
    gap: 0.4rem;
    margin-top: 0.4rem;
    padding: 0.5rem 0.7rem;
    background: color-mix(in srgb, var(--good) 12%, transparent);
    border-left: 2px solid var(--good);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    color: var(--ink-2);
}

.done-note .icon { color: var(--good); flex-shrink: 0; margin-top: 0.1rem; }

/* --------------------------------------------------------------------------
   Periodevælger — perioden skal være det første øjet fanger på en rapport,
   så man aldrig er i tvivl om, hvad tallene dækker.
   -------------------------------------------------------------------------- */

.period { display: flex; align-items: center; gap: 1.2rem; }

.period__main { flex: 1; text-align: center; }

.period__label {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
}

.period__value {
    font-size: 1.7rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    color: var(--ink);
    line-height: 1.15;
    /* Måneden kommer fra ToString("MMMM") og starter med lille bogstav på dansk. */
    text-transform: capitalize;
}

.period__range { font-size: 0.85rem; color: var(--muted); margin-top: 0.15rem; }

.period__quick {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 1.1rem;
    padding-top: 0.9rem;
    border-top: 1px solid var(--line);
}

.period__quick .btn.active {
    background: var(--navy-800);
    border-color: var(--navy-800);
    color: #fff;
}

@media (max-width: 640px) {
    .period__value { font-size: 1.3rem; }
    .period__quick { flex-wrap: wrap; }
    .period__quick .stat__meta { margin-left: 0 !important; width: 100%; }
}

/* --------------------------------------------------------------------------
   Vandret måler — bruges til oppetid og tidsfordeling i servicerapporten.
   -------------------------------------------------------------------------- */

.bar {
    height: 8px;
    border-radius: 4px;
    background: var(--line);
    overflow: hidden;
}

.bar__fill {
    height: 100%;
    border-radius: 4px;
    background: var(--blue-500);
    transition: width 0.3s ease;
}

/* --------------------------------------------------------------------------
   Sikkerhedsscore — cirkeldiagram tegnet med conic-gradient, så der ikke
   skal et diagrambibliotek ind for ét enkelt tal.
   -------------------------------------------------------------------------- */

.score { display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; }

.score__dial {
    width: 148px;
    height: 148px;
    border-radius: 50%;
    flex-shrink: 0;
    /* --pct sættes inline af komponenten: 0-100. */
    background: conic-gradient(var(--col) calc(var(--pct) * 1%), var(--line) 0);
    display: grid;
    place-items: center;
}

.score__inner {
    width: 116px;
    height: 116px;
    border-radius: 50%;
    background: var(--paper);
    display: grid;
    place-items: center;
    text-align: center;
    line-height: 1.1;
}

.score__num { font-size: 2.4rem; font-weight: 700; color: var(--ink); letter-spacing: -0.03em; }
.score__of { font-size: 0.78rem; color: var(--muted); }

.score__grade { font-size: 1.25rem; font-weight: 600; color: var(--ink); letter-spacing: -0.02em; }

@media (max-width: 600px) {
    .score { gap: 1.2rem; }
}

/* --------------------------------------------------------------------------
   Min konto
   Identity-siderne kom fra Blazors skabelon med Bootstraps form-floating.
   Vores .form-control har lavere højde og padding end Bootstrap regner med, så
   den svævende label lagde sig oven i placeholderen. Siderne bruger nu i stedet
   platformens eget mønster: label over feltet, som alle andre formularer.
   -------------------------------------------------------------------------- */

.acct { display: grid; grid-template-columns: 232px 1fr; gap: 1.1rem; align-items: start; }

.acct__nav { display: flex; flex-direction: column; gap: 2px; }

.acct__link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.75rem;
    border-radius: var(--r-sm);
    color: var(--ink-2);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
}

/* Samme udefinerede --wash: menupunktet gav ingen hover-respons overhovedet. */
.acct__link:hover { background: var(--blue-50); color: var(--ink); }

.acct__link.active {
    background: var(--navy-800);
    color: #fff;
}

.acct__link.active .icon { opacity: 1; }
.acct__link .icon { opacity: 0.75; flex-shrink: 0; }

/* Feltgruppe: label, felt, hjælpetekst og fejl som én blok. */
.fld { margin-bottom: 1rem; }

.fld > label {
    display: block;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 0.35rem;
}

.fld__hint { font-size: 0.82rem; color: var(--muted); margin-top: 0.3rem; }
.fld .validation-message { font-size: 0.82rem; }

/* Nøgle/værdi-liste til profiloplysninger vi viser men ikke redigerer. */
.kv { display: grid; gap: 0.85rem; }

.kv__row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--line);
}

.kv__row:last-child { border-bottom: 0; padding-bottom: 0; }

.kv__key { font-size: 0.85rem; color: var(--muted); }
.kv__val { font-size: 0.92rem; color: var(--ink); font-weight: 500; text-align: right; }

/* Række med en til/fra-indstilling og forklarende undertekst. */
.tgl {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1.25rem;
    padding: 0.9rem 0;
    border-bottom: 1px solid var(--line);
}

.tgl:last-of-type { border-bottom: 0; }
.tgl__text strong { display: block; font-size: 0.92rem; color: var(--ink); font-weight: 600; }
.tgl__text span { display: block; font-size: 0.83rem; color: var(--muted); margin-top: 0.15rem; max-width: 56ch; }
.tgl__ctl { flex-shrink: 0; padding-top: 0.15rem; }

@media (max-width: 900px) {
    .acct { grid-template-columns: 1fr; }
    .acct__nav { flex-direction: row; flex-wrap: wrap; }
}

/* ==========================================================================
   Indstillinger: kort i grupper
   ========================================================================== */

.setgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
    gap: 0.75rem;
}

.setcard {
    display: flex;
    align-items: flex-start;
    gap: 0.8rem;
    padding: 0.95rem 1.05rem;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--paper);
    text-decoration: none;
    color: inherit;
    transition: border-color 0.14s ease, box-shadow 0.14s ease, transform 0.14s ease;
}

.setcard:hover {
    border-color: var(--blue-300);
    box-shadow: var(--shadow-sm);
    transform: translateY(-1px);
}

.setcard__icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 9px;
    background: var(--blue-50);
    color: var(--blue-500);
}

.setcard__main { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }

.setcard__title { font-weight: 700; font-size: 0.93rem; color: var(--ink); }
.setcard__sub { font-size: 0.82rem; color: var(--muted); line-height: 1.5; }

/* Skillelinje mellem SSO-knappen og adgangskodeformularen på login. */
.auth__or {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
    color: var(--muted);
    font-size: 0.78rem;
}

.auth__or::before,
.auth__or::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
}

/* ==========================================================================
   Offentlig driftsstatusside (uden login)
   ========================================================================== */

.pub { min-height: 100vh; padding: 2.5rem 1.25rem 3rem; }
.pub__inner { max-width: 720px; margin: 0 auto; }

.pub__brand {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-bottom: 1.75rem;
}

.pub__foot {
    margin-top: 2rem;
    text-align: center;
    font-size: 0.82rem;
    color: var(--muted);
}

/* Den samlede status øverst. Farven skal kunne aflæses på et halvt sekund. */
.pub__status { display: flex; align-items: center; gap: 1rem; }

.pub__dot {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--blue-300);
}

.pub__status--ok .pub__dot { background: var(--good); box-shadow: 0 0 0 5px rgba(60, 132, 96, 0.16); }
.pub__status--warn .pub__dot { background: var(--warn); box-shadow: 0 0 0 5px rgba(176, 125, 51, 0.18); }
.pub__status--down .pub__dot { background: var(--crit); box-shadow: 0 0 0 5px rgba(176, 60, 60, 0.18); }
.pub__status--unknown .pub__dot { background: var(--blue-300); }

/* Oppetids-historik pr. system (Fase 1): en bjælke pr. dag + oppetids-%, grupperet (Fase 2). */
.pubsys__head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; margin-bottom: 0.9rem; }
.pubsys__gruppe {
    font-weight: 700;
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-2);
    margin: 1.3rem 0 0.4rem;
}
.pubsys__row { padding: 0.75rem 0; border-top: 1px solid var(--line); }
.pubsys__row:first-of-type { border-top: none; padding-top: 0.35rem; }
.pubsys__top { display: flex; justify-content: space-between; align-items: baseline; gap: 0.6rem; }
.pubsys__navn { font-weight: 600; display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0; }
.pubsys__dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.pubsys__pct { font-size: 0.8rem; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* overflow-x: auto — så kun bjælke-striben kan scrolle vandret, ikke hele den offentlige side, når
   90 dages bjælker ikke kan krympe under min-width på en smal telefon. */
.pubsys__bars { display: flex; gap: 2px; height: 26px; margin: 0.55rem 0 0.35rem; overflow-x: auto; }
.pubsys__bar { flex: 1 1 0; min-width: 2px; border-radius: 2px; }
.pubsys__status { font-size: 0.8rem; }

/* Blazor-fejlbjælken. Stod før KUN i MainLayout.razor.css, som er SCOPET til MainLayout — så den
   offentlige statusside (PublicLayout) fik ingen «display:none» og viste «Der opstod en uventet fejl»
   PERMANENT, uden at der var en fejl. Global her, så begge layouts skjuler den, og blazor.web.js viser
   den kun ved en faktisk fejl. */
#blazor-error-ui {
    color-scheme: light only;
    background: #fdf3e3;
    color: #7d5720;
    border-top: 1px solid #e8d5b0;
    bottom: 0;
    box-shadow: 0 -6px 20px rgba(19, 28, 40, 0.12);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.75rem 1.4rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: 0.9rem;
    font-weight: 600;
}
#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 1rem;
    top: 0.65rem;
}

.pub__notice {
    padding: 0.95rem 1.1rem;
    border-radius: var(--r-md);
    border-left: 4px solid var(--blue-300);
    background: var(--blue-50);
}

.pub__notice + .pub__notice { margin-top: 0.7rem; }
.pub__notice--warn { border-left-color: var(--warn); }
.pub__notice--down { border-left-color: var(--crit); }

.pub__notice-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* Auth-sider (login / 2FA) — centreret kort uden sidebar-tyngde */
.auth {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 2rem 1.25rem;
}

.auth__card {
    width: 100%;
    max-width: 430px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-lg);
    padding: 2.25rem 2.15rem;
}

/* ==========================================================================
   Responsivt
   ========================================================================== */

/* Mellembredder (typisk halv skærm / mindre laptops): giv indholdet luft ved at
   slanke sidebaren og padding — ellers bliver datatabeller unødigt klemt. */
@media (max-width: 1180px) and (min-width: 901px) {
    :root { --sidebar-w: 214px; }

    .app__content { padding: 1.9rem 1.5rem 3rem; }

    .side__brand { padding: 1.2rem 1rem 1.05rem; }
    .side__nav { padding: 0.4rem 0.6rem 1rem; }
    .side__link { font-size: 0.83rem; padding: 0.55rem 0.6rem; }

    .topbar { padding: 0.75rem 1.5rem 0; }

    .truncate { max-width: 11rem; }
}

@media (max-width: 900px) {
    .app { flex-direction: column; }

    .side {
        width: 100%;
        height: auto;
        position: relative;
    }

    .side__nav { display: none; }

    .side__toggle {
        display: block;
        position: absolute;
        top: 1.15rem;
        right: 1.15rem;
        width: 42px;
        height: 38px;
        appearance: none;
        border: 1px solid rgba(255, 255, 255, 0.2);
        border-radius: 10px;
        background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255,255,255,0.8%29' stroke-linecap='round' stroke-width='2' d='M5 8h20M5 15h20M5 22h20'/%3e%3c/svg%3e") no-repeat center/1.4rem rgba(255, 255, 255, 0.08);
        cursor: pointer;
    }

    .side__toggle:checked ~ .side__nav { display: block; }

    /* Menu-foden (Rediger genveje + skinne-knap) hører til menuen, ikke til den altid-synlige
       topbjælke. Skjul den som nav'et og vis den kun, når hamburgeren er åben — ellers står
       «Rediger genveje» alene mellem logoet og søgefeltet, hvor den ikke giver mening. */
    .side__foot { display: none; }
    .side__toggle:checked ~ .side__foot { display: block; }

    /* Ikon-skinnen er en skrivebordsting: på mobil er menuen fuld bredde og foldes med
       hamburgeren. Skjul fold-knappen, og annullér en skinne-tilstand der er husket fra
       skrivebordet (nav.js sætter data-rail på <html> uanset skærmbredde), så den fulde
       menu ikke bliver klemt ned til 66px på telefonen. */
    .side__rail { display: none; }
    :root[data-rail="1"] .side { width: 100%; }
    :root[data-rail="1"] .side__brand { justify-content: flex-start; padding-left: 1.35rem; padding-right: 1.35rem; }
    :root[data-rail="1"] .side__wordmark { display: inline; }
    :root[data-rail="1"] .side__label { display: inline; }
    :root[data-rail="1"] .side__section { display: block; }
    :root[data-rail="1"] .side__link { justify-content: flex-start; padding-left: 0.75rem; padding-right: 0.75rem; gap: 0.7rem; }

    /* Fastgør-nålen er en hover-affordance til mus. På touch bliver første tap til «hover» (viser
       nålen) i stedet for at navigere, så man skulle trykke to gange på et menupunkt — skjul den på
       mobil. Uden nålen er der heller ingen grund til at reservere plads til den i højre side af linket. */
    .side__pin { display: none; }
    .side__row .side__link { padding-right: 0.75rem; }

    .topbar { padding: 0.75rem 1.25rem 0; }
    .topbar__who { display: none; }

    /* Søgefeltet får resten af bredden, men skal kunne klemmes sammen ved siden
       af klokke, avatar og log ud. */
    .topsearch { flex: 1 1 auto; min-width: 0; }
    .topsearch__input { font-size: 0.82rem; }

    .app__content { padding: 1.5rem 1.25rem 2.5rem; }

    .hero { padding: 1.5rem 1.35rem; }

    .chart__row { grid-template-columns: 4.5rem 1fr; }
    .chart__val { grid-column: 1 / -1; text-align: left; }
}

/* --------------------------------------------------------------------------
   Telefon (≤ 640px)

   Platformen er bygget på en bred skærm, og datatabellerne er brede af natur.
   Frem for at klemme dem sammen får de lov at scrolle vandret inde i deres eget
   panel — så bliver det tabellen der scroller, ikke hele siden. En side der
   glider sidelæns, er den hurtigste måde at gøre en app ubrugelig på telefonen.
   -------------------------------------------------------------------------- */

@media (max-width: 640px) {
    /* Tabeller: scroll indeni panelet. -webkit-overflow-scrolling giver
       inerti-scroll på iOS, hvor det ellers føles hakkende. */
    .panel table.table,
    .table-wrap {
        display: block;
        max-width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* thead/tbody skal IKKE gøres til hver sin "display: table" — så bliver de to
       uafhængige tabeller, og kolonnerne i hoved og krop holder ikke linje.
       Med display:block på selve tabellen pakkes alle rækker i én anonym tabel,
       og justeringen holder. */

    /* Panel-hoveder har titel til venstre og handlinger til højre. På en telefon
       er der ikke plads til begge dele på én linje. */
    .panel__head {
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
    }

    .panel__head > div:last-child,
    .panel__head .d-flex { flex-wrap: wrap; }

    /* Filtre og vælgere sættes med style="width:auto" til desktop; her skal de
       fylde bredden, ellers bliver de for smalle til at ramme med en finger. */
    .panel__head .form-select,
    .panel__head .form-control,
    .tkt-filters .form-select,
    .tkt-filters .form-control { width: 100% !important; min-width: 0; }

    .ph { margin-bottom: 1.3rem; }
    .ph__actions { width: 100%; }
    .ph__actions .btn { flex: 1 1 auto; }

    /* Sider med paneler: giv indholdet lidt mere plads i bredden. */
    .app__content { padding: 1.15rem 0.9rem 2rem; }
    .panel { padding: 1.15rem 1rem; }

    /* Nøgletal side om side bliver ulæselige under ~340px. */
    .stat { padding: 1.05rem 1.1rem; }

    /* Sikkerhedsscore: dial og forklaring under hinanden, dialen lidt mindre. */
    .score { gap: 1.2rem; justify-content: center; }
    .score__dial { width: 124px; height: 124px; }
    .score__text { flex: 1 1 100%; }

    /* Servicerapportens periodevælger: pilene skal blive ved siden af, men
       teksten må gerne fylde resten. */
    .period { gap: 0.6rem; }

    /* Ticket-rækker: badges og tidsstempel under titlen frem for ved siden af. */
    .tkt { flex-wrap: wrap; }
    .tkt__side {
        width: 100%;
        justify-content: flex-start;
        padding-left: 1.9rem;
        flex-wrap: wrap;
    }

    /* Nøgle/værdi-lister: værdien under nøglen når begge er lange. */
    .kv__row { flex-wrap: wrap; gap: 0.2rem; }

    /* Den flydende "Registrér tid"-knap fylder for meget på en lille skærm —
       genvejstasten giver heller ingen mening uden tastatur. */
    .qte__launch { right: 0.9rem; bottom: 0.9rem; padding: 0.65rem 0.95rem; }
    .qte__launch kbd { display: none; }

    /* Dialoger: brug hele bredden og undgå at hovedet æder skærmen. */
    .dlg, .dlg--lg { width: calc(100vw - 1.2rem); max-height: calc(100vh - 1.5rem); }
    .dlg__head { padding: 1.1rem 1.15rem 0.8rem; }
    .dlg__body { padding: 1.1rem 1.15rem; }
    /* Margenerne skal følge .dlg__body's mindre luft, ellers rammer stregen ikke kanten. */
    .dlg__foot { margin: 1.1rem -1.15rem -1.1rem; padding: 0.9rem 1.15rem 1.1rem; flex-wrap: wrap; }
    .dlg__foot .btn { flex: 1 1 auto; }

    /* Lange DNS-records o.l. må gerne bruge hele bredden her. */
    .truncate { max-width: 100%; }
}

/* Fingerstørrelse frem for musestørrelse: på enheder uden præcis pegeenhed
   skal knapper og menupunkter være store nok til at ramme. */
@media (pointer: coarse) {
    .side__link { padding-top: 0.7rem; padding-bottom: 0.7rem; }
    .btn-sm { padding: 0.4rem 0.75rem; }
    .tkt-chip { padding: 0.5rem 0.95rem; }
}

/* ==========================================================================
   Tastatur og fokus

   Alt hvad man kan klikke på, skal også kunne nås med Tab og aktiveres med
   Enter/Mellemrum — og man skal kunne SE hvor man er. Ringen vises kun ved
   :focus-visible, så den dukker op når man tabber, men ikke ved museklik.
   ========================================================================== */

:where(a, button, .btn, [role="button"], input, select, textarea, summary):focus-visible {
    outline: 2px solid var(--blue-400);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

/* Klikbare rækker og kort: samme fremhævning som hover, plus ringen. .aftale (kunde-Home's
   aftalekort) er også et klikbart <a> med :hover, men manglede fokus-ringen. */
.tkt:focus-visible, .fcard:focus-visible, .notif__item:focus-visible, .aftale:focus-visible {
    outline: 2px solid var(--blue-400);
    outline-offset: 2px;
    box-shadow: inset 0 0 0 1px var(--line-2), var(--shadow-sm);
}

/* Sidebar og topbar ligger på mørk bund — dér forsvinder den blå ring. */
.side__link:focus-visible, .side__brand:focus-visible, .topbar .btn:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* Spring til indhold: usynligt indtil man tabber til det som det første på siden. */
.skiplink {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    background: var(--navy-800);
    color: #fff;
    padding: 0.65rem 1.1rem;
    border-radius: 0 0 var(--r-sm) 0;
    font-weight: 700;
    font-size: 0.88rem;
}

.skiplink:focus {
    left: 0;
    color: #fff;
}

/* Respektér systemets "reducér bevægelse". Vi fjerner ikke fokusringe eller
   farveskift — kun det der faktisk bevæger sig. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }

    .tkt:hover, .fcard:hover, .setcard:hover, .stat:hover, .btn:hover {
        transform: none;
    }
}

/* ==========================================================================
   Indlæsning

   Pladsholderne skal have samme højde og afstand som det rigtige indhold, så
   siden ikke flytter sig når data lander. Glimtet er sat lavt: det skal antyde
   at der sker noget, ikke trække blikket til sig.
   ========================================================================== */

/* Kun for skærmlæsere — bruges til at annoncere "Henter…" uden at vise det. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.skel {
    background: linear-gradient(90deg,
        var(--clay-100) 0%,
        var(--line) 40%,
        var(--clay-100) 80%);
    background-size: 300% 100%;
    border-radius: 6px;
    animation: skel-shimmer 1.4s ease-in-out infinite;
}

@keyframes skel-shimmer {
    0% { background-position: 120% 0; }
    100% { background-position: -60% 0; }
}

.skel--line { height: 0.8rem; margin-bottom: 0.55rem; }
.skel--line-sm { height: 0.65rem; opacity: 0.75; }
.skel--label { height: 0.6rem; width: 45%; margin-bottom: 0.75rem; }
.skel--value { height: 1.9rem; width: 35%; margin-bottom: 0.6rem; }
.skel--meta { height: 0.6rem; width: 60%; }
.skel--block { height: 5.5rem; margin-top: 0.9rem; }
.skel--prik { width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0; }
.skel--avatar { width: 2.1rem; height: 2.1rem; border-radius: 50%; flex-shrink: 0; }
.skel--pill { width: 4.5rem; height: 1.5rem; border-radius: 999px; flex-shrink: 0; }

/* Samme mål som .stat, så nøgletallene ikke rykker når de kommer. */
.skel-tile {
    background: var(--paper);
    border-radius: var(--r-lg);
    box-shadow: inset 0 0 0 1px var(--line);
    padding: 1.15rem 1.25rem;
}

.skel-rows { display: flex; flex-direction: column; gap: 0.5rem; }

/* Samme mål som .tkt. */
.skel-row {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.85rem 1rem;
    border-radius: var(--r-md);
    box-shadow: inset 0 0 0 1px var(--line);
}

.skel-row__main { flex: 1; min-width: 0; }
.skel-row__main .skel--line:last-child { margin-bottom: 0; }

.skel-cards {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.9rem;
}

.skel-card {
    padding: 1rem 1.1rem;
    border-radius: var(--r-md);
    box-shadow: inset 0 0 0 1px var(--line);
}

/* Har brugeren bedt om mindre bevægelse, står pladsholderne stille. De virker
   stadig — det er formen og ikke glimtet der holder layoutet på plads. */
@media (prefers-reduced-motion: reduce) {
    .skel { animation: none; background: var(--clay-100); }
}

/* Trin-for-trin-vejledninger (fx installation på hjemmeskærmen). Nummereringen
   skal kunne læses på en telefon, hvor teksten ofte fylder flere linjer. */
.pwa-steps ol, .pwa-steps ul {
    margin: 0;
    padding-left: 1.3rem;
    color: var(--ink);
    font-size: 0.92rem;
    line-height: 1.6;
}

.pwa-steps li { margin-bottom: 0.55rem; }
.pwa-steps li:last-child { margin-bottom: 0; }
.pwa-steps li::marker { color: var(--muted); font-weight: 700; }

/* ==========================================================================
   Vedhæftninger på en sag
   ========================================================================== */

.atts {
    margin: 1.15rem 0;
    padding: 1rem 1.1rem;
    border-radius: var(--r-md);
    background: var(--clay-100);
    box-shadow: inset 0 0 0 1px var(--line);
}

.atts__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 0.75rem;
}

.atts__actions { display: flex; gap: 0.4rem; flex-wrap: wrap; }

/* Filvælgeren er skjult inde i knappen: browserens egen <input type=file> kan ikke
   styles, så vi bruger en <label> som knap og lader den udløse inputtet. */
.atts__pick {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    cursor: pointer;
    margin: 0;
}

/* Vedhæftninger valgt under oprettelse, før sagen findes. */
.atts__picks {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.vedhft__liste {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.vedhft__liste li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.5rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    font-size: 0.85rem;
}

/* Filnavnet skal give plads til størrelsen og Fjern-knappen frem for at skubbe
   dem ud af rækken. Et langt navn fra en telefon er ellers nok til at gøre
   knappen utilgængelig på en smal skærm. */
.vedhft__navn {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.atts__pick input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* Tastaturbrugere skal kunne se at knappen har fokus, selvom det er inputtet inden i
   der reelt får det. */
.atts__pick:has(input:focus-visible) {
    outline: 2px solid var(--blue-400);
    outline-offset: 2px;
}

.atts__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
    gap: 0.65rem;
}

.att {
    position: relative;
    background: var(--paper);
    border-radius: var(--r-sm);
    box-shadow: inset 0 0 0 1px var(--line);
    overflow: hidden;
}

/* Miniaturen er nu en <button> for filer, der kan vises, og et <a> for dem, der kun
   kan hentes. Begge skal se ens ud, så nulstillingen af knappen står her. */
.att__view {
    display: block;
    height: 6.5rem;
    background: var(--clay-100);
    width: 100%;
    padding: 0;
    border: 0;
    cursor: pointer;
    font: inherit;
    color: inherit;
    text-align: left;
}

.att__view:hover { background: var(--blue-50); }

/* Tastaturbrugere skal kunne se, hvilken fil de står på. Indad, så ringen ikke
   klippes af kortets overflow. */
.att__view:focus-visible {
    outline: 2px solid var(--navy-800);
    outline-offset: -2px;
}

.att__view img { width: 100%; height: 100%; object-fit: cover; display: block; }

.att__file {
    display: grid;
    place-items: center;
    height: 100%;
    color: var(--muted);
}

/* Fremviseren i modalen */

.attview {
    display: grid;
    place-items: center;
    background: var(--clay-100);
    border-radius: 10px;
    overflow: hidden;
}

/* Højden er bundet til vinduet og ikke til billedet. Et portrætfoto fra en telefon
   ville ellers skubbe modalens fodrække langt under skærmkanten. */
.attview__img {
    max-width: 100%;
    max-height: 72vh;
    display: block;
    object-fit: contain;

    /* Der zoomes ved at skalere elementet, så det forstørrede skal blive inde i
       rammen — ellers ville billedet lægge sig hen over modalens kanter. */
    transform-origin: center center;
    will-change: transform;
}

.attview--zoom {
    overflow: hidden;

    /* Så man kan se, at der er noget at gøre, før man prøver. */
    cursor: zoom-in;

    /* Uden det ville et træk på billedet markere det som tekst i stedet for at
       flytte det, og markeringen ville blive hængende bagefter. */
    user-select: none;
    -webkit-user-select: none;
}

.attview--zoom img { -webkit-user-drag: none; }

.attview__zoom { display: flex; gap: 0.3rem; }

/* Knapperne er runde og lige brede, så "−" og "+" ikke hopper i forhold til
   "Tilpas" imellem dem. 40 px er trykmålet fra resten af mobilvisningen. */
.attview__zoom .btn {
    min-width: 40px;
    min-height: 40px;
    font-weight: 700;
}

.attview__pdf {
    width: 100%;
    height: 72vh;
    border: 0;
    display: block;
    background: #fff;
}

.attview__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

/* På en telefon er 72vh for lidt til en PDF — der er ingen sidebar at tage plads fra,
   og en A4-side skal kunne læses uden at zoome på hver linje. */
@media (max-width: 640px) {
    .attview__pdf { height: 78vh; }
    .attview__img { max-height: 68vh; }
}

.att__meta { padding: 0.5rem 0.6rem; }

.att__name {
    display: block;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.att__sub { font-size: 0.74rem; color: var(--muted); }

/* Slet-knappen ligger oven på billedet — den skal kunne læses på både lyse og
   mørke fotos, så den får sin egen baggrund. */
.atts__del {
    position: absolute;
    top: 0.3rem;
    right: 0.3rem;
    background: rgba(255, 255, 255, 0.92);
    border-radius: 6px;
    padding: 0.1rem 0.45rem;
}

/* Tilmeldingsbillet: skal kunne læses højt og tastes af på en boks uden fejl. */
.tokenbox {
    font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
    font-size: 1.3rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-align: center;
    padding: 1.1rem 0.75rem;
    border-radius: var(--r-md);
    background: var(--clay-100);
    box-shadow: inset 0 0 0 1px var(--line-2);
    color: var(--ink);
    user-select: all;
    overflow-wrap: anywhere;
}

/* Godkendelsesfeltet under en ukendt afsender. */
.afs__godkend { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; }
.afs__godkend .form-control { flex: 1; min-width: 11rem; }

/* Kvitteringen nederst på Dmarc: kommer der rapporter? Én linje, ikke en liste. */
.dm-kvittering { display: flex; flex-wrap: wrap; gap: 0.5rem 1rem; font-size: 0.82rem; color: var(--muted); padding: 0.2rem 0.2rem 0.9rem; }
.dm-kvittering--gammel { color: var(--warn); font-weight: 700; }

/* SPF og DKIM som to selvstaendige maerker paa afsenderkortet. */
.afs__ben { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.45rem; }
.afs__ben-mærke { font-size: 0.72rem; font-weight: 800; letter-spacing: 0.02em; border-radius: 999px; padding: 0.12rem 0.5rem; }
.afs__ben-mærke.er-ok { color: var(--good); background: var(--good-bg); }
.afs__ben-mærke.er-fejl { color: var(--crit); background: var(--crit-bg); }
.afs__ben-note { font-size: 0.74rem; color: var(--muted); }
.afs__raad--diag { border-left: 2px solid var(--line-2); padding-left: 0.6rem; margin-top: 0.35rem; }

/* ── Dmarc: raekkeniveau-drilldown ────────────────────────────────────────
   Bevidst under overblikket. Teknikeren har brug for linjen; alle andre har
   brug for konklusionen, og den staar ovenfor. */
.dm-politik { font-size: 0.84rem; color: var(--ink-2); padding: 0.2rem 0 0.8rem; }
.dm-politik code { background: color-mix(in srgb, var(--ink) 7%, transparent); padding: 0.05rem 0.3rem; border-radius: 4px; }

.dm-linjer__row { cursor: pointer; }
.dm-linjer__row:hover { background: var(--blue-50); }
.dm-linjer__row:focus-visible { outline: 2px solid var(--ink-2); outline-offset: -2px; }
.dm-linjer__navn { font-weight: 700; font-size: 0.84rem; }
.dm-linjer__ip { font-size: 0.72rem; color: var(--faint); font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

.dm-mrk { font-size: 0.72rem; font-weight: 800; border-radius: 999px; padding: 0.1rem 0.45rem; white-space: nowrap; }
.dm-mrk.er-ok { color: var(--good); background: var(--good-bg); }
.dm-mrk.er-fejl { color: var(--crit); background: var(--crit-bg); }

.dm-linjer__detalje > td { background: var(--shell); }

.dm-detalje { display: grid; grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr)); gap: 1rem 2rem; padding: 0.5rem 0.2rem; }
.dm-detalje__titel { font-weight: 800; font-size: 0.8rem; margin-bottom: 0.3rem; }
.dm-detalje dl { display: grid; grid-template-columns: auto 1fr; gap: 0.15rem 0.9rem; margin: 0; font-size: 0.78rem; }
.dm-detalje dt { color: var(--muted); }
.dm-detalje dd { margin: 0; color: var(--ink); font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }

/* ── Dmarc: kan politikken strammes? ──────────────────────────────────────
   Oeverst paa siden, fordi det er konklusionen. Alt andet paa siden er
   argumenterne for den. */
.dm-gate { border-left: 4px solid var(--line-2); }
.dm-gate--ok { border-left-color: var(--good); }
.dm-gate--klar { border-left-color: var(--good); }
.dm-gate--blok { border-left-color: var(--warn); }

.dm-gate__hd { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; justify-content: space-between; }
.dm-gate__nu { font-size: 0.8rem; color: var(--muted); }
.dm-gate__svar { font-size: 1.02rem; font-weight: 800; color: var(--ink); margin-top: 0.15rem; }

.dm-trin { display: flex; align-items: center; gap: 0.35rem; }
.dm-trin__t {
    font-size: 0.72rem; font-weight: 800; border-radius: 999px;
    padding: 0.16rem 0.55rem; color: var(--faint);
    background: color-mix(in srgb, var(--ink) 5%, transparent);
    white-space: nowrap;
}
.dm-trin__t.er-naaet { color: var(--good); background: var(--good-bg); }
.dm-trin__t.er-naeste { color: var(--ink); background: var(--clay-200); }

.dm-gate__liste { margin-top: 0.9rem; }
.dm-gate__titel { font-weight: 800; font-size: 0.82rem; margin-bottom: 0.4rem; }
.dm-gate__titel--blok { color: var(--warn); }

.dm-punkt { padding: 0.4rem 0; border-top: 1px solid var(--line); }
.dm-punkt__h { font-weight: 700; font-size: 0.86rem; }
.dm-punkt__d { font-size: 0.82rem; color: var(--ink-2); line-height: 1.5; margin-top: 0.1rem; }

.dm-gate__raad { margin-top: 0.9rem; font-size: 0.84rem; color: var(--ink-2); line-height: 1.55; }
.dm-gate__raad code { background: color-mix(in srgb, var(--ink) 7%, transparent); padding: 0.05rem 0.3rem; border-radius: 4px; }

/* Forslag fra kundesiden, der endnu ikke er bekraeftet. Roligt, ikke alarmerende:
   det er et svar, ikke et problem. */
.afs__forslag { margin-top: 0.15rem; }
.afs__forslag-navn { font-size: 0.84rem; }
.afs__forslag-af { font-size: 0.74rem; color: var(--faint); margin-top: 0.1rem; }
.afs__forslag-knap { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.45rem; }

/* Periodevaelger i sidehovedet. */
.dm-periode { display: inline-flex; gap: 0.15rem; background: color-mix(in srgb, var(--ink) 5%, transparent); border-radius: 999px; padding: 0.15rem; }
.dm-periode__k { border: 0; background: transparent; font-size: 0.76rem; font-weight: 700; color: var(--muted); border-radius: 999px; padding: 0.25rem 0.6rem; cursor: pointer; }
.dm-periode__k:hover { color: var(--ink); }
.dm-periode__k.er-valgt { background: var(--paper); color: var(--ink); box-shadow: var(--shadow-xs); }

/* SPF-analysen: hvad koster recorden, og hvad bliver ikke brugt. */
.dm-spf__raad { font-size: 0.86rem; color: var(--ink-2); line-height: 1.55; padding: 0.2rem 0 0.8rem; }

/* ── Dmarc: svaret oeverst, resten bag faner ──────────────────────────────
   Siden voksede ét panel ad gangen og endte med ni sektioner under hinanden.
   Rettelsen er ikke faerre oplysninger, men at de tre spoergsmaal — "er vi i
   maal?", "hvem sender?" og "vis mig linjen" — ikke laengere staar blandet. */
.dmh {
    display: flex; flex-wrap: wrap; gap: 1rem 2rem; align-items: center; justify-content: space-between;
    background: var(--paper); border: 1px solid var(--line); border-left: 4px solid var(--line-2);
    border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
    padding: 1.1rem 1.3rem; margin-bottom: 0.9rem;
}
.dmh--ok { border-left-color: var(--good); }
.dmh--klar { border-left-color: var(--good); }
.dmh--blok { border-left-color: var(--warn); }

.dmh__label { font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.dmh__svar { font-size: 1.24rem; font-weight: 800; color: var(--ink); line-height: 1.25; margin: 0.15rem 0 0.5rem; max-width: 34rem; }

.dmh__trin { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; }
.dmh__t {
    font-size: 0.7rem; font-weight: 800; border-radius: 999px; padding: 0.14rem 0.5rem;
    color: var(--faint); background: color-mix(in srgb, var(--ink) 5%, transparent);
}
.dmh__t.er-naaet { color: var(--good); background: var(--good-bg); }
.dmh__t.er-naeste { color: var(--ink); background: var(--clay-200); }
.dmh__klar { font-size: 0.76rem; font-weight: 700; color: var(--good); margin-left: 0.25rem; }
.dmh__blok { font-size: 0.76rem; font-weight: 700; color: var(--warn); margin-left: 0.25rem; }

.dmh__tal { display: flex; flex-wrap: wrap; gap: 1.4rem; }
.dmh__n { display: flex; flex-direction: column; }
.dmh__n > b { font-size: 1.3rem; font-weight: 800; line-height: 1.1; color: var(--ink); font-variant-numeric: tabular-nums; }
.dmh__n > span { font-size: 0.72rem; color: var(--muted); }

.txt-good { color: var(--good); }

/* Faner. Trykmaal paa 44 px hoejde ligger inden for det, mobilreglerne kraever. */
.dmfaner { display: flex; gap: 0.25rem; border-bottom: 1px solid var(--line); margin-bottom: 0.9rem; }
.dmfaner__f {
    border: 0; background: transparent; cursor: pointer;
    font-size: 0.88rem; font-weight: 700; color: var(--muted);
    padding: 0.6rem 0.9rem; border-bottom: 2px solid transparent; margin-bottom: -1px;
    display: inline-flex; align-items: center; gap: 0.4rem; min-height: 44px;
}
.dmfaner__f:hover { color: var(--ink); }
.dmfaner__f.er-valgt { color: var(--ink); border-bottom-color: var(--ink); }
.dmfaner__n {
    font-size: 0.68rem; font-weight: 800; border-radius: 999px; padding: 0.05rem 0.4rem;
    background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink-2);
}
.dmfaner__f.er-valgt .dmfaner__n { background: var(--clay-200); }

/* Filterchips i stedet for syv sektioner under hinanden. */
.afsfilter { display: flex; flex-wrap: wrap; gap: 0.35rem; padding: 0.2rem 0 0.9rem; }
.afsfilter__k {
    border: 1px solid var(--line-2); background: var(--paper); cursor: pointer;
    font-size: 0.78rem; font-weight: 700; color: var(--ink-2);
    border-radius: 999px; padding: 0.28rem 0.7rem;
    display: inline-flex; align-items: center; gap: 0.35rem;
}
.afsfilter__k:hover { border-color: var(--ink-2); }
.afsfilter__k.er-valgt { background: var(--ink); border-color: var(--ink); color: #fff; }
.afsfilter__n { font-size: 0.7rem; opacity: 0.75; }

@media (max-width: 720px), (pointer: coarse) {
    .dmh { padding: 0.9rem 1rem; }
    .dmh__svar { font-size: 1.08rem; }
    .dmh__tal { gap: 1rem; }
    .afsfilter__k { min-height: 36px; }
}

/* Politik pr. domaene i heroen. Vurderingen bygger paa det svageste domaene —
   uden at det staar her, ligner det en fejl, naar kunden ved at hoveddomaenet
   for laengst er paa reject. */
.dmh__dom { display: flex; flex-wrap: wrap; gap: 0.35rem 0.8rem; margin-top: 0.5rem; font-size: 0.74rem; color: var(--muted); }
.dmh__d > b { color: var(--ink-2); font-weight: 800; }
.dmh__d.er-ok > b { color: var(--good); }
.dmh__d.er-fejl > b { color: var(--crit); }

/* Planlagte koersler: platformens eget arbejde. */
.krs__navn { font-weight: 700; font-size: 0.88rem; }
.krs__hvad { font-size: 0.76rem; color: var(--muted); margin-top: 0.1rem; max-width: 34rem; }
.krs__bagud { font-size: 0.74rem; color: var(--crit); font-weight: 700; margin-top: 0.2rem; }
.krs__fejl { font-size: 0.76rem; color: var(--crit-ink); margin-top: 0.2rem; max-width: 34rem; }
.krs__fejl a { color: inherit; text-decoration: underline; }

/* Lyd til/fra i notifikationspanelet */

.notif__lyd {
    display: inline-grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--navy-800);
    cursor: pointer;
}

.notif__lyd:hover { background: var(--blue-50); }

/* Slået fra: dæmpet, men stadig over kontrastkravet for et betjeningselement. */
.notif__lyd--fra { color: var(--ink-2); }

.notif__lyd:focus-visible {
    outline: 2px solid var(--navy-800);
    outline-offset: 1px;
}

/* Sagens sidepanel på en telefon.
   ========================================================================== */

/* To og to. Seks felter under hinanden er seks skærmfulde at rulle forbi; parvis er det tre
   rækker, og status og prioritet kan læses i ét blik.

   Det argument stod skrevet og godkendt her — men kun bag @media (max-width: 640px), altså kun
   på en telefon. Det gælder ordret på en computer: seks felter under hinanden er seks felter
   under hinanden, uanset hvor bred skærmen er, og sidepanelet fyldte ~620 px af en side, hvor
   sagens egen tekst skal kunne læses ved siden af. Løftet ud 1. september 2026. */
.tkt-sidepanel .panel {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 0.7rem;
    align-items: start;
}

/* Overskriften og tidsstemplerne skal stadig have hele bredden. */
.tkt-sidepanel .panel__title,
.tkt-sidepanel .panel > .alert,
.tkt-sidepanel .stat__meta { grid-column: 1 / -1; }

.tkt-sidepanel .fld { margin-bottom: 0.6rem; }

/* Kontaktpersonens navn kan være langt, og en rulleliste, der presses ned i halv bredde, viser
   kun de første par bogstaver. Den får rækken for sig selv. */
.tkt-sidepanel .fld:last-of-type { grid-column: 1 / -1; }

@media (max-width: 640px) {
    /* Op over forløbet. Bento er et grid, så rækkefølgen kan vendes uden at røre
       markuppen — og uden at ændre den på en computer, hvor panelet står i sin
       egen spalte og altid er synligt. */
    .tkt-sidepanel { order: -1; }
}

/* Genåbningstælleren på en sag. Skiller sig ud fra de øvrige tidsstempler, fordi
   den er den ene linje, der siger «her gik noget ikke som planlagt». */
.tkt-genaabnet {
    margin-top: 0.5rem;
    padding: 0.3rem 0.5rem;
    border-radius: 8px;
    background: var(--warn-bg);
    color: var(--ink-2);
    font-weight: 700;
}

/* Lukket uden løsning. Rød-tonet, ikke gul: det er ikke en advarsel om noget
   fremtidigt, men en oplysning om noget, der endte anderledes end planlagt. */
.tkt-lukket {
    margin-top: 0.6rem;
    padding: 0.45rem 0.6rem;
    border-radius: 8px;
    background: var(--crit-bg);
    color: var(--ink-2);
    font-weight: 700;
}

.tkt-lukket__note {
    margin-top: 0.25rem;
    font-weight: 400;
    white-space: pre-wrap;
}

/* Beskeden over svarfeltet på en lukket sag: her kan kun skrives internt. */
.reply__laast {
    margin-bottom: 0.6rem;
    padding: 0.5rem 0.7rem;
    border-radius: 10px;
    background: var(--blue-50);
    color: var(--ink-2);
    font-size: 0.85rem;
    line-height: 1.45;
}

/* Brugermenu i topbaren. Log ud ligger heri frem for som løs knap ved siden af
   burgermenuen, hvor et fejlklik loggede folk af uden fortrydelse (sag #1018). */

.brugermenu { position: relative; }

.brugermenu__knap {
    border: 0;
    cursor: pointer;
    font: inherit;
    color: inherit;
    gap: 0.55rem;
}

.brugermenu__knap:hover { background: rgba(255, 255, 255, 0.95); }

.brugermenu__knap:focus-visible {
    outline: 2px solid var(--navy-800);
    outline-offset: 2px;
}

/* Fanger klik uden for menuen. Under panelet, over alt andet. */
.brugermenu__baggrund {
    position: fixed;
    inset: 0;
    z-index: 950;
}

.brugermenu__panel {
    position: absolute;
    top: calc(100% + 0.5rem);
    right: 0;
    z-index: 951;
    min-width: 220px;
    padding: 0.35rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    box-shadow: 0 18px 40px -18px rgba(22, 32, 46, 0.45);
}

.brugermenu__form { margin: 0; }

.brugermenu__punkt {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.55rem 0.7rem;
    border: 0;
    border-radius: 8px;
    background: none;
    color: var(--ink);
    font-size: 0.88rem;
    text-align: left;
    text-decoration: none;
    cursor: pointer;

    /* 40 px trykmål, samme som resten af mobilvisningen. */
    min-height: 40px;
}

.brugermenu__punkt:hover { background: var(--blue-50); color: var(--ink); }

/* Log ud adskilt fra resten: det er den ene handling, man ikke vil ramme ved et uheld. */
.brugermenu__punkt--ud {
    margin-top: 0.35rem;
    border-top: 1px solid var(--line);
    border-radius: 0 0 8px 8px;
    color: var(--crit-ink);
}

.brugermenu__punkt--ud:hover { background: var(--crit-bg); color: var(--crit-ink); }

/* Plads til den svævende «Registrér tid».
   ==========================================================================

   Knappen er fast i nederste højre hjørne og dækker de nederste ~56 px af skærmen.
   Indholdet havde 32 px bundpolstring på mobil, så det sidste af siden lå under
   knappen, uanset hvor langt man rullede. Meldt ind som sag #1019.

   4rem (64 px) rydder knappen på ~56 px med lidt luft. Var før 6rem, men det efterlod
   et unødigt bånd tomt hvidt rum, man kunne rulle ned i, når indholdet næsten fyldte
   skærmen. Polstringen står til sidst i filen med vilje: den skal vinde over alle
   skærmstørrelses-reglerne ovenfor, som hver især sætter deres egen bund. */
.app__content { padding-bottom: 4rem; }

@media (max-width: 640px) {
    /* Lidt mere på telefonen: der er knappen forholdsvis større, og der er ingen
       plads i siden at læse det dækkede indhold fra. */
    .app__content { padding-bottom: 6.5rem; }
}

/* Forslag fra sprogmodellen.
   ==========================================================================

   Tonet anderledes end resten af formularen med vilje: det er et bud, ikke en
   værdi. Man skal kunne se forskel på «sådan er det» og «sådan tror en maskine
   det er» uden at læse teksten. */
.aiforslag {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin: -0.35rem 0 0.9rem;
    padding: 0.45rem 0.6rem;
    border: 1px dashed var(--line);
    border-radius: 10px;
    background: var(--blue-50);
}

.aiforslag__tekst {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    color: var(--ink-2);
}

.aiforslag__fejl {
    flex-basis: 100%;
    font-size: 0.8rem;
    color: var(--crit-ink);
}

/* «Sådan finder du derhen» under et konfigurationspunkt. Dæmpet, fordi det er en
   vejviser og ikke et fund — men stort nok til at kunne læses højt i telefonen. */
.konfig__sti {
    margin-top: 0.3rem;
    font-size: 0.8rem;
    white-space: normal;
}

.konfig__sti a {
    display: inline-flex;
    align-items: baseline;
    gap: 0.3rem;
    color: var(--ink-2);
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}

.konfig__sti a:hover { color: var(--blue-600, var(--ink)); }

.konfig__berørte {
    list-style: none;
    margin: 0.3rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    white-space: normal;
}

.konfig__berørte a {
    color: var(--ink-2);
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}

.konfig__berørte a:hover { color: var(--blue-600, var(--ink)); }

/* Maskinskrevet referat over sagsteksten.
   Stiplet kant og samme blå som forslagsstriben, så «det her er modellens ord»
   er den samme visuelle besked overalt i platformen. Den venstre streg gør den
   til et citat frem for til indholdet. */
.airesume {
    margin: 0 0 0.9rem;
    padding: 0.55rem 0.75rem;
    border: 1px dashed var(--line);
    border-left: 3px solid var(--blue-300, var(--line));
    border-radius: 10px;
    background: var(--blue-50);
}

.airesume__mærke {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ink-3, var(--ink-2));
    margin-bottom: 0.3rem;
}

/* Svarudkast over svarfeltet. Samme sprog som resuméet — stiplet kant, blå
   venstrestreg — så «det her er modellens ord» ser ens ud overalt. */
.aiudkast {
    margin: 0 0 0.6rem;
    padding: 0.6rem 0.75rem;
    border: 1px dashed var(--line);
    border-left: 3px solid var(--blue-300, var(--line));
    border-radius: 10px;
    background: var(--blue-50);
}

.aiudkast__mærke {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ink-3, var(--ink-2));
    margin-bottom: 0.35rem;
}

.aiudkast__tekst {
    margin: 0 0 0.5rem;
    font-size: 0.9rem;
    line-height: 1.5;
    white-space: pre-wrap;
    color: var(--ink-1, var(--ink-2));
}

.aiudkast__knapper {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.aimangler {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 0.9rem;
    line-height: 1.5;
}

/* Punkttegnet sættes her frem for af modellen. Så ser listen ens ud, uanset om
   modellen huskede at lade være med at skrive en bindestreg foran — og koden
   fjerner den slags i forvejen, netop for at kunne bestemme det her. */
.aimangler li::before {
    content: "· ";
    color: var(--ink-3, var(--ink-2));
    font-weight: 700;
}

.airesume__tekst {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--ink-1, var(--ink-2));
}

/* Vaerktoejslinjen over fundlisten paa Netvaerksscan: soegning, markering, eksport.
   Wrapper paa smal skaerm frem for at skubbe eksportknappen ud af billedet — den
   sidder yderst til hoejre og ville ellers vaere den foerste, der forsvandt. */
.scanværktøj {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.7rem;
}

.scanværktøj__søg {
    flex: 1 1 18rem;
    max-width: 26rem;
}

/* ms-auto virker ikke, naar raekken wrapper — knappen ville lande alene paa en linje
   med al pladsen foran sig. Under wrap-graensen slaas den fra. */
@media (max-width: 42rem) {
    .scanværktøj .ms-auto {
        margin-left: 0 !important;
    }
}

/* Slip-felt i dokumentbiblioteket.

   Filfeltet ligger gennemsigtigt hen over hele feltet frem for at vaere en
   haandrullet drop-zone i JavaScript. Browseren fyrer selv change, naar filer
   slippes paa et filfelt, saa klik og slip virker med den samme kode — og
   tastaturbrugere kan tabbe til det. En egen implementering ville skulle holde
   styr paa dragleave over indlejrede elementer og kunne klikkes forbi. */
.slip {
    position: relative;
    border: 2px dashed var(--line-2, #cbd5e1);
    border-radius: 10px;
    padding: 1.1rem;
    margin-bottom: 1rem;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.slip--sigtet {
    border-color: var(--blue-400, #3b82f6);
    background: var(--blue-50);
}

.slip--arbejder {
    border-style: solid;
    opacity: 0.75;
}

.slip__felt {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.slip__felt:disabled {
    cursor: default;
}

/* Fokusringen sidder paa det usynlige felt og ville ikke kunne ses. Den flyttes
   derfor ud paa rammen, saa man kan se hvor man er, naar man tabber rundt. */
.slip:has(.slip__felt:focus-visible) {
    border-color: var(--blue-400, #3b82f6);
    box-shadow: 0 0 0 3px var(--blue-100, rgba(59, 130, 246, 0.25));
}

.slip__indhold {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    color: var(--ink-2, #64748b);
    font-size: 0.9rem;
    pointer-events: none;
}

/* Mappekort som drop-maal. Feltet indsaettes foerst ved traek — laa det der
   altid, ville det spise klikket, og mappen kunne ikke aabnes. */
.fcard--sigtet {
    outline: 2px solid var(--blue-400, #3b82f6);
    outline-offset: 2px;
}

.fcard__slip {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: copy;
}

.fcard {
    position: relative;
}

/* Hjaelpetekst inde i en label maa ikke arve dens versaler.

   .fld label saetter text-transform: uppercase, hvilket er rigtigt for et kort
   feltnavn som «E-MAIL». Laegger man en hel saetning i samme label — fx forklaringen
   under et flueben — bliver den ogsaa til versaler, og en saetning i versaler raaber
   ad laeseren. */
.fld label .fld__hint {
    text-transform: none;
    letter-spacing: normal;
    font-weight: 400;
}

/* Vidensbase: læsevisning af en artikel. Indholdet er renderet fra Markdown til et sikkert
   HTML-subset (KnowledgebaseMarkdown), så det er almindelige elementer der styles her — ikke
   Blazor-scoped CSS, som ikke når MarkupString-indhold. */
.kb-article {
    max-width: 70ch;
    color: var(--ink-2);
    line-height: 1.65;
}
.kb-article h2, .kb-article h3, .kb-article h4, .kb-article h5, .kb-article h6 {
    color: var(--ink);
    font-weight: 700;
    line-height: 1.3;
    margin: 1.6rem 0 0.6rem;
}
.kb-article h2 { font-size: 1.25rem; }
.kb-article h3 { font-size: 1.1rem; }
.kb-article h4, .kb-article h5, .kb-article h6 { font-size: 1rem; }
.kb-article > :first-child { margin-top: 0; }
.kb-article p { margin: 0 0 0.9rem; }
.kb-article ul, .kb-article ol { margin: 0 0 0.9rem 1.4rem; }
.kb-article li { margin: 0.2rem 0; }
.kb-article a { color: var(--navy-800); text-decoration: underline; }
.kb-article code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.88em;
    background: var(--blue-100);
    color: var(--navy-800);
    padding: 0.1rem 0.35rem;
    border-radius: 4px;
}
.kb-article pre {
    background: var(--blue-100);
    border-radius: 8px;
    padding: 0.9rem 1rem;
    overflow-x: auto;
    margin: 0 0 0.9rem;
}
.kb-article pre code { background: none; padding: 0; }
.kb-article blockquote {
    margin: 0 0 0.9rem;
    padding: 0.2rem 0 0.2rem 1rem;
    border-left: 3px solid var(--blue-100);
    color: var(--ink-2);
}
.kb-article hr { border: 0; border-top: 1px solid var(--blue-100); margin: 1.4rem 0; }

/* Tabeller. Ombryderen er ikke pynt: en tabel med fem kolonner er bredere end en telefon, og
   uden en flade der selv kan rulle, skubber den hele siden sidelæns. */
.kb-tabel { overflow-x: auto; margin: 0 0 1rem; }
.kb-article .kb-tabel { max-width: 100%; }
.kb-article table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.94rem;
}
.kb-article th, .kb-article td {
    border-bottom: 1px solid var(--blue-100);
    padding: 0.5rem 0.7rem;
    text-align: left;
    vertical-align: top;
}
.kb-article th {
    color: var(--ink);
    font-weight: 700;
    white-space: nowrap;
    border-bottom-width: 2px;
}
.kb-article tbody tr:last-child td { border-bottom: 0; }
/* Tal skal kunne sammenlignes lodret — cifrene skal stå i kolonne, også i en proportional skrift. */
.kb-article td[style*="right"], .kb-article th[style*="right"] { font-variant-numeric: tabular-nums; }

/* Afkrydsningslister. Feltet er låst med vilje — en artikel gemmer ikke noget, og et felt der
   kan klikkes uden at noget sker, lover mere end det holder. Markøren siger det samme. */
.kb-article ul:has(> .kb-opgave) { list-style: none; margin-left: 0; }
.kb-article .kb-opgave { display: flex; align-items: flex-start; gap: 0.5rem; }
.kb-article .kb-opgave input {
    margin: 0.35rem 0 0;
    flex: none;
    cursor: default;
    accent-color: var(--navy-800);
}

/* Billeder må aldrig kunne blive bredere end spalten. */
.kb-article img {
    max-width: 100%;
    height: auto;
    border-radius: 8px;
    margin: 0.3rem 0;
}

.kb-article del { color: var(--ink-3, var(--ink-2)); }

/* ---- NIS2-parathed ------------------------------------------------------ */

.nis-list { display: grid; gap: 0.7rem; margin-top: 0.9rem; }

.nis {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.7rem 0.9rem;
    align-items: start;
    padding: 0.85rem 0.95rem;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--paper);
}
.nis__mark { align-self: start; margin-top: 0.15rem; white-space: nowrap; }
.nis__main { min-width: 0; }
.nis__title {
    font-weight: 700;
    color: var(--ink);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.nis__desc { color: var(--muted); font-size: 0.9rem; margin-top: 0.2rem; line-height: 1.55; }
.nis__finding { color: var(--ink-2); font-size: 0.88rem; margin-top: 0.4rem; line-height: 1.5; }
.nis__evidence {
    display: inline-flex; align-items: center; gap: 0.35rem;
    color: var(--ink-2); font-size: 0.85rem; margin-top: 0.4rem;
}

/* Muted "Automatisk"-markør på lys flade — den hvide .chip-basis dur ikke på et hvidt panel. */
.chip--muted {
    background: var(--line);
    color: var(--muted);
    border-color: var(--line-2);
    backdrop-filter: none;
    padding: 0.16rem 0.55rem;
    font-size: 0.72rem;
    font-weight: 700;
}

.nis__actions { display: flex; gap: 0.5rem; margin-top: 0.6rem; }
.nis__editor {
    margin-top: 0.7rem;
    padding: 0.85rem;
    border: 1px solid var(--line-2);
    border-radius: var(--r-md);
    background: var(--blue-50);
    display: grid;
    gap: 0.6rem;
}
.nis__editor label { display: grid; gap: 0.25rem; font-size: 0.82rem; font-weight: 600; color: var(--ink-2); }
.nis__row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
@media (max-width: 640px) {
    .nis__row { grid-template-columns: 1fr; }
    .nis { grid-template-columns: 1fr; }
}

/* ---- GDPR-fortegnelse (RoPA) ------------------------------------------- */
.ropa-list { display: grid; gap: 1rem; }
.ropa__head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 0.8rem; flex-wrap: wrap; margin-bottom: 0.8rem;
}
.ropa__navn { font-weight: 800; color: var(--ink); font-size: 1.02rem; }
.ropa__meta { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.ropa__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem 1.4rem; }

.felt { min-width: 0; }
.felt--bred { grid-column: 1 / -1; }
.felt__etiket { font-size: 0.72rem; letter-spacing: 0.03em; text-transform: uppercase; color: var(--muted); font-weight: 700; }
.felt__vaerdi { color: var(--ink-2); font-size: 0.92rem; line-height: 1.5; white-space: pre-wrap; }
.felt__vaerdi--tom { color: var(--muted); }

/* Kom-i-gang-skabeloner */
.ropa-forslag { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 0.7rem; margin-top: 0.9rem; }
.ropa-forslag__k {
    display: grid; gap: 0.2rem; text-align: left; padding: 0.75rem 0.9rem;
    border: 1px solid var(--line-2); border-radius: var(--r-md); background: var(--blue-50); cursor: pointer;
    transition: box-shadow 0.13s ease, transform 0.13s ease;
}
.ropa-forslag__k:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.ropa-forslag__k:disabled { opacity: 0.6; cursor: default; transform: none; box-shadow: none; }
.ropa-forslag__navn { font-weight: 700; color: var(--ink); }
.ropa-forslag__hint { font-size: 0.82rem; color: var(--muted); line-height: 1.4; }
.ropa-forslag__plus { font-size: 0.78rem; font-weight: 700; color: var(--blue-500); }

/* Editor-form */
.ropa-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1rem; }
.ropa-check {
    display: flex; align-items: flex-start; gap: 0.5rem; margin-bottom: 1rem;
    font-size: 0.9rem; color: var(--ink-2); line-height: 1.4;
}
.ropa-check input { margin-top: 0.2rem; }

@media (max-width: 640px) {
    .ropa__grid, .ropa-form__row { grid-template-columns: 1fr; }
}

/* ---- Spørg platformen (AI-copilot) ------------------------------------ */
.kop-input { display: flex; gap: 0.6rem; align-items: flex-end; }
.kop-input textarea { flex: 1; resize: vertical; }
.kop-input .btn { flex-shrink: 0; }
.kop-forslag { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.8rem; }
.kop-sp { font-weight: 700; color: var(--ink); margin-bottom: 0.5rem; }
.kop-tekst { color: var(--ink-2); line-height: 1.65; white-space: pre-wrap; }
.kop-kilder { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin-top: 0.8rem; }
.kop-meta { margin-top: 0.6rem; }
.kop-taenker, .kop-tænker { display: flex; align-items: center; padding: 0.4rem 0; }
.kop-prik {
    width: 7px; height: 7px; border-radius: 999px; background: var(--blue-400);
    margin-right: 4px; display: inline-block; animation: kopblink 1.2s infinite ease-in-out both;
}
.kop-prik:nth-child(2) { animation-delay: 0.2s; }
.kop-prik:nth-child(3) { animation-delay: 0.4s; }
@keyframes kopblink { 0%, 80%, 100% { opacity: 0.25; } 40% { opacity: 1; } }

/* ---- Cockpit (Tillid & efterlevelse) ---------------------------------- */
.cockpit-narrativ { font-size: 1rem; line-height: 1.7; color: var(--ink-2); margin: 0.4rem 0 0; white-space: pre-wrap; }
.cockpit-tal { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.6rem 1.4rem; margin-top: 1rem; }

/* ---- NOC: mål-først «Tilføj overvågning» ------------------------------ */
/* Mål-vælgeren: klikbare kort i et responsivt gitter. Deler formsprog med
   panelerne (--paper/--line/--r-md/--shadow-sm), så de ikke ser fremmede ud. */
.goalgrid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 0.7rem;
    margin: 0.2rem 0 0.4rem;
}

.goalcard {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35rem;
    text-align: left;
    padding: 0.9rem 1rem;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--paper);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;
}

.goalcard:hover {
    border-color: var(--blue-400);
    box-shadow: 0 6px 18px rgba(19, 28, 40, 0.10);
    transform: translateY(-1px);
}

.goalcard:focus-visible { outline: 2px solid var(--blue-500); outline-offset: 2px; }

.goalcard__icon {
    display: inline-flex;
    width: 2.2rem;
    height: 2.2rem;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--line);
    color: var(--ink-2);
}

.goalcard__title { font-weight: 700; color: var(--ink); line-height: 1.25; }
.goalcard__sub { font-size: 0.82rem; color: var(--muted); line-height: 1.35; }

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

/* Mål-linjen i formularen: viser det valgte mål med en diskret «Skift»-genvej,
   i stedet for den kolde 7-vejs type-dropdown. */
.goalline {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--paper);
}

.goalline__val { font-weight: 600; color: var(--ink); }
.goalline__change { font-size: 0.85rem; }

/* Tastemærket i topbarens søgefelt.
   Erstatter den flydende «Søg eller hop til…»-pille, der lå oven på indholdet i hjørnet og fyldte
   hele tiden for en genvej, man lærer én gang. Her koster den ingen plads og står, hvor man i
   forvejen kigger. Skjules på smalle skærme: der er der ingen tastatur, og så er mærket støj. */
.topsearch__kbd {
    flex-shrink: 0;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--faint);
    background: color-mix(in srgb, var(--ink) 5%, transparent);
    border: 1px solid var(--line);
    border-radius: 5px;
    padding: 0.1rem 0.36rem;
    white-space: nowrap;
}

@media (max-width: 900px) {
    .topsearch__kbd { display: none; }
}

/* ==========================================================================
   Problemgrupper på Domænesikkerhed
   --------------------------------------------------------------------------
   Fundene samlet efter PROBLEM frem for efter domæne. Arbejdet foregår sådan:
   man logger ind hos én DNS-udbyder og retter DMARC på fem domæner. Seksten
   domæner gange otte tjek er 128 felter at skimme; fire linjer er en dagsorden.
   Se Domaenedom for reglen bag rækkefølgen.
   ========================================================================== */

.probs { display: flex; flex-direction: column; gap: 0.55rem; }

.prob {
    border: 1px solid var(--line);
    border-radius: 10px;
    overflow: hidden;
    background: var(--paper);
}

/* Hele overskriften er knappen — ikke en lille pil i kanten. Rækken ER handlingen. */
.prob__head {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    padding: 0.8rem 1rem;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.prob__head:hover { background: var(--blue-50); }
.prob__head:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }

/* Alvoren som en kant i venstre side. Farve OG plads, så den kan ses uden at læse. */
.prob__sev {
    width: 3px;
    align-self: stretch;
    border-radius: 2px;
    background: var(--warn);
    flex-shrink: 0;
}

.prob--krit .prob__sev { background: var(--crit); }
.prob--tapet .prob__sev { background: var(--line-2); }

.prob__n {
    font-size: 1.3rem;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    min-width: 1.7rem;
    text-align: right;
    flex-shrink: 0;
}

.prob--krit .prob__n { color: var(--crit); }
.prob--tapet .prob__n { color: var(--muted); font-weight: 700; }

.prob__tekst { min-width: 0; flex: 1; }
.prob__t { font-weight: 700; display: block; }
.prob__d { font-size: 0.82rem; color: var(--muted); display: block; margin-top: 0.1rem; }

/* Mærkat for det, der gælder næsten alle. Se Domaenedom.TapetGrænse: et fund på 16 af 16
   er ikke seksten fund — det er en beslutning, vi ikke har truffet, og den skal ikke fylde
   som seksten. */
.prob__mrk {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.45rem;
    border: 1px solid var(--line-2);
    border-radius: 999px;
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    vertical-align: 0.1em;
}

.prob__pil {
    width: 7px; height: 7px;
    border-right: 1.5px solid var(--faint);
    border-bottom: 1.5px solid var(--faint);
    transform: rotate(-45deg);
    flex-shrink: 0;
    transition: transform 0.14s ease;
}

.prob__head[aria-expanded="true"] .prob__pil { transform: rotate(45deg); }

.prob__body {
    padding: 0.9rem 1rem 1rem 2.55rem;
    border-top: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.doms { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.dom {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    padding: 0.22rem 0.55rem;
    border: 1px solid var(--line-2);
    border-radius: 6px;
    background: var(--paper);
    color: var(--ink-2);
    cursor: pointer;
}

.dom:hover { border-color: var(--brass); color: var(--ink); }
.dom:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
.dom__kunde { font-family: var(--font); font-size: 0.7rem; color: var(--faint); }

/* Rettelsen. «SPF har 9 opslag» er en diagnose; posten, der skal stå, er et svar. */
.fix {
    background: var(--blue-50);
    border-radius: 8px;
    padding: 0.75rem 0.9rem;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.fix__t {
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--brass);
}

.fix__rec {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.78rem;
    line-height: 1.7;
    color: var(--ink);
    word-break: break-all;
}

.fix__note { font-size: 0.82rem; color: var(--muted); }

@media (max-width: 640px) {
    .prob__head { gap: 0.6rem; padding: 0.7rem 0.8rem; }
    .prob__body { padding-left: 0.8rem; }
    .prob__d { font-size: 0.78rem; }
}

/* ==========================================================================
   Grene i Driftsovervågning: årsagen og det, der står bag den
   --------------------------------------------------------------------------
   Da routeren gik ned, blev det til seks lige store kort: ét nede og fem «kan
   ikke måles». Det er ikke seks problemer — det er ét problem og fem
   konsekvenser. Børnene tegnes derfor som en indrykket, tæt liste og ikke som
   kort: de er ikke fund, man skal undersøge, men OMFANGET af det ene fund
   ovenover. Se Afhaengighedstrae for reglen.
   ========================================================================== */

.grenboern {
    display: flex;
    flex-direction: column;
    margin: -0.35rem 0 0.9rem 1.5rem;
    padding-left: 1rem;

    /* Stregen binder børnene til kortet ovenover. Indrykning alene ligner en
       sorteringsdetalje; stregen siger «de hænger fast i den». */
    border-left: 1px solid var(--line-2);
}

.grenbarn {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    flex-wrap: wrap;
    padding: 0.4rem 0 0.4rem 0.7rem;
    font-size: 0.82rem;
    position: relative;
}

.grenbarn + .grenbarn { border-top: 1px solid var(--line); }

/* Den lille vandrette streg ind til rækken — samme greb som et filtræ. */
.grenbarn::before {
    content: "";
    position: absolute;
    left: -1px;
    top: 1.05em;
    width: 0.55rem;
    border-top: 1px solid var(--line-2);
}

.grenbarn__navn { font-weight: 600; color: var(--ink-2); }

.grenbarn__adr {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.76rem;
    color: var(--muted);
}

/* Årsagen står på HVER række og ikke kun i overskriften: ruller man forbi
   kortet, skal rækken stadig kunne forklare sig selv. */
.grenbarn__aarsag { color: var(--faint); font-size: 0.76rem; margin-left: auto; }

.grenbarn--flere { color: var(--muted); font-size: 0.8rem; }
.grenbarn--flere .grenbarn__navne { color: var(--faint); font-size: 0.76rem; }

@media (max-width: 640px) {
    .grenboern { margin-left: 0.5rem; }
    .grenbarn__aarsag { margin-left: 0; width: 100%; }
}

/* ==========================================================================
   Døgnbåndet på Driftsovervågning
   --------------------------------------------------------------------------
   Pulsstriben findes pr. enhed. Båndet lægger dem oven på hinanden, fordi det
   interessante er, når FLERE striber knækker samme sted: tre enheder med hvert
   sit hak klokken 09.14 er ikke tre uheld, det er én hændelse. Se Driftsbaand.
   ========================================================================== */

.dbaand {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.85rem 1rem;
    margin-bottom: 1rem;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
}

.dbaand__hoved { display: flex; align-items: baseline; gap: 0.8rem; flex-wrap: wrap; }

.dbaand__titel {
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--faint);
}

.dbaand__mest { font-size: 0.78rem; color: var(--crit); font-weight: 600; margin-left: auto; }

.dbaand__spor { display: flex; gap: 1px; height: 14px; }

.dbaand__felt {
    flex: 1;
    min-width: 2px;
    border-radius: 1px;

    /* Roligt tegnes SVAGT og ikke grønt. Båndet findes for at vise hakkene; et døgn i fuld
       grøn ville råbe «alt er godt» hen over den ene halve time, hvor det ikke var. */
    background: var(--line-2);
    opacity: 0.55;
}

.dbaand__felt--ned { background: var(--crit); opacity: 1; }

.dbaand__akse {
    display: flex;
    justify-content: space-between;
    font-size: 0.66rem;
    color: var(--faint);
    font-variant-numeric: tabular-nums;
}

/* «Vis de N øvrige» under en foldet sektion. En knap og ikke et link: den gør noget på siden,
   den fører ingen steder hen. */
.epfold {
    display: block;
    width: 100%;
    margin-top: 0.5rem;
    padding: 0.55rem;
    border: 1px dashed var(--line-2);
    border-radius: 8px;
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
}

.epfold:hover { border-color: var(--brass); color: var(--ink-2); }
.epfold:focus-visible { outline: 2px solid var(--brass); outline-offset: 2px; }

/* Dommen over et domæne — ét ord i stedet for brøken «6/8».
   Brøken var sidens mest fremtrædende tal og det mest misvisende: den vejede DNSSEC lige så tungt
   som DMARC, så 4/8 kunne være fuldt beskyttet og 6/8 kunne lade hvem som helst sende fakturaer i
   kundens navn. Et ord kan ikke lægges sammen, sammenlignes eller jages. Se Domaenedom. */
.domdom {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
    font-weight: 700;
    white-space: nowrap;
    letter-spacing: 0.01em;
}

.domdom::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex-shrink: 0; }

.domdom--krit { color: var(--crit); }
.domdom--obs { color: var(--warn); }
.domdom--ok { color: var(--good); }
.domdom--ukendt { color: var(--faint); }
.domdom--ukendt::before { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }

/* Pulsstriben inde i den tætte række.
   Den lå før kun i kortet, man skulle folde ud — altså skjult bag et klik pr. enhed. Striben er
   det eneste på siden, der viser et FORLØB, og skjult er den ingenting værd: med den i rækken kan
   fyrre enheder skimmes for «hvem har haft hak i dag» i ét blik. */
.eprow__puls { display: flex; align-items: center; min-width: 0; }

.spark--mini {
    height: 14px;
    width: 100%;
    margin-bottom: 0;
    border-bottom: none;
    padding-bottom: 0;
}

.spark--mini .spark__bar { min-width: 1px; border-radius: 1px; }

@media (max-width: 900px) {
    /* Rækken folder til to linjer på små skærme, og der er ikke plads til striben. Den står
       stadig i kortet, man folder ud — det er ét klik, ikke en manglende oplysning. */
    .eprow__puls { display: none; }
}

/* Gruppeoverskrift inde i den tætte liste. Kundens EGNE grupper — «Hjemmeside», «Servere» —
   ikke tjektype: en gruppe er, hvad kunden selv har kaldt tingene, og det er den inddeling, man
   leder i. Vises kun, når der er mere end én. */
.eprows__grp {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 1rem 0.9rem 0.35rem;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--faint);
}

.eprows__grp:first-child { padding-top: 0.2rem; }
.eprows__grpantal { font-size: 0.68rem; letter-spacing: 0; font-weight: 700; color: var(--line-2); }

/* Hvad der er GALT på et domæne — ikke hvor galt.
   Rækken stod før med seks anonyme prikker plus et ord, der var det samme på alle rækker i
   sektionen. Prikkerne skulle afkodes med musen (og kunne slet ikke på en telefon), og ordet
   tilføjede ingenting under en overskrift, der sagde det samme. En kolonne, hvor hver celle siger
   det samme, er død plads. */
.dsp-row__fejl { flex: 1 1 34%; display: flex; flex-wrap: wrap; gap: 0.3rem; min-width: 0; justify-content: flex-end; }

.domfejl {
    font-size: 0.72rem;
    font-weight: 600;
    padding: 0.1rem 0.45rem;
    border-radius: 5px;
    white-space: nowrap;
    border: 1px solid transparent;
}

.domfejl--krit { color: var(--crit); background: color-mix(in srgb, var(--crit) 9%, transparent); }
.domfejl--obs { color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent); }
.domfejl--svag { color: var(--muted); border-color: var(--line-2); }
.domfejl--ok { color: var(--good); }

/* ── Hover-aflæsning på graferne (graf.js) ──────────────────────────────────────────────
   Boksen og trådkorset ligger på <body> og er position:fixed, fordi de skal kunne stå over
   en graf, Blazor gentegner en gang i sekundet. Ét sæt for hele siden, uanset hvor mange
   grafer der er åbne. Ingen pointer-events: de må aldrig spise den bevægelse, der styrer dem. */
.graf-streg {
    position: fixed;
    display: none;
    width: 1px;
    z-index: 1080;
    pointer-events: none;
    background: var(--ink-3);
    opacity: 0.55;
}

.graf-boks {
    position: fixed;
    display: none;
    z-index: 1081;
    pointer-events: none;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--line-2);
    border-radius: 0.4rem;
    background: var(--paper);
    box-shadow: var(--shadow-md);
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--ink);
    white-space: nowrap;
    /* Tal, der skifter en gang i sekundet, må ikke få boksen til at hoppe i bredden. */
    font-variant-numeric: tabular-nums;
}

.graf-boks__tid {
    color: var(--muted);
    font-size: 0.72rem;
    margin-bottom: 0.1rem;
}

.graf-boks__navn { color: var(--muted); }

/* «ikke målt» er ikke et tal og skal ikke se ud som et. */
.graf-boks__tom {
    color: var(--muted);
    font-style: normal;
}

/* Selve grafen: markér, at der er noget at pege på. */
[data-graf] { cursor: crosshair; }

/* Tidsaksen under en live-graf. Samme rolle som .chart__axis, men i live-panelernes
   mindre skriftstørrelse — de sidder inde i et kort, ikke på en side. */
.livegraf__akse {
    display: flex;
    justify-content: space-between;
    margin-top: 0.2rem;
    font-size: 0.7rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* ── Driftsovervågning på enheden (Enheder.razor) ───────────────────────────────────────
   En enhed er én række, man kan folde ud. Sensorerne ligger indeni, og kanalerne under dem.
   Rækken skal kunne læses på ét blik i en liste på hundrede: prik, navn, hvad der måles,
   puls, tilstand — i den rækkefølge, fordi det er den rækkefølge, øjet spørger i. */
.dstatus {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.dstatus__line {
    font-size: 1.05rem;
    font-weight: 600;
}

.dstatus__dot {
    width: 0.7rem;
    height: 0.7rem;
    border-radius: 50%;
    flex: 0 0 auto;
}

.dstatus__dot--ok { background: var(--good); }
.dstatus__dot--obs { background: var(--warn); }

.denhed {
    border-top: 1px solid var(--line);
}

.denhed:first-of-type { border-top: 0; }

/* Kun det, der KRÆVER noget, får en kant. Grøn skal være usynlig — en markering på hver
   række er det samme som ingen markering. */
.denhed--obs { box-shadow: inset 3px 0 0 var(--warn); }

.denhed__hoved {
    display: grid;
    grid-template-columns: 1rem 0.7rem minmax(9rem, 1.5fr) minmax(0, 1.3fr) 4.5rem auto 7rem;
    align-items: center;
    gap: 0.7rem;
    width: 100%;
    padding: 0.6rem 0.4rem;
    background: none;
    border: 0;
    text-align: left;
    color: inherit;
    cursor: pointer;
    font: inherit;
}

.denhed__hoved:hover { background: color-mix(in srgb, var(--ink) 3%, transparent); }
.denhed__hoved:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }

.denhed__pil {
    color: var(--muted);
    font-size: 0.8rem;
}

.denhed__navn { min-width: 0; }

.denhed__sensorer,
.denhed__tilstand {
    color: var(--muted);
    font-size: 0.82rem;
}

.denhed__tilstand {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.dprik {
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    display: inline-block;
    flex: 0 0 auto;
}

.dprik--ok { background: var(--good); }
.dprik--obs { background: var(--warn); }
.dprik--nede { background: var(--crit); }
.dprik--krit { background: var(--crit); }

/* «Ukendt» og «delvis» er ikke grønne og ikke røde. De er huller, og et hul skal ses som et hul
   — en grøn prik over noget, vi ikke har målt, er husets værste fejl i prikform. */
.dprik--ukendt {
    background: repeating-linear-gradient(45deg, var(--muted) 0 2px, transparent 2px 4px);
    border: 1px solid var(--muted);
}

.dprik--delvis {
    background: var(--good);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--warn) 60%, transparent);
}

.spark--lille {
    height: 1.1rem;
    min-width: 6rem;
    gap: 1px;
}

.denhed__krop {
    padding: 0.2rem 0.4rem 0.9rem 2.4rem;
}

.dsensor {
    border-left: 2px solid var(--line-2);
    padding: 0.45rem 0 0.45rem 0.7rem;
    margin-bottom: 0.4rem;
}

.dsensor__hoved {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    flex-wrap: wrap;
}

.dsensor__vaerdi {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

.dsensor__fejl {
    color: var(--crit-ink, var(--crit));
    font-size: 0.8rem;
    margin-top: 0.25rem;
}

.dmaerke {
    font-size: 0.7rem;
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
    border: 1px solid var(--line-2);
    color: var(--muted);
}

/* Kanalerne: to kolonner, navn til venstre og tal til højre, så de kan læses lodret.
   Tabular-nums, fordi et tal, der skifter en gang i minuttet, ikke må rykke i kolonnen. */
.dkanaler {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
    gap: 0.1rem 1.5rem;
    margin-top: 0.4rem;
}

.dkanal {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 4.5rem auto;
    align-items: center;
    gap: 0.6rem;
    font-size: 0.82rem;
    padding: 0.12rem 0;
    border-bottom: 1px dotted var(--line);
}

.dkanal__navn { color: var(--muted); }

.dkanal__vaerdi { font-variant-numeric: tabular-nums; }

.dkanal__vaerdi--obs {
    color: var(--warn);
    font-weight: 600;
}

.denhed__handlinger {
    margin-top: 0.5rem;
    padding-top: 0.4rem;
    border-top: 1px dotted var(--line);
}

@media (max-width: 780px) {
    .denhed__hoved {
        grid-template-columns: 1rem 0.7rem 1fr auto;
        row-gap: 0.2rem;
    }

    /* Linje 1: navnet og tilstandsordet.
       Tilstanden faldt før igennem til en linje for sig selv og landede i PILENS kolonne — 16 px
       til «svarer ikke», som så flød ud over sin boks, fordi sporet ikke kunne rumme den. Det er
       det ene ord på rækken, der skal kunne læses. */
    .denhed__tilstand { grid-column: 4; text-align: right; }

    /* Linje 2: sensorerne og tallet — hvor længe den ikke har svaret, eller hvor hurtigt den gør. */
    .denhed__sensorer { grid-column: 3; }
    .denhed__ms { grid-column: 4; display: block; text-align: right; }

    /* Linje 3: 2-timers-striben i fuld bredde.
       Den var skjult her. Men den er det eneste på rækken, der viser FLAPNING — en enhed, der ikke
       er nede nu, men har været det tre gange i dag — og en overvågningsside læses netop på en
       telefon om aftenen. Rækken vokser fra 89 til 115 px; det er prisen for oplysningen. */
    .spark--lille { grid-column: 3 / -1; display: flex; }

    .denhed__krop { padding-left: 1rem; }

    /* Værktøjslinjen brød ikke, og «Gem visning» endte på x=385 i et panel, der slutter ved 361 —
       uden for sin egen ramme og uden for rækkevidde. Målt på en 375 px-telefon den 13. september
       2026. Søgefeltet får sin egen linje, så fluebenet og knappen får plads under det. */
    .dvaerktoej { flex-wrap: wrap; }
    .dvaerktoej .dsoeg { flex: 1 1 100%; }
}

.dafsnit {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    margin: 1.4rem 0 0.5rem;
    font-weight: 600;
}

.dafsnit:first-of-type { margin-top: 0; }

.dmaerke--obs {
    color: var(--warn);
    border-color: color-mix(in srgb, var(--warn) 45%, transparent);
}

.dsensor__live { padding-left: 0; }

.denhed__ms {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--muted);
    font-size: 0.82rem;
}

.denhed__sensorer {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
}

.denhed__sensorer > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* «Kendes også af» — de andre moduler, der kender den samme maskine. En oplysning om enheden,
   ikke et modul for sig; derfor står den nederst i udfoldningen og ikke øverst. */
.dkendt {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.3rem 0.8rem;
    margin-top: 0.6rem;
    padding-top: 0.5rem;
    border-top: 1px dotted var(--line);
    font-size: 0.8rem;
}

.dkendt__mrk {
    color: var(--muted);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.dkendt__link { text-decoration: none; }
.dkendt__link:hover { text-decoration: underline; }

/* Forslaget i «Tilføj enhed». Fluebenene skal se ud som beslutninger, ikke som en formular:
   én linje pr. ting, med begrundelsen ovenover og ikke gemt i et værktøjstip. */
.dforslag {
    margin-top: 1rem;
    padding: 0.8rem 0.9rem;
    border: 1px solid var(--line-2);
    border-radius: 0.5rem;
    background: color-mix(in srgb, var(--good) 5%, transparent);
}

.dforslag__hoved {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--muted);
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.dforslag__valg {
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    padding: 0.3rem 0;
    cursor: pointer;
}

.dforslag__valg input { margin-top: 0.15rem; }

/* Søgning og «kun det, der er galt». Står i statuslinjen og ikke i en værktøjslinje for sig:
   de to hører til det, siden lige har sagt, og en linje mere ville koste plads uden at give noget. */
.dstatus__tekst { flex: 1 1 auto; min-width: 0; }

.dvaerktoej {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    flex: 0 0 auto;
}

.dsoeg { width: 15rem; max-width: 40vw; }

.dkun {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.82rem;
    color: var(--ink-2);
    white-space: nowrap;
    cursor: pointer;
}

@media (max-width: 780px) {
    .dstatus { flex-wrap: wrap; }
    .dvaerktoej { width: 100%; margin-top: 0.6rem; }
    .dsoeg { flex: 1 1 auto; max-width: none; width: auto; }
}

/* Kurven bag hvert kanaltal. Dæmpet med vilje: den er en BAGGRUND for tallet, ikke en graf i
   sig selv — bliver den lige så tydelig som værdien, kæmper de om øjet, og listen bliver til
   femten diagrammer i stedet for femten aflæsninger. */
.dkanal__kurve {
    width: 4.5rem;
    height: 1.1rem;
    display: block;
    color: var(--muted);
    opacity: 0.65;
}

.dkanal:hover .dkanal__kurve {
    opacity: 1;
    color: var(--brand);
}

/* Kanaler uden kurve — tekstmålinger som «Beskrivelse» — skal ikke få tallet til at hoppe
   ud i en anden kolonne end naboens. Den tomme plads holdes. */
.dkanal > .dkanal__vaerdi:nth-child(2) { grid-column: 3; }

@media (max-width: 780px) {
    .dkanal { grid-template-columns: minmax(0, 1fr) auto; }
    .dkanal__kurve { display: none; }
}

/* Oppetiden i udfoldningen. Tallet stort nok til at læses, teksten under lille nok til ikke at
   konkurrere — og «hvor langt vi har kigget» står altid med, så procenten ikke lover mere end
   den dækker. */
.dopptid {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-top: 0.6rem;
    padding-top: 0.5rem;
    border-top: 1px dotted var(--line);
}

.dopptid__tal {
    font-size: 1.05rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.dmaerke--kvit {
    color: var(--good);
    border-color: color-mix(in srgb, var(--good) 45%, transparent);
}

/* «Det, vi ikke måler lige nu». Gul og ikke rød: det er ikke et nedbrud, det er en blind vinkel
   — og de to skal ikke se ens ud, for de kræver hver sin handling. */
.dhuller { border-left: 3px solid var(--warn); }

.dhuller__liste {
    margin: 0;
    padding-left: 1.1rem;
    font-size: 0.86rem;
    color: var(--ink-2);
}

.dhuller__liste li { padding: 0.12rem 0; }

/* Et tal, der lige har ændret sig. Kort og dæmpet: markeringen skal kunne fanges i øjenkrogen
   på en side, man har stående åben — ikke kræve opmærksomhed som en advarsel. */
@keyframes drift-nyt-blink {
    0%   { background: color-mix(in srgb, var(--brand) 26%, transparent); }
    100% { background: transparent; }
}

.drift-nyt {
    animation: drift-nyt-blink 1.6s ease-out;
    border-radius: 0.2rem;
}

/* En række, der bliver til et problem, glider ind. Den, der har siden stående åben, skal kunne
   se, at der KOM noget — ikke bare at listen ser anderledes ud end sidst man kiggede. */
@keyframes drift-ind {
    from { opacity: 0; transform: translateY(-0.35rem); }
    to   { opacity: 1; transform: none; }
}

.denhed--obs { animation: drift-ind 0.35s ease-out; }

/* Tastaturvalget skal kunne ses tydeligt — ellers er j/k en genvej, man taber undervejs. */
.denhed__hoved:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: -2px;
    background: color-mix(in srgb, var(--brand) 7%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    .drift-nyt, .denhed--obs { animation: none; }
}

/* Portlisten i forslaget. Rulbar, fordi en 48-ports switch ellers skubber knapperne ud af
   dialogen — og den, der ikke kan se «Opret», tror at der mangler noget. */
.dporte {
    margin-top: 0.7rem;
    padding-top: 0.6rem;
    border-top: 1px dotted var(--line-2);
    max-height: 15rem;
    overflow-y: auto;
}

.dporte__hoved {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 600;
    margin-bottom: 0.3rem;
    position: sticky;
    top: 0;
    background: var(--paper);
}

.dport {
    display: grid;
    grid-template-columns: 1.1rem minmax(0, 1fr) 5rem 3rem;
    align-items: center;
    gap: 0.4rem;
    padding: 0.15rem 0;
    font-size: 0.82rem;
    cursor: pointer;
}

.dport__navn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.dport__fart {
    text-align: right;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.dport__op {
    text-align: right;
    color: var(--muted);
    font-size: 0.75rem;
}

/* «Derfor er den markeret». Står før navne- og gruppefelterne, fordi det er det første spørgsmål —
   og fordi et svar, man skal rulle ned til, er et svar, folk holder op med at lede efter.
   (Sensorlisten står stadig over den; «øverst i udfoldningen» er den altså ikke.) */
.dgrund {
    margin-bottom: 0.6rem;
    padding: 0.5rem 0.7rem;
    border-radius: 0.4rem;
    background: color-mix(in srgb, var(--warn) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--warn) 28%, transparent);
    font-size: 0.83rem;
}

.dgrund__hoved {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--muted);
    font-weight: 600;
    margin-bottom: 0.2rem;
}

.dgrund__linje { padding: 0.08rem 0; }

.dkvit {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.6rem;
}

.dkvit__grund { flex: 1 1 18rem; max-width: 26rem; }

/* Gemte visninger. Små og lavmælte: de er genveje, ikke navigation — og skal ikke se ud som
   faner, man SKAL vælge imellem. */
.dvisninger {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
}

.dvisning {
    border: 1px solid var(--line-2);
    background: none;
    color: var(--ink-2);
    border-radius: 1rem;
    padding: 0.1rem 0.6rem;
    font-size: 0.76rem;
    cursor: pointer;
    max-width: 10rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dvisning:hover { border-color: var(--brand); color: var(--brand); }
.dgem { padding-left: 0; padding-right: 0; white-space: nowrap; }

/* Graferne på enhedssiden. Her er kurven IKKE en baggrund for et tal — den er det, man kom
   efter, og får derfor sin fulde højde, sin akse og sine grænselinjer. */
.dgraf {
    padding: 0.8rem 0;
    border-top: 1px solid var(--line);
}

.dgraf:first-of-type { border-top: 0; }

.dgraf__hoved {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.3rem;
}

.dgraf__nu {
    font-variant-numeric: tabular-nums;
    font-size: 1.05rem;
    font-weight: 600;
}

.dport--fund { grid-template-columns: 1.1rem minmax(0, 1fr) auto; }

.dprofil {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-top: 0.4rem;
}

/* Det, en handling KOSTER, står med i linjen — ikke i en advarsel bagefter. Gul, fordi det er
   noget man skal vide, ikke noget der er galt. */
.dport__advar {
    color: var(--warn);
    font-size: 0.76rem;
    text-align: right;
}

/* Sensorens verber. Diskrete, fordi de er der hele tiden og kun bruges sjældent — en række
   knapper i fuld styrke ved hver sensor ville tage opmærksomheden fra det, der måles. */
.dhandling {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    flex-wrap: wrap;
    margin-top: 0.35rem;
}

.dhandling .btn-link { padding-left: 0.35rem; padding-right: 0.35rem; }

/* To felter side om side i en dialog. Falder sammen på smal skærm, så et talfelt aldrig bliver
   så smalt, at man ikke kan se, hvad man skriver. */
.drow {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 1rem;
}

@media (max-width: 620px) {
    .drow { grid-template-columns: 1fr; }
}

/* Enhed eller tjeneste. To store valg frem for en rulleliste med ti typer: spørgsmålet er ikke
   «hvilken af ti», det er «hvilken slags ting» — og det har kun to svar. */
.dvalgart {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.6rem;
    margin-bottom: 1rem;
}

.dvalgart__knap {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    text-align: left;
    padding: 0.7rem 0.8rem;
    border: 1px solid var(--line-2);
    border-radius: 0.5rem;
    background: none;
    color: inherit;
    cursor: pointer;
    font: inherit;
}

.dvalgart__knap span { font-size: 0.78rem; color: var(--muted); }
.dvalgart__knap:hover { border-color: var(--brand); }

.dvalgart__knap--valgt {
    border-color: var(--brand);
    background: color-mix(in srgb, var(--brand) 8%, transparent);
}

@media (max-width: 620px) {
    .dvalgart { grid-template-columns: 1fr; }
}

/* Certifikatets udløb. Ikke en fejl og ikke en måling — en dato, der nærmer sig. Neutral, indtil
   den er tæt nok på at kræve noget. */
.dcert {
    font-size: 0.8rem;
    color: var(--muted);
    margin-top: 0.25rem;
}

.dcert--obs {
    color: var(--warn);
    font-weight: 600;
}

/* Tidsaksens gitterstreger. Meget svage: de er en hjælp til at pege, ikke en del af billedet —
   og et gitter, der er lige så tydeligt som kurven, gør grafen sværere at læse, ikke lettere. */
.chart__grid {
    stroke: var(--line-2);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

/* Mærkerne står UNDER deres egen streg. En etiket, der ikke flugter med sit mærke, er værre end
   ingen etiket: den inviterer til at aflæse et forkert tidspunkt af kurven. */
.chart__akse {
    position: relative;
    height: 1.15rem;
    margin-top: 0.35rem;
    font-size: 0.72rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.chart__akse__mrk {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    white-space: nowrap;
}

/* Enderne siger, hvor langt grafen rækker. De står yderst og må gerne overlappes af et mærke —
   derfor er de dæmpede yderligere. */
.chart__akse__ende {
    position: absolute;
    top: 0;
    left: 0;
    opacity: 0.55;
}

.chart__akse__ende--h { left: auto; right: 0; }

/* På smal skærm er der ikke plads til både ender og mærker. Mærkerne vinder: de siger hvornår,
   enderne siger kun hvor langt. */
@media (max-width: 620px) {
    .chart__akse__ende { display: none; }
}

/* Enhedens navn og gruppe. Diskret linje NEDERST i udfoldningen, under «derfor er den markeret» og
   kvitteringen: det er noget, man sætter én gang og sjældent rører, mens de to andre er grunden
   til, at rækken blev foldet ud. Den skal stadig kunne findes uden at gætte, hvilken sensor det
   gemmer sig i. Stregen under den skiller den fra oppetiden nedenunder. */
.denavn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 0.6rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px dotted var(--line);
}

.denavn__felt { flex: 1 1 16rem; max-width: 24rem; }

.denavn__gruppe {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin-left: auto;
    font-size: 0.8rem;
    color: var(--muted);
}

.denavn__gruppe select { width: auto; min-width: 9rem; }

/* Tilbagelink over en sides overskrift. Står før titlen og til venstre, fordi det er dér
   øjet leder efter vejen ud — ikke i knapperækken til højre, som er indstillinger. */
.tilbage {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 0.6rem;
    color: var(--ink-2);
    font-size: 0.9rem;
    text-decoration: none;
}
.tilbage:hover { color: var(--navy-800); text-decoration: underline; }
.tilbage span { font-size: 1.05em; line-height: 1; }
:root[data-theme="dark"] .tilbage:hover { color: var(--link); }

/* Hvad en sensor tjekker. Dæmpet med vilje: den skal kunne læses, når man er i tvivl, og
   overses, når man ikke er — ellers konkurrerer den med tallet, der er det, man kom for. */
.dsensor__hvad {
    font-size: 0.85rem;
    color: var(--ink-2);
    line-height: 1.5;
    margin: 0.15rem 0 0.35rem;
    max-width: 78ch;
}

/* Ticket tabs. Open cases across the top of the module, so several can be held at once.
   Rendered by TicketTabs.razor and stored per user — see TicketTab for why. */
.tkt-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin: 0 0 1rem;
}
.tkt-tabs:empty { display: none; }

.tkt-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.15rem;
    background: var(--shell);
    border: 1px solid var(--line);
    border-radius: 7px;
    font-size: 0.85rem;
    max-width: 22rem;
}
.tkt-tab__link {
    padding: 0.3rem 0.15rem 0.3rem 0.6rem;
    color: var(--ink-2);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.tkt-tab__link:hover { color: var(--navy-800); }

/* Den, man står på, skal kunne findes uden at læse. Kanten bærer det — ikke en flade,
   der ville konkurrere med sagens eget indhold. */
.tkt-tab--current {
    border-color: var(--navy-800);
    background: var(--paper);
}
.tkt-tab--current .tkt-tab__link { color: var(--ink); font-weight: 600; }

.tkt-tab__close {
    border: 0;
    background: none;
    color: var(--ink-3, var(--ink-2));
    font-size: 1rem;
    line-height: 1;
    padding: 0.25rem 0.45rem;
    cursor: pointer;
    border-radius: 5px;
}
.tkt-tab__close:hover { background: var(--line); color: var(--ink); }

:root[data-theme="dark"] .tkt-tab { background: var(--shell); border-color: var(--line-2); }
:root[data-theme="dark"] .tkt-tab--current { border-color: var(--link); }
:root[data-theme="dark"] .tkt-tab__link:hover,
:root[data-theme="dark"] .tkt-tab--current .tkt-tab__link { color: var(--link); }

/* Sektionsfaner: én ting set fra flere sider. Bevidst UNDERSTREGET, hvor de åbne sagers
   .tkt-tabs er piller — to bjælker på samme side må ikke se ens ud, når den ene skifter sag
   og den anden kun skifter afsnit. */
.sectabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.1rem;
    margin: 0 0 0.9rem;
    border-bottom: 1px solid var(--line);
}

.sectab {
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 0.45rem 0.7rem;
    font: inherit;
    font-size: 0.86rem;
    color: var(--muted);
    cursor: pointer;
    white-space: nowrap;
}

.sectab:hover { color: var(--ink); }

.sectab--current {
    color: var(--ink);
    font-weight: 600;
    border-bottom-color: var(--brand);
}

.sectab__count {
    margin-left: 0.35rem;
    font-size: 0.74rem;
    font-weight: 400;
    color: var(--muted);
}

.sectab--current .sectab__count { color: var(--ink-2); }

/* Alderen på en fejlende måling. Dæmpet: den er en oplysning om selve målingen, ikke en del
   af fejlen — men den skal stå DÉR, hvor fejlen står, ikke et andet sted på kortet. */
.dsensor__alder {
    color: var(--muted);
    font-weight: 400;
    white-space: nowrap;
}

/* Oprydningsdialogens liste over, hvad der bliver slettet.
   Den skal kunne rulle: et filter kan ramme mange poster, og en dialog, der vokser ud over
   skærmen, skjuler netop den knap, man skal kunne nå. Tokens frem for faste farver, så den
   følger med i mørkt tema. */
.ryd__liste {
    margin-top: 0.9rem;
    border-top: 1px solid var(--line);
    padding-top: 0.7rem;
}

.ryd__ul {
    list-style: none;
    margin: 0 0 0.4rem;
    padding: 0;
    max-height: 15rem;
    overflow-y: auto;
}

.ryd__ul li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.3rem 0;
    border-bottom: 1px solid var(--line);
}

.ryd__ul li:last-child {
    border-bottom: 0;
}

/* Beskrivelsen er den længste del og må gerne tage resten af linjen; tidspunktet skubbes
   til højre, så øjet kan løbe ned ad datoerne uden at læse resten. */
.ryd__ul li .stat__meta:first-of-type {
    flex: 1 1 12rem;
    min-width: 0;
}

.ryd__ul li .stat__meta:last-of-type {
    margin-left: auto;
    white-space: nowrap;
}
