/* Look Awesome — UdstillerGuide. Brand/accent/neutral/success/warning/danger
   som --wa-color-* (forbruges af WA-komponenter) + --ug-* (kanoniske navne) +
   --ug-radius-* (B1 form-tokens). Kilde: Johannes' farve-spec (ADR-0047).
   .wa-look-custom på <html> vinder over WA's default-tema via specificitet. */

.wa-look-custom {
  /* Brand — base #00483e (oklch(0.36 0.065 180)), lidt mørkere tone (2026-06-18). */
  --wa-color-brand-95: #dff7f1;
  --wa-color-brand-90: #cbece4;
  --wa-color-brand-80: #a6d2c8;
  --wa-color-brand-70: #83b9ad;
  --wa-color-brand-60: #64a094;
  --wa-color-brand-50: #448074;
  --wa-color-brand-40: #266358;
  --wa-color-brand-30: #174e45;
  --wa-color-brand-20: #0d3932;
  --wa-color-brand-10: #05221d;
  --wa-color-brand-05: #041512;
  --wa-color-accent-95: #ffeee9;
  --wa-color-accent-90: #ffdfd3;
  --wa-color-accent-80: #ffb9a0;
  --wa-color-accent-70: #ff916a;
  --wa-color-accent-60: #ea7246;
  --wa-color-accent-50: #c55123;
  --wa-color-accent-40: #a03500;
  --wa-color-accent-30: #7f2900;
  --wa-color-accent-20: #5f1c00;
  --wa-color-accent-10: #3c0e00;
  --wa-color-accent-05: #290700;
  --wa-color-neutral-95: #f3f1f1;
  --wa-color-neutral-90: #e7e5e4;
  --wa-color-neutral-80: #cbc9c7;
  --wa-color-neutral-70: #b1aeac;
  --wa-color-neutral-60: #979492;
  --wa-color-neutral-50: #787573;
  --wa-color-neutral-40: #5b5957;
  --wa-color-neutral-30: #484544;
  --wa-color-neutral-20: #343231;
  --wa-color-neutral-10: #1f1e1d;
  --wa-color-neutral-05: #131211;
  --wa-color-success-95: #dafadf;
  --wa-color-success-90: #c5f0cc;
  --wa-color-success-80: #9cd7a7;
  --wa-color-success-70: #77be86;
  --wa-color-success-60: #55a568;
  --wa-color-success-50: #33854a;
  --wa-color-success-40: #0b672e;
  --wa-color-success-30: #005121;
  --wa-color-success-20: #003c16;
  --wa-color-success-10: #00240a;
  --wa-color-success-05: #001705;
  --wa-color-warning-95: #f8f3c7;
  --wa-color-warning-90: #eee7aa;
  --wa-color-warning-80: #d6cb76;
  --wa-color-warning-70: #beb042;
  --wa-color-warning-60: #a59600;
  --wa-color-warning-50: #837700;
  --wa-color-warning-40: #635a00;
  --wa-color-warning-30: #4e4600;
  --wa-color-warning-20: #393300;
  --wa-color-warning-10: #221e00;
  --wa-color-warning-05: #161300;
  --wa-color-danger-95: #ffeeec;
  --wa-color-danger-90: #ffded9;
  --wa-color-danger-80: #ffb8ae;
  --wa-color-danger-70: #ff8f82;
  --wa-color-danger-60: #ff5f53;
  --wa-color-danger-50: #da3832;
  --wa-color-danger-40: #b6000e;
  --wa-color-danger-30: #910009;
  --wa-color-danger-20: #6d0005;
  --wa-color-danger-10: #460002;
  --wa-color-danger-05: #2f0001;

  /* lys-gron (variant="lys-gron") */
  --wa-color-lys-gron-95: #dafadf;
  --wa-color-lys-gron-90: #c5f0cc;
  --wa-color-lys-gron-80: #9cd7a7;
  --wa-color-lys-gron-70: #77be86;
  --wa-color-lys-gron-60: #55a568;
  --wa-color-lys-gron-50: #33854a;
  --wa-color-lys-gron-40: #0b672e;
  --wa-color-lys-gron-30: #005121;
  --wa-color-lys-gron-20: #003c16;
  --wa-color-lys-gron-10: #00240a;
  --wa-color-lys-gron-05: #001705;

  /* lys-accent (variant="lys-accent") · base #946C5C */
  --wa-color-lys-accent-95: #ffeee8;
  --wa-color-lys-accent-90: #fae0d6;
  --wa-color-lys-accent-80: #e4c2b5;
  --wa-color-lys-accent-70: #cda697;
  --wa-color-lys-accent-60: #b68c7b;
  --wa-color-lys-accent-50: #946c5c;
  --wa-color-lys-accent-40: #765041;
  --wa-color-lys-accent-30: #5f3e31;
  --wa-color-lys-accent-20: #462c22;
  --wa-color-lys-accent-10: #2b1a13;
  --wa-color-lys-accent-05: #1b0f0b;
  --ug-lys-accent-95: #ffeee8;
  --ug-lys-accent-90: #fae0d6;
  --ug-lys-accent-80: #e4c2b5;
  --ug-lys-accent-70: #cda697;
  --ug-lys-accent-60: #b68c7b;
  --ug-lys-accent-50: #946c5c;
  --ug-lys-accent-40: #765041;
  --ug-lys-accent-30: #5f3e31;
  --ug-lys-accent-20: #462c22;
  --ug-lys-accent-10: #2b1a13;
  --ug-lys-accent-05: #1b0f0b;

  /* lys-brand = brand-quiet (variant="lys-brand") · base #66797F */
  --wa-color-lys-brand-95: #ebf3f6;
  --wa-color-lys-brand-90: #dce7eb;
  --wa-color-lys-brand-80: #bdccd1;
  --wa-color-lys-brand-70: #9fb2b7;
  --wa-color-lys-brand-60: #85989f;
  --wa-color-lys-brand-50: #66797f;
  --wa-color-lys-brand-40: #4a5c62;
  --wa-color-lys-brand-30: #38484d;
  --wa-color-lys-brand-20: #283539;
  --wa-color-lys-brand-10: #171f22;
  --wa-color-lys-brand-05: #0d1315;
  --ug-lys-brand-95: #ebf3f6;
  --ug-lys-brand-90: #dce7eb;
  --ug-lys-brand-80: #bdccd1;
  --ug-lys-brand-70: #9fb2b7;
  --ug-lys-brand-60: #85989f;
  --ug-lys-brand-50: #66797f;
  --ug-lys-brand-40: #4a5c62;
  --ug-lys-brand-30: #38484d;
  --ug-lys-brand-20: #283539;
  --ug-lys-brand-10: #171f22;
  --ug-lys-brand-05: #0d1315;

  /* --ug-status-familier (ADR-0047): alias wa-color-trin. (Den blå plan-familie er fjernet — plan = info.) */
  --ug-success-95: var(--wa-color-success-95);
  --ug-success-80: var(--wa-color-success-80);
  --ug-success-70: var(--wa-color-success-70);
  --ug-success-50: var(--wa-color-success-50);
  --ug-success-40: var(--wa-color-success-40);
  --ug-success-30: var(--wa-color-success-30);
  --ug-success-surface: var(--wa-color-success-95);
  --ug-warning-95: var(--wa-color-warning-95);
  --ug-warning-80: var(--wa-color-warning-80);
  --ug-warning-70: var(--wa-color-warning-70);
  --ug-warning-50: var(--wa-color-warning-50);
  --ug-warning-40: var(--wa-color-warning-40);
  --ug-warning-30: var(--wa-color-warning-30);
  --ug-warning-surface: var(--wa-color-warning-95);
  /* Warning INK on the page surface (theme-flipping — facit redform.css
     .mp-dirtylab: warning-30 lys / warning-70 mørk). Tints are fixed-lightness,
     so text roles need the flip; element-CSS (C7: no .wa-dark class selectors)
     consumes this semantic token instead. First consumer: ug-gemt-indikator's
     dirty state (M4c-1). */
  --ug-warning-text: var(--wa-color-warning-30);
  --ug-danger-95: var(--wa-color-danger-95);
  --ug-danger-80: var(--wa-color-danger-80);
  --ug-danger-70: var(--wa-color-danger-70);
  --ug-danger-50: var(--wa-color-danger-50);
  --ug-danger-40: var(--wa-color-danger-40);
  --ug-danger-30: var(--wa-color-danger-30);
  --ug-danger-surface: var(--wa-color-danger-95);
  --ug-neutral-50: var(--wa-color-neutral-50);

  /* plan-status: den blå oklch-hue-275-familie er FJERNET (off-roster, off-brand, nul
     forbrugere). "plan" deler nu info-tonen (lys-brand-40) — se --ug-surface-plan nedenfor.
     Gendan ALDRIG den blå familie (ADR-0047: kun de 8 sanktionerede familier + info). */

  /* Per-familie panel-fyld-baggrunde --ug-surface-<familie> (ADR-0047 §Consequences
     "Nye opgaver 1" + ADR-0061 §5 / ug3-njo2o). Panel-fyld = familiens FULDE core-farve
     (ikke en -95-tint): danger/warning/success deler samme loud-core som tier-badgen, info
     = lys-brand-40, plan = info, brand = den dybe brand-flade (login/CTA). Valgt visuelt
     2026-06-25: -80/-95-tints var for tæt på et normalt hvidt panel; fulde farver gør
     danger/warning tydelige. Et tone-bærende panel trækker --ug-surface-<familie> via
     [data-surface="<familie>"]-konteksten (LAG 3 nedenfor) der re-mapper den kontekst-neutrale
     --ug-surface; et neutralt panel beholder global --ug-surface (fallback iboende i cascaden).
     On-teksten flipper til --ug-on-<familie>-surface (= den loud --ug-on-<familie>-ink). */
  /* Fuld familie-core som panel-fyld. Værdier sat DIREKTE (hex/wa-color) her i
     .wa-look-custom så token-parserens tier-2-primitiv-split klassificerer dem som
     farver (cores --ug-success/--ug-warning/--ug-info bor i :root/.wa-light og kan
     ikke resolves af .wa-look-custom-fixpunktet). Hold i sync med cores nedenfor. */
  --ug-surface-success: #63b375;                     /* = --ug-success, fuld (on = sort, 8.2:1) */
  --ug-surface-warning: #fff075;                     /* = --ug-warning, fuld (on = sort, 18:1) */
  --ug-surface-danger:  var(--wa-color-danger-40);   /* = --ug-danger, fuld (on = hvid, 7.0:1) */
  --ug-surface-info:    var(--wa-color-lys-brand-40);/* = --ug-info, lys-brand-40 (on = hvid, 7.0:1) */
  --ug-surface-plan:    var(--ug-surface-info);      /* plan deler info-tonen (blå hue-275-familie fjernet) */
  --ug-surface-brand:   var(--ug-brand);             /* #00483e loud brand-flade — store grafiske/CTA, login (on = hvid) */

  /* --ug-on-* AAA on-tekst per ADR-0047-tabel (sat ét sted; relations-kontekst kan overskrive).
     Panel-fyld = fuld familie-core (ikke -95-tint), så --ug-on-<familie>-surface = den loud
     --ug-on-<familie>-ink: success/warning sort, danger/info/plan hvid. Badge OG panel deler
     disse, så de aldrig divergerer. Alle ≥7:1 AAA (beregnet, ikke gættet). */
  --ug-on-success: #000;            /* sort på fuld success #63b375 (8.2:1) */
  --ug-on-success-surface: var(--ug-on-success);
  --ug-on-warning: #000;            /* sort på fuld warning #fff075 (18:1) */
  --ug-on-warning-surface: var(--ug-on-warning);
  --ug-on-danger: #fff;             /* hvid på fuld danger #b6000e (7.0:1) */
  --ug-on-danger-surface: var(--ug-on-danger);
  --ug-on-danger-duotone: #000;     /* sort duotone-DETALJELAG på fuld danger (trash-lågets primary-lag på ug-raekke-slet — Johannes' galleri-valg 2026-07-20: sort låg + hvid spand). Kontekst-invariant som --ug-on-danger. NB: låget står kant-adjacent DIREKTE mod den røde flade (sort-på-#b6000e ≈ 3,0:1) — grafisk objekt, WCAG 1.4.11-baren er 3:1; æstetisk valg, ikke AAA-tekst-kontrast som nabolinjernes 7:1. */
  --ug-on-info: #fff;               /* hvid på info #4a5c62 (lys-brand-40, 7.0:1) */
  --ug-on-info-surface: var(--ug-on-info);
  --ug-on-plan-surface: var(--ug-on-info-surface); /* plan = info */

  /* B1 form-radius-tokens (pill vs kort). --ug-radius-info udfaset (#1313:
     form-loven "firkant"->"kort" gjorde --ug-radius det kanoniske kort-token). */
  --ug-radius-pill: 9999px;
  --ug-radius: 0.5rem;
  --ug-radius-s: 0.25rem;

  /* OTP-felt cell dimensions + focus ring (ug-otp-felt web component). */
  --ug-otp-cell-w: 2.625rem;
  --ug-otp-cell-h: 3.125rem;
  --ug-otp-font:   1.3125rem;
  --ug-otp-gap:    var(--ug-space-xs);
  --ug-otp-ring:   0 0 0 0.1875rem color-mix(in srgb, var(--ug-brand) 14%, transparent);

  /* Thumbnail-swatch (ug-preview-kort + senere metode-kort-familie). */
  --ug-thumb-size: 2.75rem;

  /* Icon-tile sizes: seccard icon (44px) + avatar initialer-tile (50px / hero 60px). */
  --ug-ikon-size:     2.75rem;  /* 44px — .sec-ico facit (konto-sikkerhed.html) */
  --ug-avatar-size:   3.125rem; /* 50px — .el-ava / .ph-ava facit (samlet.css) */
  --ug-avatar-size-l: 3.75rem;  /* 60px — .kh-ava konto-hero facit (konto.css) */
  --ug-avatar-size-s: 2.25rem;  /* 36px — meta-panelets ejer-avatar (75% af WA's 3rem-default, Johannes 2026-07-26) */
  --ug-session-flise-size: 2.125rem; /* 34px — .se-ico session-række facit (konto.css) */
  --ug-side-flise-size: 2.375rem; /* 38px — .vs-ico udstillerside-række facit (konto.css) */
  --ug-hovedfane-flise-size: 1.25rem; /* 20px — .cttab-ava hoved-fane facit (udstiller-indhold.html) */

  /* Delt topbar-kontrol-højde — iconbtn/logo-pill/topbar-action/topbar-user i claude-design-facit er alle 38px. */
  --ug-control-height: 2.375rem;   /* 38px — delt topbar-kontrol-højde */

  /* Line-height (leading) scale — den manglende typografi-akse. Værdier er
     ratios (unitless), ekstraheret verbatim fra auth.css-facit (.lc-h 1.12,
     .lc-sub 1.5, .lc-foot/.sb-sub 1.55, .sb-h 1.1, .lc-glyph 1). C8 afviser
     bare ratios (1.5/1.55/…) som design-værdier; disse tokens er deres hjem. */
  --ug-leading-flush:   1;      /* glyph/wordmark — ingen extra leading */
  --ug-leading-snug:    1.1;    /* .sb-h (messe-navn) */
  --ug-leading-tight:   1.12;   /* .lc-h (titler) */
  --ug-leading-normal:  1.5;    /* .lc-sub (undertekster) */
  --ug-leading-relaxed: 1.55;   /* .lc-foot / .sb-sub (fodnoter, pitch) */

  /* Display-glyf (login-flade tilstands-ikoner) + brand-glyf-størrelse.
     Facit: .lc-glyph 38px (link-sendt/totp), drevet-af-mærkets bomærke 1.2rem. */
  --ug-glyph-display:  2.375rem; /* 38px — .lc-glyph (auth.css:52) */
  --ug-glyph-mark:     1.2rem;   /* bomærke i drevet-af-mærke (auth.css sb-foot) */

  /* Tekst-mål (max-inline-size i ch) — facit .sb-sub max-width: 34ch (messe-pitch). */
  --ug-measure-pitch: 34ch;
  /* Liste-søgefeltets mål — facit oversigt.js .search (liste.css toolbar-rytmen). */
  --ug-measure-soeg: 32ch;
  /* Kort-griddens mindste kolonne — facit liste.css .grid.landskab minmax(330px, 1fr). */
  --ug-measure-kort: 20.625rem;
  /* Media-first-flisens mindste kolonne — facit medie-kort-mockup .grid minmax(240px, 1fr). */
  --ug-measure-medieflise: 15rem;
  /* Media-first-flisen i kompakt tæthed — facit medie-kort-mockup .grid.kompakt minmax(150px, 1fr). */
  --ug-measure-medieflise-kompakt: 9.375rem;
  /* Kort-mediakolonnens bredde. Facit (liste.css .landskab .card-media) er en 84px
     stribe i kortets fulde højde; den er BEVIDST forladt (ug3-uizpx, Johannes):
     landskab-media er kvadratisk. Bredden ER firkantens side, så den er valgt ved at
     måle den komponerede kort-render (kort-boks 174px høj ved 4 felt-linjer): 7.5rem
     dækker 120/174 ≈ 69% af kortets højde mod 84px' ≈ 48%. Flisen flugter kortets
     top (align-self: start i ug-post-kort) og fylder IKKE ned til fod-rækken —
     der står ~53px kortflade under den. */
  --ug-measure-kortmedia: 7.5rem;
  /* Kort-felt-etikettens spalte — facit liste.css .cf-k min-width: 78px. */
  --ug-measure-kortetiket: 4.875rem;
  /* Meta-panelets faste kolonne — facit redform.css .rf-layout grid 326px. */
  --ug-measure-metapanel: 20.375rem;
  /* Redigeringsfelternes maksbredde — facit redform.css .field-grid max-width: 660px. */
  --ug-measure-felt: 41.25rem;
  /* Tabellens mindstebredde før vandret scroll — facit liste.css table.data min-width: 720px. */
  --ug-measure-tabelmin: 45rem;
  /* Tal-tabellens mindstebredde før vandret scroll inde i kortet (ug3-iwv8o.2.75). */
  --ug-measure-tal-tabelmin: 40rem;
  /* Tabel-tilstandens kolonne-grid. Facit (liste.css table.data) er en NATIV
     tabel med table-layout:auto — kolonnerne følger kolonne-tallet og fylder
     bredden (2 kolonner ⇒ 2 kolonner der fylder, aldrig reserverede tomme spor).
     Div-grid-emuleringen genskaber det med grid-auto-flow:column: navn-kolonnen er
     det ENE eksplicitte spor (bred, minmax), og hver yderligere celle får et
     implicit --ug-tabel-kol-auto-spor. Kolonneantallet er DATA (galleri: navn +
     status + 2 felter = 4; M4b-produktion: navn + status = 2) og grid'et adapterer
     uden en per-render override. Post-tabellen tilføjer en handlings-celle pr.
     række-menu (U2) eller rækkens Rediger-knap: den celle er IKKE et datasporet
     kolonne-spor — den tages ud af kolonneflowet og lægges i et indholdsbredt
     bånd langs rækkens inderste kant (--ug-tabel-handling-reserve), så
     data-kolonnerne deler hele den øvrige bredde. Kun aktiv når rækkerne bærer
     handlings-celler (ug-tabel-flade.css :has-scope); stab-tabellen uden
     handlings-celle er upåvirket. Literalerne bor HER i token-laget (L3). */
  --ug-tabel-kol-foerste: minmax(var(--ug-measure-kort), 2fr);
  --ug-tabel-kol-auto: 1fr;
  /* Bredden på handlings-båndet i tabelrækken. Båndet skal rumme rækkens
     bredeste handling plus cellens inline-padding, så knappens højre kant
     flugter med de øvrige cellers indhold; overskuddet er luft til venstre for
     handlingen, og fordi data-sporene stopper hvor båndet begynder, kan tekst
     ikke løbe ind under den. Hoved- og række-grid'et reserverer det SAMME bånd
     som padding-inline-end, så de to separate grids resolver til samme
     kolonnegrænser.
     BÅNDET ER FAST, og rækkens handling er en oversat etiket (i18n-nøglen
     `common.edit`): en etiket bredere end båndet reflower ikke, den lander oven
     på sidste datakolonne. Værdien er derfor målt i dev-browser mod den
     LÆNGSTE registrerede `common.edit` og lagt med luft ovenpå. Præmissen —
     at ingen lokalisering har tilføjet en længere etiket siden målingen — er
     ikke en påstand her, men en gate: TestTabelHandlingsBaand_MaaltEtiketErStadigDenLaengste
     (cmd/gallery/tabel_handlingsbaand_test.go) fejler hvis den brister, og
     beder om en ny måling. Bor HER i token-laget (L3, C8). */
  --ug-tabel-handling-reserve: 8rem;
  /* Åbn-i-panel-cellens bånd (ug3-l7zav): den ikon-alene runde plain-knap
     (takt 3, 28px) plus luft, lagt FORAN Rediger-båndet i tabel-panel-
     tilstanden — kassen (ug-tabel-flade) summerer de to til rækkens samlede
     handlings-bånd når begge celler er komponeret. */
  --ug-tabel-aabn-reserve: 2.75rem;
  /* Tidspunkt-tabellens FASTE kolonnespor (B1, drawer-modellen — facit
     tidspunkt-drawer-model.html .trow 52px 12px 52px 64px 72px 1fr): Start |
     – | Slut | Varighed | Status | handlinger. Sporene er faste (ikke
     ug-tabel-flades adaptive auto-flow) så tiderne aligner på tværs af de
     SEPARATE række-grids; spor 6 er det fleksible (status/handlings-luft),
     7-8 bærer ⧉/⋯-knapperne (B2: ✎ ⧉ ⋯ samles som én pill-gruppe — kassens
     hjørne-kollaps; basernes kompakte bredde = facit .acts
     wa-button::part(base) 32px, 30px ≤520px). Kolonneheader-rækken er UDGÅET
     (facit 2026-07-11) — dag-hovederne bærer strukturen. ≤520px udgår
     Varighed-sporet (facit 46px 10px 46px 1fr + handlinger). Visningens
     standalone-grid (element-kortet) bruger samme spor uden
     handlings-kolonnerne. Literalerne bor HER (L3, C8). */
  /* Standafstemningens FASTE kolonnespor (ug3-249g2.3, mockuppens tabel-
     render). Mockuppen er en native auto-tabel hvor standnr-kolonnen krymper
     til sit mono-indhold og pin-kolonnen er smal; de SEPARATE hoved- og
     række-grids kan kun aligne på faste spor, så standnr-sporet rummer en
     standkode plus cellens inline-padding, pin-sporet er mockuppens pin-
     bredde, udstilleren er det brede spor, og konfidens-sporet er bredere end
     de øvrige, fordi en afgjort række bærer afgørelses-chippen ved siden af
     konfidens-chippen. Det sidste spor er åbn-cellen (ikon-knap, ug3-5zdp3.15);
     hovedet har ingen etiket der, så sporet står tomt i hoved-griddet.
     Aktiveres af ug-tabel-flade.css' :has(ug-stand-nr)-scope.
     Literalerne bor HER (L3, C8). */
  --ug-tabel-kol-afstemning: 6.5rem 1.75rem minmax(12rem, 2fr) 1.5fr 1fr 1fr 1fr 2.5rem;
  --ug-tidspunkt-kol: 3.25rem 0.75rem 3.25rem 5.25rem 5rem 1fr max-content max-content;
  --ug-tidspunkt-kol-mobil: 2.875rem 0.625rem 2.875rem minmax(0, 1fr) max-content max-content max-content;
  --ug-tidspunkt-kol-visning: 3.25rem 0.75rem 3.25rem 5.25rem; /* Start | – | Slut | Varighed — Status-cellen er flyttet til grp-tidspunkt-raekkes familie-plads (F4-5) */
  --ug-tidspunkt-span-fuld: 1 / -1;
  /* Heldags-rækkens ENE celle (ug3-jw6cm.1.6.3) spænder tids-sporene, så
     status-cellen bliver stående i sit eget spor: Start | – | Slut | Varighed
     = 4 spor, og ≤520px hvor Varighed-sporet udgår = 3. Literalerne bor HER
     (L3, C8) sammen med de spor de tæller. */
  --ug-tidspunkt-span-tider: span 4;
  --ug-tidspunkt-span-tider-mobil: span 3;
  --ug-tidspunkt-handling-bredde: 2rem;
  --ug-tidspunkt-handling-bredde-mobil: 1.875rem;
  /* Skrå-stribet media-placeholder-flade — facit liste.css .card-media (8px/9px
     hatch over dæmpet flade). Literalen bor HER i token-laget (L3); elementer
     refererer var(--ug-hatch). */
  --ug-hatch: repeating-linear-gradient(45deg, transparent, transparent 8px, color-mix(in srgb, var(--ug-border-quiet) 55%, transparent) 8px, color-mix(in srgb, var(--ug-border-quiet) 55%, transparent) 9px);
  --ug-measure-intro: 62ch; /* .kp-intro konto-panel-intro facit (konto.css) */
  --ug-measure-beskrivelse: 58ch; /* .sec-d metode-beskrivelse facit (konto.css) */
  --ug-feltgrid-min: 26rem; /* konto-feltgrid min-kolonne — 2 kol på desktop-kort, 1 kol smalt (.kfields facit, konto.css) */
  --ug-adgangsgrid-min: 17.5rem; /* bruger-rediger adgang-feltgrid min-kolonne (K2b) — redform-kolonnens 2-kol grid: facit redform.css .field-grid max 660px, .two 1fr 1fr (~319px/kolonne, 1 kol under 640-viewport); 26rem-tokenen er målt for bred til redform-kolonnen */
  --ug-lyn-felt-min: 11.25rem; /* lyn-rediger auto-fit-grid min-kolonne — facit liste.css .qe-fields minmax(180px,1fr) */
  --ug-sideomside-liste: 15rem; /* side-om-side master-liste-kolonne — facit liste.css .sl-list (snap 260px, holdt smallere for galleri-flade) */
  --ug-measure-kort-portraet: 12.5rem; /* portræt-tætheds kort-grid min-kolonne — facit liste.css .grid.portraet minmax(200px,1fr) */
  --ug-measure-kort-kompakt: 14.5rem; /* kompakt-tætheds kort-grid min-kolonne — facit liste.css .grid.kompakt minmax(232px,1fr) */
  --ug-measure-kortmedia-kompakt: 3.25rem; /* kompakt-kortets media-kolonne — facit liste.css .kompakt .card-media width: 52px */
  --ug-kort-aspect-portraet: 4 / 3; /* portræt-kortets media-billedformat — facit liste.css .portraet .card-media aspect-ratio: 4/3. Strukturel literal bor i token-laget (L3). */
  --ug-kort-aspect-landskab: 1; /* landskab-kortets media-billedformat: KVADRATISK (ug3-uizpx, Johannes) — facits fuld-højde-stribe gav et smalt/aflangt billede. Strukturel literal bor i token-laget (L3). */
  /* Kort-fodens deler (ug3-2r51s, mockup 2026-08-03-kort-knapraekke): preview +
     rediger står ALTID på egen linje nederst i kort-kroppen bag en tynd deler.
     --ug-kant-linje er selve hairline-værdien (genbruger --ug-border-quiet, samme
     streg som ug-linje-skiller); --ug-kort-fod-kant/-luft er KONTEKST-dials med
     neutral default (none/0), som post-kort-kassernes :has(knap)-guardede
     fod-regel slår til DIREKTE på fod-clusteren (custom-property-deklaration,
     Del-D-legal) — aldrig på kasse-hosten, hvor arven lækkede stregen ind i
     grp-medie-chips (lånt cluster oven på mediet, nested gennem
     ug-post-kort-portraet). Literalerne bor HER i token-laget (L3, C8). */
  --ug-kant-linje: var(--wa-border-width-s) solid var(--ug-border-quiet);
  --ug-kort-fod-kant: none;
  --ug-kort-fod-luft: 0;
  /* ug-meta-rækkens nøgle-frase (ug3-iav9l): KONTEKST-dial med neutral default
     (none = nøglen skrumper ikke, værdien skubbes til højre — meta-panelets
     rækkeform). En flade hvor nøglen bærer HELE teksten og boksen er smal slår
     den til på sin egen kontekst, så frasen ellipserer inde i sin egen kasse i
     stedet for at flyde ud over nabokolonnen. Grep dialens navn for at finde de
     kontekster der gør det. Literalen bor HER i token-laget (L3, C8);
     ug-meta-raekke.css forbruger den med inert fallback. */
  --ug-meta-noegle-flex: none;
  /* Kort-griddens spor. WA's wa-grid-utility former sporene med auto-FIT
     (internal/waassets/.../layout.css), og auto-fit kollapser de tomme spor: ét
     kort i modulet blev strakt til hele indholdsbredden. Facit-gridden
     (liste.css .grid.landskab) bruger auto-FILL netop derfor — tomme spor bevares,
     så kortbredden er den samme ved 1 og ved 30 poster. min(…, 100%) er WA's
     mobil-værn (aldrig et spor bredere end containeren) og beholdes. Ved
     ramme-shellens 1072px indholdsbredde giver 20.625rem-sporet 3 kolonner, ved
     smallere container 2, og 1 på mobil. Literalerne bor HER i token-laget (L3). */
  --ug-kort-kolonner: repeat(auto-fill, minmax(min(var(--ug-measure-kort), 100%), 1fr));
  /* Portræt-tæthedens spor — SAMME auto-fill-formel som --ug-kort-kolonner, med
     portrættets egen min-kolonne (facit liste.css .grid.portraet
     minmax(200px,1fr)). Uden den arvede rel-post-liste-portraet WA's auto-FIT
     via --min-column-size, og ét kort i modulet blev MÅLT til 1072px — hele
     ramme-shellens indholdsbredde (ug3-nt4pz). Med auto-fill giver de samme
     1072px 5 spor à ~200px, uanset om modulet har 1 eller 30 poster. */
  --ug-kort-kolonner-portraet: repeat(auto-fill, minmax(min(var(--ug-measure-kort-portraet), 100%), 1fr));
  /* Kompakt-tæthedens spor — SAMME auto-fill-formel som --ug-kort-kolonner, med
     kompaktens egen min-kolonne (facit liste.css .grid.kompakt
     minmax(232px,1fr)). Uden den arvede rel-post-liste-kompakt WA's auto-FIT
     via --min-column-size (layout.css: repeat(auto-fit, …)), og ét kort i
     modulet blev strakt til hele ramme-shellens indholdsbredde — MÅLT til 1072px
     med auto-fit mod 259px med auto-fill (ug3-cguyo). Med auto-fill giver de
     1072px 4 spor (232px-minimum, vokset til 259px af 1fr), uanset om modulet
     har 1 eller 30 poster. */
  --ug-kort-kolonner-kompakt: repeat(auto-fill, minmax(min(var(--ug-measure-kort-kompakt), 100%), 1fr));
  /* Medieflisens spor — SAMME auto-fill-formel som --ug-kort-kolonner, med
     medieflisens egen min-kolonne (facit medie-kort-mockup .grid
     minmax(240px,1fr)). Uden den arvede rel-medie-liste WA's auto-FIT via
     --min-column-size (layout.css: repeat(auto-fit, …)), og én fil i
     mediegalleriet blev strakt til hele indholdsbredden — MÅLT til 1072px med
     auto-fit mod 259px med auto-fill (ug3-u42ex). Med auto-fill giver de 1072px
     4 spor à 259px (240px-minimum, vokset af 1fr), uanset om galleriet har 1
     eller 30 filer. */
  --ug-medieflise-kolonner: repeat(auto-fill, minmax(min(var(--ug-measure-medieflise), 100%), 1fr));
  /* Medieflisen i kompakt tæthed — samme auto-fill-formel over kompaktens egen
     min-kolonne (facit medie-kort-mockup .grid.kompakt minmax(150px,1fr));
     samme auto-fit-kollaps-klasse som ovenfor (ug3-u42ex). */
  --ug-medieflise-kolonner-kompakt: repeat(auto-fill, minmax(min(var(--ug-measure-medieflise-kompakt), 100%), 1fr));
  --ug-kort-daempet-daek: 0.55; /* dæmpet dashboard-korts opacity (ug-dashboard-kort-daempet, «kommer senere»-kort, ug3-y35w1) */
  /* ug-side-kort-redesign (ug3-trxlr, Johannes' beslutning 2 2026-07-11):
     ikon-kolonne | tekst-stak — ikonet spænder navn+meta-rækkerne, teksterne
     stakkes i kolonne 2 (aldrig kolonner-i-teksten). Literalerne bor HER (L3, C8). */
  --ug-sidekort-kol: auto 1fr;
  --ug-sidekort-ikon-raekker: 1 / span 2;
  --ug-sidekort-tekst-kol: 2;
  /* Statistik-klodserne (ug3-iwv8o.2.53): andels-bjælken lægger etiket | tal
     på første linje og lader bjælken spænde hele rækken under dem; tragt-
     trinnet er nummer | navn | antal | andel. Literalerne bor HER (L3, C8). */
  --ug-andel-bjaelke-kol: minmax(0, 1fr) auto;
  --ug-andel-bjaelke-spor-fuld: 1 / -1;
  /* With the current-build mark (ug3-iwv8o.2.74): etiket | mærke | tal, the
     mark in the middle column on the first line. */
  --ug-andel-bjaelke-kol-maerke: auto minmax(0, 1fr) auto;
  --ug-andel-bjaelke-maerke-raekke: 1;
  --ug-andel-bjaelke-maerke-kol: 2;
  /* The share bar's fill: brand by default; a list relation may set it neutral
     for rows that are not the highlighted one (ug3-iwv8o.2.74). */
  --ug-andel-fyld: var(--ug-brand-strong);
  --ug-andel-fyld-neutral: var(--wa-color-neutral-border-loud);
  /* ug-sparkline (ug3-iwv8o.2.76): the time-series strip under a statistics
     card's KPI tiles — its height and the stroke width of its top edge.
     Literals live HERE (L3, C8). */
  --ug-sparkline-hoejde: 4rem;
  --ug-sparkline-streg: 3;
  --ug-tragt-trin-kol: auto minmax(0, 1fr) auto auto;

  --ug-split-min: 25%; /* side-om-side wa-split-panel: start-panelet aldrig < 25% (Johannes 2026-07-05, ADR-0091) */
  --ug-split-max: 75%; /* side-om-side wa-split-panel: start-panelet aldrig > 75% ⇒ end-panelet aldrig < 25% (Johannes 2026-07-05, ADR-0091) */

  /* Media-felter (galleri + video, ug3-a19i3 — design facit galleri-felt.js/
     video-felt.js). Strukturelle literaler bor HER i token-laget (L3);
     elementerne (ug-galleri-felt/-visning, ug-video-felt/-visning) refererer
     tokens. */
  --ug-media-video-format: 16 / 9; /* video-preview/embed-rammens billedformat (facit .vf-frame) */
  --ug-media-fit: cover; /* media-thumbs fylder rammen (facit .gf-thumb img object-fit) */
  --ug-measure-video: 28rem; /* video-preview/embed maksbredde */
  --ug-galleri-kolonner: repeat(auto-fill, minmax(9rem, 1fr)); /* galleri-læsegrid */
  --ug-galleri-kolonner-rediger: repeat(auto-fill, minmax(10rem, 1fr)); /* galleri-editgrid (facit .gf-grid) */
  --ug-galleri-flise-format: 4 / 3; /* galleri-læsegrid billedformat-fallback */
  --ug-galleri-scrim: rgb(0 0 0 / 55%); /* hovedbillede-/grip-badge scrim på thumbnails (facit .gf-ord) */

  /* Beskærings-laget (ug-billede-felt, ug3-gytm8 — facit billede-upload.js +
     redform.css .bf-*). Strukturelle literaler bor HER i token-laget (L3);
     elementet refererer tokens. Ramme/gitter er faste lyse værdier — de
     tegnes OVEN PÅ fotoet og må ikke følge temaet. */
  --ug-beskaering-ramme: rgb(255 255 255 / 95%); /* crop-rammens kant (facit .bf-frame 2px solid #fff) */
  --ug-beskaering-ramme-bredde: 2px;
  --ug-beskaering-scrim: 0 0 0 999rem rgb(15 23 26 / 50%); /* mørklægning uden for rammen (facit .bf-frame box-shadow) */
  --ug-beskaering-gitter: linear-gradient(rgb(255 255 255 / 50%) 1px, transparent 1px), linear-gradient(90deg, rgb(255 255 255 / 50%) 1px, transparent 1px); /* tredjedels-gitter (facit .bf-grid) */
  --ug-beskaering-gitter-net: 33.33% 33.33%; /* gitterets 3×3-inddeling (background-size) */
  --ug-beskaering-gitter-daek: 0.85; /* gitterets opacity under træk (facit .bf-frame.grabbing .bf-grid) */
  --ug-beskaering-gitter-fade: opacity 0.12s ease; /* gitterets ind-/udtoning (facit .bf-grid transition) */
  --ug-beskaering-scene-bredde: 16rem; /* redigerings-scenens kolonne (facit .bf-editor 256px) */
  --ug-beskaering-preview-bredde: 10.5rem; /* oversigts-preview-kortet (facit .bf-output 168px) */
  --ug-beskaering-drop-maks: 18.75rem; /* dropzonens maksbredde (facit .bf-drop 300px) */
  --ug-beskaering-contain-maks: 84%; /* skaler-visningens contain-luft (facit .bf-contain max 84%) */
  --ug-media-contain: contain; /* skaler-politikkens object-fit — beskær ALDRIG (facit .bf-contain) */
  --ug-checker: linear-gradient(45deg, var(--ug-surface-sunk) 25%, transparent 25%), linear-gradient(-45deg, var(--ug-surface-sunk) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--ug-surface-sunk) 75%), linear-gradient(-45deg, transparent 75%, var(--ug-surface-sunk) 75%); /* skaler-visningens transparens-checker (facit .bf-checker) */
  --ug-checker-size: 16px 16px;
  --ug-checker-position: 0 0, 0 8px, 8px -8px, -8px 0;

  /* Login-split grid-ratio — facit .split grid-template-columns: 1.05fr 1fr
     (co-brand-panel : login-kort). Ét hjem for forholdet: ramme-login.css'
     .split-grid OG rel-login-splits udtryks-token peger begge hertil. */
  --ug-split-login: 1.05fr 1fr;

  /* Dashboard-række grid-ratio — facit dashboard-tilpas.js 'Drift'-preset: bredt +
     smalt sektionskort (m+s) deler en række. Ét hjem for forholdet: rel-dashboard-
     raekkes udtryks-token peger hertil (samme L3-mønster som --ug-split-login). */
  --ug-dashboard-raekke: 2fr 1fr;
  /* KPI-flisens indre alignment — facit samlet.css .kpi (venstrestillet stak);
     rel-kpi-flises udtryks-token peger hertil. */
  --ug-kpi-flise-align: flex-start;
  /* Knap-stak-justering (knap-og-ikon-dom A2, bundt C.5 → center 2026-07-20) — en
     wa-stack af RENE knapper (grp-sekundaere-metoder, grp-genveje-liste,
     grp-messevalg-liste) må ikke strække sine knapper til fuld bredde: knap-bredde
     er ALTID auto. Knapper der står i en LISTE centreres (Johannes 2026-07-20) —
     ét token rammer alle tre lister på tværs af flader (login, udstiller-dashboard,
     messe-menu/post-rediger). Stakkens udtryks-token peger hertil (C8 kræver et
     token, ikke literalen "center"; samme L3-mønster som --ug-kpi-flise-align). Kun
     rene knap-stakke bruger den — en blandet form-stak (input + knap) beholder
     stretch, så feltet forbliver fuldbredde mens knappen af sig selv står auto
     (wa-button er inline-block; enlige knapper centreres IKKE — kun lister). */
  --ug-knap-stak-align: center;
  /* Intro-modalens nav-klynge justering — den enlige synlige Næste (trin fjernet,
     Tilbage skjult på slide 1) skal centreres; rel-intro-navs udtryks-token peger
     hertil (C8 kræver et token, ikke literalen "center"). Samme L3-mønster som
     --ug-kpi-flise-align. */
  --ug-intro-nav-justify: center;
  /* Liste-række/sektion-hoved-divider — facit components.css .w-list li + li
     border-top. Style-leddet som token så rel-*-raekke + rel-sektion-hoved kan
     udtrykke divideren C8-rent (width/color er allerede --wa-/--ug-tokens). */
  --ug-divider-style: solid;
  /* Fane-bånd-geometri (ug3-6nqle — facit redform.css §6 bruger wa-tab-group,
     hvis indikator overlejrer tracket uden at bidrage til fanens højde).
     Topline: fane-listernes labels deler topline uanset aktiv-stak-højde
     (aktivstregen må ikke løfte den aktive fane — wa-cluster centrerer ellers).
     Indryk: redform-listen trækkes ét fane-padding til venstre så første label
     flugter med indholdet under (facit-intentionen i redform.css:127's
     part(tabs) padding-left:0; §6:153's shorthand overrider den i facit-
     cascaden, men flush-labels er det mockup-godkendte mål). Samme L3-mønster
     som --ug-kpi-flise-align (C8 kræver tokens, ikke literaler). */
  --ug-fane-topline: flex-start;
  --ug-fane-indryk: calc(-1 * var(--ug-space-s));

  /* Udstillerside read-panel (facit udstiller-indhold .pf-*, målt — plan
     2026-07-05 §2). L3: literalerne bor HER; relations-udtrykkene refererer
     tokens (rel-udstillerside + rel-udstillerside-felter). */
  --ug-split-udstillerside: minmax(0, 1fr) 20rem; /* .pf-wrap 1fr 320px; kollaps <860px redefineres nedenfor */
  --ug-laesefelt-kolonner: 1fr 1fr;               /* .pf-fields 2 kolonner (ingen facit-kollaps) */
  --ug-measure-laesefelter: 40rem;                /* .pf-fields max-width 640px */
  --ug-term-raekke-kolonner: minmax(0, 1fr) auto; /* term-række: read-felt vokser, Fjern-handling naturlig bredde (ug3-72lwo) */

  /* Tal-tabellens kolonne-spor (ug3-iwv8o.2.75): navne-kolonnen lidt bredere,
     tal-kolonnerne lige brede. Ét spor pr. celle i en linje; pinnet af
     TestTalTabelSpor_RealRegistry. */
  --ug-tal-tabel-kolonner: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);

  /* Indhold-plus-handling-rækken (ug3-e2e7a): indholdet vokser til venstre, ÉN
     handling står i naturlig bredde til højre. Samme værdi og samme begrundelse
     som --ug-term-raekke-kolonner ovenfor — men et EGET token, fordi de to har
     forskellige konsumenter og skal kunne bevæge sig hver for sig; term-rækkens
     navn ville desuden lyve på en top-bar og i et velkomst-banner.
     Konsument: rel-indhold-handling (flade-topbar + fane-bånds-række). Disse to
     KOLLAPSER IKKE på mobil: deres venstre kolonne er et tilbage-link/fane-bånd,
     ikke prosa, og målt i dev-browser ved 390px står knappen ved siden af uden
     overløb (scrollWidth 375 ≤ 390) mens fanerne selv ombryder. */
  --ug-indhold-handling-kolonner: minmax(0, 1fr) auto;
  /* «Dit program»s agenda-række (ug3-rlpfn.10.3.5, rel-program-raekke): tids-
     kolonnen i sin egen bredde, så den flugter på tværs af rækker, tekst-delen
     fyldende og side-kolonnen i naturlig bredde. Tids-kolonnen smalner på en
     smal skærm, så tekst-delen beholder sin plads. */
  --ug-program-tid-bredde: clamp(4.25rem, 12vw, 5.5rem);
  --ug-program-raekke-kolonner: var(--ug-program-tid-bredde) minmax(0, 1fr) auto;
  /* Side-kolonnen (rel-program-side): medlemmerne flyder side om side og står ved
     kolonnens ende; til/fra-knappen vælger selv sin linje. */
  --ug-program-side-kolonner: none;
  --ug-program-side-flow: column;
  --ug-program-side-justify: end;
  --ug-program-side-align: start;
  /* Side-kolonnens linje under prik-linjen — etiket-knappens plads. */
  --ug-program-side-etiket-linje: 2;
  /* Et tidsrum står i sin smalleste bredde, så det brydes efter tankestregen. */
  --ug-program-tidsrum-bredde: min-content;
  /* Et tegn tegnet af to kanter på en kasse drejes en ottendedel omgang. */
  --ug-tegn-drejning: 45deg;
  /* «Mine enheder»s ene justering, center | start (ug3-e624h). Embed-
     fallbacken pinnes af TestBesoegsTokenBro_FallbacksMatcherGalleriet. */
  --ug-enheder-justering: center;
  /* Velkomst-bannerets to-kolonne (ug3-e2e7a). Samme værdi som ovenfor, men et
     EGET token fordi banneret SKAL kollapse på mobil og de to top-bar-rækker
     ikke skal: venstre kolonne er her prosa, som ved 390px ellers ombryder over
     ~6 linjer i en smal spalte med knappen ved siden af. Token-redefinitionen
     nedenfor er scopet på tokenets navn, så den kan kun ramme denne relation. */
  --ug-velkomst-kolonner: minmax(0, 1fr) auto;

  /* Messe-logo-placeholder (ph-logo, auth.css:64) — dashed hvid-på-brand mærke.
     Faste dimensioner + facit-dekorations-alfaer; samme component-token-mønster
     som --ug-otp-… og --ug-ikon-size. Hvid-alfaerne er ph-logo-specifikke
     (matcher ikke --ug-on-brand-…-trinene), så de bor her med facit-værdierne
     verbatim. NB: skriv ALDRIG et glob-mønster der ender på «*» efterfulgt af
     «/» i en kommentar — «* /»-sekvensen lukkede kommentaren for tidligt og fik
     parseren til at æde --ug-ph-logo-h (avatar 0x0 på login/claim, 2026-07-16). */
  --ug-ph-logo-h:        2.875rem; /* 46px — height */
  --ug-ph-logo-min-w:    7.5rem;   /* 120px — min-width */
  --ug-ph-logo-pad-x:    1rem;     /* 16px — vandret padding */
  --ug-ph-logo-radius:   0.5625rem;/* 9px — placeholder-radius (ikke en B1-form) */
  --ug-ph-logo-border:   0.0625rem;/* 1px — dashed kant-bredde */
  --ug-ph-logo-fill:     rgba(255,255,255,.10); /* flade + gradient-streger */
  --ug-ph-logo-border-c: rgba(255,255,255,.35); /* dashed kant-farve */
  --ug-ph-logo-ink:      rgba(255,255,255,.85); /* tekst-farve */
  --ug-ph-logo-stripe:   repeating-linear-gradient(135deg, var(--ug-ph-logo-fill) 0 0.4375rem, transparent 0.4375rem 0.875rem); /* 7px/14px diagonal */

  /* ug-billede containerformater (DDR-0008) — component tokens for the
     generalised image atom. Box values from the 2026-07-16 valg-side's
     demo-containers; a composing context retunes them per instance. The
     radius follows the canonical kort/information radius; the band height
     matches the ph-logo mark so co-brand stacks don't jump. Focus point
     (--ug-billede-fokus) is deliberately NOT defaulted here: it is per-image
     crop DATA (upload-reframe), and the element carries the 50% 50% fallback
     under its C8e: DDR-0008 valve. */
  --ug-billede-hoej-w:   4.125rem; /* 66px — portrait box width */
  --ug-billede-hoej-h:   6.25rem;  /* 100px — portrait box height */
  --ug-billede-kvadrat:  4.5rem;   /* 72px — square box side */
  --ug-billede-tvaer-w:  10rem;    /* 160px — landscape box width */
  --ug-billede-tvaer-h:  4.5rem;   /* 72px — landscape box height */
  --ug-billede-baand-h:  2.875rem; /* 46px — band height (= --ug-ph-logo-h) */
  --ug-billede-plade-w: 100%;   /* plade fills the composing container's inline extent */
  --ug-billede-plade-h: 12rem;  /* gallery default; the composing context retunes (DDR-0008) */
  --ug-billede-radius:   var(--ug-radius); /* image-frame radius (kanonisk kort-radius) */
  /* Flise (media-first card/thumb, medie-kort mockup 2026-07-19): fills the
     composing container's width and derives height from the ratio. Defaults =
     the 4/3 card face; the composing table context retunes w/h to the 96×64
     thumb. Radius 0 so the card kasse's own rounded frame owns the corners. */
  --ug-billede-flise-w:      100%;   /* fill the composing container's inline extent */
  --ug-billede-flise-h:      auto;   /* height follows the ratio, not a fixed box */
  --ug-billede-flise-ratio:  4 / 3;  /* card-face aspect (mockup .medie aspect-ratio:4/3) */
  --ug-billede-flise-radius: 0;      /* the card frame clips the corners, not the tile */

  /* ── Knap-takter (knap-og-ikon-domme A1 + A3, bundt C.3) ──────────────────
     De tre størrelses-takter i knap-hierarkiet. Rå skala HER; C.4 tildeler
     takterne pr. klods (A1-mappingen) + bygger den runde ikon-knap. Tokenene
     er inerte indtil en klods refererer dem — C.3 ændrer INTET render.
       Takt 1 — Handling (44px): CTA/Pop, én pr. flade (WA size="m").
       Takt 2 — Sektion  (34px): brand-solid/outline-pille/danger (size="s").
       Takt 3 — Inline   (28px): plain + kompakt outline-pille (size="s").
     Højde-tokenet overstyrer WA's size-afledte højde OG den size-koblede interne
     padding (takt 2+3 deler size="s" og ville ellers kunne drive fra hinanden)
     — C.4 wirer --ug-knap-h/-pad til WA's --wa-form-control-height/-padding-inline.
     Længder i rem (÷16) efter repo-idiomet; px i kommentar. */
  --ug-knap-h-l:    2.75rem;   /* 44px — takt 1 højde */
  --ug-knap-h-m:    2.125rem;  /* 34px — takt 2 højde */
  --ug-knap-h-s:    1.75rem;   /* 28px — takt 3 højde */
  --ug-knap-font-l: 0.95rem;   /* takt 1 label-font */
  --ug-knap-font-m: 0.84rem;   /* takt 2 label-font */
  --ug-knap-font-s: 0.78rem;   /* takt 3 label-font */
  --ug-knap-pad-l:  0.875rem;  /* 14px — padding-inline (A3: 0,32×h) */
  --ug-knap-pad-m:  0.6875rem; /* 11px */
  --ug-knap-pad-s:  0.5625rem; /* 9px */
  --ug-knap-gap-l:  0.375rem;  /* 6px — ikon-til-tekst gap (moderat, strammere end WA's 0.75em-default) */
  --ug-knap-gap-m:  0.3125rem; /* 5px */
  --ug-knap-gap-s:  0.25rem;   /* 4px */
  /* Ikon-størrelse pr. takt (A3: 0,58×h). Sat af KONTEKSTEN (glyph-dommen A4:
     atomet definerer tegnet, ikke størrelsen); disse er de kanoniske knap-mål
     som en komponerende kontekst sætter via --ug-glyph-size. Bruges også som
     ikon-leddet i koncentrisk-formlen nedenfor. */
  --ug-knap-ikon-l: 1.625rem;  /* 26px */
  --ug-knap-ikon-m: 1.25rem;   /* 20px */
  --ug-knap-ikon-s: 1rem;      /* 16px */
  /* Rod-default for et glyph-atom uden komponerende kontekst: 1em = den
     nedarvede skriftstørrelse, dvs. samme udfald som en udeklareret var()
     giver font-size. Konteksten sætter stadig sin egen (nærmere) værdi. */
  --ug-glyph-size: 1em;
  /* Koncentrisk-reglen (A3): et CIRKULÆRT ikon (aflys/ban, circle-info, rotate)
     i en pille lægges koncentrisk med endebuen → padding-inline-start =
     (højde − ikon)/2. Værdierne udledt: (44−26)/2=9, (34−20)/2=7, (28−16)/2=6.
     Kantede ikoner bruger takt-paddingen (--ug-knap-pad-*), IKKE denne. */
  --ug-knap-koncentrisk-l: 0.5625rem; /* 9px */
  --ug-knap-koncentrisk-m: 0.4375rem; /* 7px */
  --ug-knap-koncentrisk-s: 0.375rem;  /* 6px */
  /* ── Rund ikon-knap (knap-og-ikon-domme A2/A5/A7, bundt C.4) ───────────────
     Den ikon-only runde knap: en takt-3-cirkel (28px = --ug-knap-h-s) med bart,
     koncentrisk centreret ikon (16px = --ug-knap-ikon-s). Formen deles via
     data-ug-knap-rund; FLADEN (accent/danger/neutral efter klodsens rolle) + ink-
     sættet sætter hver klods selv (A5/A7). Tokenene her styrer det usynlige
     touch-target og hover-/fokus-ringen. */
  --ug-knap-touch-min:      2.75rem;  /* 44px — usynligt hit-areal (A2: ≥40px, WA/WCAG-mål) */
  --ug-knap-rund-ring-bredde: 0.1875rem; /* 3px fokus-/hover-ring (jf. --ug-otp-ring) */
  /* Ring-tinten: default en dæmpet brand-fokus-ring (neutrale + additive runde
     knapper); danger-runde klodser re-mapper den til en danger-tint hos sig selv. */
  --ug-knap-rund-ring:      color-mix(in srgb, var(--ug-brand) 30%, transparent);
  --ug-knap-rund-ring-danger: color-mix(in srgb, var(--ug-danger) 32%, transparent);
}

/* ── WA layout-utility gap: honorér den INLINE --wa-gap-token'en ─────────────
   Grammatikkens [udtryk.tokens] emitterer en per-instans gap som en INLINE
   style="--wa-gap: …" på relations-wrapperen (udtrykToWrapper, compose.go) — E2
   tillader kun ÉN utility-klasse, så gap KAN ikke udtrykkes som en wa-gap-*-klasse.
   Men WA's egen layout.css læser KUN var(--wa-space-m), så --wa-gap var en no-op og
   hver relations gap faldt til WA-default'en (m). Denne shim læser --wa-gap.

   KRITISK — scopet til [style*='--wa-gap']: look.css er ULAGDELT, og WA's gap-regler
   (BÅDE :where()-default'en OG hele wa-gap-*-utility-familien) bor i @layer wa-utilities.
   Ulagdelt slår ALTID lagdelt (uanset specificitet), så en USCOPET [class*='wa-cluster']
   ville også klobre en eksplicit .wa-gap-2xs/.wa-gap-l på samme element (galleri-chrome
   som elementer.gohtml's `wa-cluster wa-gap-2xs` → tvunget til m). [style*='--wa-gap']
   matcher KUN relations-wrapperne (som sætter --wa-gap inline); chrome der bruger
   wa-gap-*-KLASSER har ingen inline --wa-gap → urørt, dens wa-utilities-gap vinder.
   (Tidligere kommentar her ræsonnerede forkert om specificitet; mekanismen er lag-
   præcedens — #1814-review fund, fast-follow.) */
[class*='wa-cluster'][style*='--wa-gap'], [class*='wa-stack'][style*='--wa-gap'],
[class*='wa-grid'][style*='--wa-gap'], [class*='wa-flank'][style*='--wa-gap'],
[class*='wa-split'][style*='--wa-gap'], [class*='wa-frame'][style*='--wa-gap'] {
  gap: var(--wa-gap, var(--wa-space-m));
}

/* ── Udstillerside-splittets kollaps (facit .pf-wrap @media max-width:860px →
   én kolonne, meta-kortet stables under felterne). rel-udstillersides udtryk
   emitterer grid-template-columns: var(--ug-split-udstillerside) INLINE, så
   kollapset kan ikke bo i en media-regel på selve egenskaben (inline slår
   stylesheet) — det redefinerer i stedet TOKENEN på wrapperen, som var()
   resolver mod. Scopet til [style*='--ug-split-udstillerside'] efter samme
   mønster som --wa-gap-shimmen ovenfor (rammer kun relations-wrapperen).
   TO triggere, SAMME redefinition (ug-rediger-flade/ug-topbar-user-mønstret):
   @container for galleriets preview-kort (query containers, .gal-viewport-body)
   og @media for den reelle viewport (standalone render/cockpits uden container). */
@container (max-width: 860px) {
  [style*='--ug-split-udstillerside'] { --ug-split-udstillerside: minmax(0, 1fr); }
}
@media (max-width: 860px) {
  [style*='--ug-split-udstillerside'] { --ug-split-udstillerside: minmax(0, 1fr); }
}

/* ── Dashboard-rækkens kollaps på smal viewport (2fr/1fr → én fuld-bredde kolonne,
   widgets stablet lodret). rel-dashboard-raekke emitterer grid-template-columns:
   var(--ug-dashboard-raekke) INLINE, så kollapset kan ikke bo i en media-regel på
   selve egenskaben (inline slår stylesheet) — det redefinerer i stedet TOKENEN på
   wrapperen, som var() resolver mod. MEKANISMEN er nøjagtigt --ug-split-udstillerside-
   mønstret ovenfor (token-redefinition + @container/@media dobbelt-trigger); kun
   BREAKPOINTEN er en anden: 640px her (ikke read-panelets facit-baserede 860px), fordi
   dashboard-rækkens smalle højre-kolonne (kontakt-form, 1fr) forbliver brugbar længere
   ned end read-panelets nær-lige split — bevidst divergens, ikke en stray værdi.
   TO triggere, SAMME redefinition: @container for galleriets preview-kort (query
   containers) og @media for den reelle viewport (standalone render/cockpits). Rammer
   også admin-dashboardets rækker (grp-dashboard-raekke-*, samme delte relation) — de
   kollapser nu ligeledes korrekt på mobil. */
@container (max-width: 640px) {
  [style*='--ug-dashboard-raekke'] { --ug-dashboard-raekke: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  [style*='--ug-dashboard-raekke'] { --ug-dashboard-raekke: minmax(0, 1fr); }
}

/* ── Velkomst-bannerets kollaps på smal viewport (ug3-e2e7a, Johannes 2026-07-31):
   to-kolonne → én fuld-bredde kolonne, så Vis-introduktion-knappen falder UNDER
   hilsen/underteksten i stedet for at klemme prosaen ned i en smal spalte (målt
   ved 390px: teksten ombrød over 6 linjer). rel-velkomst-split emitterer
   grid-template-columns: var(--ug-velkomst-kolonner) INLINE, så kollapset kan
   ikke bo i en media-regel på selve egenskaben (inline slår stylesheet) — det
   redefinerer i stedet TOKENEN på wrapperen, som var() resolver mod. MEKANISMEN
   er nøjagtigt --ug-dashboard-raekke-/--ug-split-udstillerside-mønstret ovenfor
   (token-redefinition + @container/@media dobbelt-trigger), og BREAKPOINTEN er
   dashboard-familiens 640px — banneret ER en dashboard-widget og bør kollapse
   sammen med rækkerne omkring det, ikke ved read-panelets 860px.
   Bevidst scopet til dette token alene: de to top-bar-rækker deler arrangementet
   men IKKE kollapset (se --ug-indhold-handling-kolonner). */
@container (max-width: 640px) {
  [style*='--ug-velkomst-kolonner'] { --ug-velkomst-kolonner: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  [style*='--ug-velkomst-kolonner'] { --ug-velkomst-kolonner: minmax(0, 1fr); }
}

/* ── Dashboard-widget grid-footprint (ug3-2ua0c) ─────────────────────────────
   Composeren wrapper hvert placerings-medlem i <div class="sz-s|m|l"> (wrapSize,
   compose.go). Fase 1 (#2139) shippede wrapperen men UDSKØD grid-CSS'en; denne
   task (2.1.3) er første flade der emitter sz-klasser, så footprinten defineres
   her. grid-column-span virker KUN i en grid-container; admin-dashboardets
   container er rel-dashboard-admin-stak (wa-stack = flex-column), hvor
   grid-column er inert → widgets forbliver fuld-bredde (korrekt for den lodrette
   stak). Definitionen gør klasserne meningsfulde den dag en widget sidder i en
   ægte grid (fx et fremtidigt fler-kolonne-dashboard), uden at røre den nuværende
   stak. WA har ingen utility for en per-barn column-span, så custom er berettiget. */
.sz-s { grid-column: span 1; }
.sz-m { grid-column: span 2; }
.sz-l { grid-column: 1 / -1; }

/* ── Dashboard edit-mode "Tilpas"-chrome (ug3-2ua0c.2.1.3) ───────────────────
   Toolbar + per-widget editbar + widget-bibliotek, injiceret gennem
   uirender.EditChrome (kun i edit-visningen; normal-visningen emitter intet af
   dette). Alt på --ug-*-tokens; ingen nye farver. WA-utilities dækker ikke en
   sticky, bordered værktøjslinje med badge/segment-aktioner, så custom-klasser
   er berettiget (::part/utility ville ikke være enklere). */
.ug-dash-toolbar {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--ug-space-m); flex-wrap: wrap;
  margin-bottom: var(--ug-space-m);
  padding: var(--ug-space-s) var(--ug-space-m);
  border: var(--wa-border-width-s) solid var(--ug-brand-line);
  border-radius: var(--ug-radius);
  background: var(--ug-surface);
  box-shadow: var(--ug-shadow);
}
.ug-dt-id { display: flex; align-items: center; gap: var(--ug-space-s); min-width: 0; flex-wrap: wrap; }
.ug-dt-badge {
  display: inline-flex; align-items: center; gap: var(--ug-space-2xs);
  padding: var(--ug-space-2xs) var(--ug-space-xs);
  border-radius: var(--ug-radius-s);
  background: var(--ug-brand-strong); color: #fff;
  font-family: var(--ug-mono); font-size: var(--ug-text-2xs);
  font-weight: var(--ug-weight-bold); letter-spacing: var(--ug-tracking-label);
  text-transform: uppercase; white-space: nowrap;
}
.ug-dt-ctx { font-size: var(--ug-text-s); color: var(--ug-text-quiet); }
.ug-dt-ctx b { color: var(--ug-text); font-weight: var(--ug-weight-semibold); }
.ug-dt-actions { display: flex; align-items: center; gap: var(--ug-space-2xs); flex-wrap: wrap; }

/* Per-widget editbar: en bar øverst i widget-cellen med Skjul (eller Fast-lås). */
.ug-widget-edit { position: relative; }
.ug-editbar {
  display: flex; align-items: center; gap: var(--ug-space-xs);
  flex-wrap: wrap; margin-bottom: var(--ug-space-2xs);
  padding: var(--ug-space-2xs) var(--ug-space-xs);
  border: var(--wa-border-width-s) dashed var(--ug-border-strong);
  border-radius: var(--ug-radius-s);
  background: var(--ug-surface-sunk);
}
.ug-editbar-label { font-size: var(--ug-text-xs); font-weight: var(--ug-weight-semibold); color: var(--ug-text-quiet); }
.ug-editbar-spring { flex: 1; }
.ug-editbar-fixed {
  display: inline-flex; align-items: center; gap: var(--ug-space-2xs);
  font-size: var(--ug-text-xs); color: var(--ug-text-faint);
}
.ug-toggle-form { display: inline-flex; margin: 0; }

/* Toolbar sprog-segment (ug3-2ua0c.2.5.1) + "Sætter op for"-target-vælger
   (ug3-2ua0c.2.4.1). Segment-layout ejes af wa-cluster + wa-gap-xs i
   tilpas-toolbar.html; her kun label-styling (delt regel). */
.ug-dt-sprog-label,
.ug-dt-target-label {
  display: inline-flex; align-items: center; gap: var(--ug-space-2xs);
  font-size: var(--ug-text-xs); color: var(--ug-text-quiet);
}

/* Inline i18n-panel (designets w-i18n): felt pr. flagget i18n-felt under widgetten.
   Stak/klynge ejes af wa-stack/wa-cluster i tilpas-i18n.html; her kun de
   ikke-WA-dækkede regler (ramme, baggrund, radius, typografi, farve). */
.ug-i18n-panel {
  margin-top: var(--ug-space-2xs);
  padding: var(--ug-space-s);
  border: var(--wa-border-width-s) dashed var(--ug-border-strong);
  border-radius: var(--ug-radius-s);
  background: var(--ug-surface-sunk);
}
.ug-i18n-head {
  font-size: var(--ug-text-xs); color: var(--ug-text-quiet);
}
.ug-i18n-head b { color: var(--ug-text); }
.ug-i18n-sub { font-size: var(--ug-text-2xs); color: var(--ug-text-faint); }
.ug-i18n-form { margin: 0; }
.ug-i18n-mangler {
  display: inline-flex; align-items: center; gap: var(--ug-space-2xs);
  font-size: var(--ug-text-2xs); color: var(--ug-warning-text);
}

/* Relations-kobling drawer-fragmentets gruppe-overskrifter («Valgte <label>» +
   typenavn, .drawer-gruppe-overskrift): Johannes' rytme-regel (prototype-facit) —
   LUFTEN sidder OVER overskriften (stor margin-top = gruppe-adskillelsen), og
   overskriften sidder TÆT på egne rækker (ingen margin-bottom). Fragment-h3 har
   intet element-CSS-hjem, så reglen bor i det delte bundt der også renderes på
   post-rediger-draweren. Token-only. */
.drawer-gruppe-overskrift {
  margin-block: var(--ug-space-l) 0;
  display: flex; align-items: baseline; gap: var(--ug-space-xs);
}
/* Koblede-tællertal ved siden af «Valgte <label>»-overskriften (prototype-facit
   .proto-gruppe-antal): dæmpet, medium vægt, i footnote-størrelse. Rendres kun
   når der ER koblede — prototypen viser aldrig «0». */
.drawer-gruppe-antal {
  font-size: var(--ug-text-s);
  font-weight: var(--ug-weight-medium);
  color: var(--ug-text-quiet);
}

/* Drag-grip + S/M/L-størrelsesvalg i editbaren (ug3-2ua0c.2.2.1). Grip-måltal fra
   design-facittet (dashboard-tilpas.css .w-grip), oversat til --ug-tokens. Custom
   CSS er berettiget for grippet (WA har intet draggable håndtag); størrelses-
   knapperne er rene wa-buttons (pill, filled/plain) og behøver kun tæt gap. */
.ug-w-grip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--ug-radius-s);
  color: var(--ug-text-faint); cursor: grab; flex: none;
}
.ug-w-grip:hover { background: var(--ug-surface-sunk); color: var(--ug-brand); }
.ug-w-grip:active { cursor: grabbing; }
.ug-w-grip wa-icon { font-size: 14px; }
.ug-w-size { display: inline-flex; align-items: center; gap: 2px; }

/* Drag-tilstande (tilpas-dragjs.html): den trukne widget dæmpes; drop-målet
   markeres med brand-outline (widget indsættes FØR målet ved drop). */
.ug-widget-edit.ug-dragging { opacity: .45; }
.ug-widget-edit.ug-drag-over { outline: 2px solid var(--ug-brand); outline-offset: 2px; border-radius: var(--ug-radius-s); }

/* Widget-bibliotek (wa-drawer indhold). */
.ug-wlib-intro { margin: 0 0 var(--ug-space-m); font-size: var(--ug-text-s); color: var(--ug-text-quiet); line-height: 1.5; }
.ug-wlib-item {
  display: flex; align-items: center; gap: var(--ug-space-s);
  padding: var(--ug-space-s);
  border: var(--wa-border-width-s) solid var(--ug-border-quiet);
  border-radius: var(--ug-radius);
  margin-bottom: var(--ug-space-2xs);
  background: var(--ug-surface);
}
.ug-wlib-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.ug-wlib-t { font-size: var(--ug-text-s); font-weight: var(--ug-weight-semibold); color: var(--ug-text); }
.ug-wlib-empty { margin: 0; font-size: var(--ug-text-s); color: var(--ug-text-faint); }

/* ── Medlems-status er en attribut, aldrig en boks (ug3-cjcdm) ───────────────
   markStatus (compose.go) sætter data-ug-status direkte på medlemmets eget
   rod-tag — der er ingen wrapper, så DOM'en er den samme i kladde og godkendt,
   og klodsernes søskende-selektorer (+ / ~) rammer i begge. Giv ALDRIG
   [data-ug-status] en display-regel: den ville ramme medlemmets egen boks
   (TestLookCSS_StatusAttributGiverIngenBoks). */

/* Søgefiltret (ug-cmdk-search) skjuler ikke-matchende rækker via hidden-attribut
   på .wa-cluster-rækken. Rækkens egen display:flex (author-origin) slår
   UA-stylesheetets [hidden]{display:none} → uden dette forbliver rækken synlig.
   Specificity (0,2,0) slår (0,1,0) → intet !important. Samme mønster som
   .gal-cmp-tray[hidden] nedenfor. */
.wa-cluster[hidden] { display: none; }

/* ── Dæmpet-markør (composer-injiceret, ug3-ml7au) ───────────────────────────
   Gentagelse.Daempet → data-ug-daempet="ja" på forekomstens boks-element; selve
   boksen dæmpes. Substrat-regel her, ikke element-CSS: markøren er composer-ejet. */
[data-ug-daempet] { opacity: 50%; }

/* ── ov-pillmenu · række-fladen (render-tilstand på overlay-niveau) ──────────
   grp-cmdk-raekke's manifest erklærer pr.-række-fladen (padding/hover/aktiv) som
   render-tilstand på liste-/overlay-niveau — bevidst IKKE en del af den statiske
   komposition. Hele den tilstand bor her, scoped til paletten. Orakel-fladen
   shell (.menu-item): padding 10px 12px → --ug-space-s-u / --ug-space-s, radius,
   hover → --ug-row-hover; keyboard-highlight (.menu-item.kbd-on, sat af
   ug-cmdk-search's ↓/↑) deler hover-baggrunden; aktiv (.menu-item.on = nuværende
   side) → --ug-brand-quiet baggrund + --ug-brand-strong etiket. Oraklets egen
   .wa-dark-variant er unødvendig: --ug-brand-quiet/-strong tema-flipper selv
   (look.css' dark-blok). Markører er data-attributter i data-ug-*-namespacet
   ([data-ug-kbd] JS-sat, [data-ug-aktiv] host/JS-sat) — aldrig klasser på
   composer-emitteret markup. Aktiv-reglerne står EFTER kbd-reglen så aktiv
   vinder når begge er sat (samme kaskade-orden som oraklet). Token-only.
   NB: selektoren følger rel-cmdk-raekkes utility (wa-cluster) — skifter
   udtrykket utility, skal selektoren med. */
[data-ug-overlay="ov-pillmenu"] .wa-cluster[data-ug-id="grp-cmdk-raekke"] {
  padding-block: var(--ug-space-s-u);
  padding-inline: var(--ug-space-s);
  border-radius: var(--ug-radius);
  cursor: pointer;
}
[data-ug-overlay="ov-pillmenu"] .wa-cluster[data-ug-id="grp-cmdk-raekke"]:hover,
[data-ug-overlay="ov-pillmenu"] .wa-cluster[data-ug-id="grp-cmdk-raekke"][data-ug-kbd] {
  background: var(--ug-row-hover);
}
[data-ug-overlay="ov-pillmenu"] .wa-cluster[data-ug-id="grp-cmdk-raekke"][data-ug-aktiv] {
  background: var(--ug-brand-quiet);
}
[data-ug-overlay="ov-pillmenu"] .wa-cluster[data-ug-id="grp-cmdk-raekke"][data-ug-aktiv] ug-cmdk-label {
  color: var(--ug-brand-strong);
}

/* ── grp-medie-chips i KOMPAKT tæthed · én chip-linje (ug3-iav9l) ────────────
   Johannes' billedgennemgang 2026-08-27: i kompakt-kortet blev chip-teksten
   skåret af ved kortets kant uden luft, og «Brugt N» ombrød til egen linje.
   Målformen er ÉN linje: messenavnet ellipserer i den plads der er, og
   tælleren står yderst til højre. Linje-tilstanden bor her frem for på en
   klasse på gruppen: gruppens medlemskaber står i
   groups/grp-medie-fod/manifest.toml, og en klasse ville ramme bredere end
   kompakt-kortet. Derfor: scoped til composerens gruppe-identitet
   (ov-pillmenu-præcedensen ovenfor). Nøglens skrump slås til via
   --ug-meta-noegle-flex, så ellipsen faktisk kan ske.
   SCOPET TIL KOMPAKT-KORTET: standard-tætheden er ikke den form ug3-iav9l
   ændrer, og en ellipse dér ville skjule data uden at være bedt om det.
   NB: selektoren følger den utility rel-kort-fods udtryk emitter — skifter
   den, skal selektoren med. TestMedieKompaktChip_DOMKontrakt er vagten. */
[data-ug-id="grp-medie-kort-kompakt"] .wa-cluster[data-ug-id="grp-medie-chips"] {
  flex-wrap: nowrap;
}
[data-ug-id="grp-medie-kort-kompakt"] .wa-cluster[data-ug-id="grp-medie-chips"] ug-meta-raekke {
  flex: 1;
  --ug-meta-noegle-flex: 0 1 auto;
}
[data-ug-id="grp-medie-kort-kompakt"] .wa-cluster[data-ug-id="grp-medie-chips"] ug-taeller-chip {
  flex: none;
  /* Right-aligned by its OWN margin, not by the info line's flex:1 — the line is
     data-conditional (a file with no confirmed reading omits it), and when it is
     gone nothing else pushes the counter over. Without this the pill sits left
     on exactly those cards and stops flush-aligning with its neighbours in the
     same grid. */
  margin-inline-start: auto;
}

/* ── ov-post-forhaandsvis · dialog-bredden (kompositions-chrome, ug3-e6743) ──
   Johannes' testrunde 2026-07-27: «selve modalen til previewet skal være
   bredere». WA-dialogens default --width klemmer preview-iframen så smal at
   publikums-modallen inde i den aldrig når kundens facit-bredde (Nicolines
   _modal.css: 560px) — den faldt tilbage til calc(100vw - 2rem) af IFRAMENS
   viewport. Fladen er composer-emitteret (ingen klods ejer wa-dialog-tagget),
   så breddereglen bor her som overlay-scoped chrome — ov-tidspunkt-drawer-
   mønstret nedenfor. 60rem giver Desktop-visningen rum til facit-modallen
   med luft; WA klipper selv ned på smalle viewports. */
wa-dialog[data-ug-overlay="ov-post-forhaandsvis"] {
  --width: 60rem;
}

/* ── ov-tidspunkt-drawer · drawer-bredden (kompositions-chrome) ──────────────
   Facit tidspunkt-drawer-model.html: draweren glider ind fra højre over
   rækkerne; ≤520px fylder den hele bredden (#drawer --size: 100vw). Fladen er
   composer-emitteret (ingen klods ejer wa-drawer-tagget), så breddereglen bor
   her som overlay-scoped chrome — samme mønster som ov-pillmenu ovenfor. */
@media (max-width: 520px) {
  wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] {
    --size: 100vw;
  }
}

/* ── ov-tidspunkt-drawer · Start/Slut på samme linje (facit .tider) ──────────
   Facit tidspunkt-drawer-model.html: de to tids-inputs står side om side i et
   to-spors grid (.tider { grid-template-columns: 1fr 1fr }). Formen er en
   composer-emitteret wa-stack hvis direkte børn er selve klodserne, så de er
   grid-items — geometrien bor her som overlay-scoped kompositions-chrome
   (bredde-reglen ovenfor er præcedensen). Formen bliver et to-spors grid: alle
   medlemmer spænder begge spor (tag-selektoren i Start/Slut-reglerne holder
   deres specificitet over catch-all'en), kun Start/Slut deler en række. Gap
   arver formens --wa-gap-shim. */
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] {
  display: grid;
  grid-template-columns: 1fr 1fr;
}
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] > * {
  grid-column: 1 / -1;
}
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] > ug-tidspunkt-start-input {
  grid-column: 1;
}
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] > ug-tidspunkt-slut-input {
  grid-column: 2;
}

/* ── ov-tidspunkt-drawer · handlingsknapper på ÉN linje (facit .dknapper) ─────
   Facit drawer-footeren: Tilføj (den brede primære) og Tilføj + nyt i én
   knap-række; Gemt-indikatoren står UNDER rækken som stille info (godkendt
   placering). Samme grid-chrome som Start/Slut: de to opret-knapper deler en
   række (spor 1 + 2, Tilføj som den fyldte primære i første spor), og deres
   wa-buttons fylder deres spor så rækken læser som facit'ens flex-række.
   Rediger-tilstandens Gem-knap beholder catch-all'ens fulde bredde (facit:
   den brede Gem ændringer); csrf-feltet er display:contents og Gemt-
   indikatoren auto-placeres på næste række under knapperne. */
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] > ug-tilfoej-tidspunkt-button {
  grid-column: 1;
}
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] > ug-tilfoej-og-nyt-button {
  grid-column: 2;
}
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] ug-tilfoej-tidspunkt-button wa-button,
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] ug-tilfoej-og-nyt-button wa-button,
wa-drawer[data-ug-overlay="ov-tidspunkt-drawer"] form[data-ug-id="grp-tidspunkt-form"] ug-gem-button wa-button {
  width: 100%;
}

/* Login-resend-formens send-igen-knap (F4-1 par 6 → auto+centreret 2026-07-20):
   arrangeringen flyttet HERTIL fra den slettede ug-send-igen-button, da knappen
   blev den delte ug-gensend-button (inline pille i invitations-rækkerne) —
   ADR-0043: konteksten (gruppens wrapper), ikke elementet, er kanalen for ren
   arrangering. grp-send-igen findes kun i login-fladens link-sendt-tilstand.
   Knap-bredde er auto (dom A2 — den tidligere inline-size:100% var et kontekst-
   scopet A2-brud som lint B.2 ikke fanger). Host beholder display:block så
   wa-button står som ren inline-block-atom (auto bredde). Centreret som UNDTAGELSE
   fra "kun lister centreres" (Johannes 2026-07-20): den enlige send-igen afløser
   link-sendt-tilstandens plads for de centrerede metode-knapper, så den skal stå
   centreret som dem. align-self:center pr. flex-item i grp-send-igens form-wa-stack. */
[data-ug-id="grp-send-igen"] ug-gensend-button {
  display: block;
  align-self: center;
}

/* ── Overlay footer-Luk · knap-anatomi (ug3-qchfj) ────────────────────────────
   The dialog/drawer footer close button (overlay.go's overlaySurfaceTmpls) is
   shared composition-chrome — it is baked into EVERY overlay surface, not a
   registry klods — so it never picked up a klods' own ::part(base) pill-rule
   the way ug-forhaandsvis-button/ug-annuller-button do (each scopes its own
   tag). Since there is no klods tag to scope on, the rule scopes on the
   shared .ug-overlay class (present on every wa-dialog/wa-drawer surface,
   overlaySurfaceTmpls) + the footer slot, matching those klodsers' B1 pill
   radius (var(--ug-radius-pill)). The .ug-knap/.ug-knap-m sizing classes are
   set directly in the overlay templates (Takt 2 — Sektion, size="s",
   same anatomy as ug-slet-aflys-i-stedet/ug-tilfoej-kandidat's
   variant="brand" pairing). */
.ug-overlay wa-button[slot="footer"]::part(base) {
  border-radius: var(--ug-radius-pill);
}

/* ══ Knap-anatomi (delt) — knap-og-ikon-domme A3, bundt C.3 ══════════════════
   Bomærke-idiomet centraliseret ÉT sted. C.3 leverer KUN infrastrukturen: den
   delte klasse .ug-knap + takt-modifikatorerne .ug-knap-l/-m/-s. INGEN klods
   bærer klassen endnu — C.4 tildeler takterne pr. A1-mappingen — så hele blokken
   er render-neutral (nul selektor-match på nuværende registry). Placeret som en
   klasse (ikke globale wa-button-regler) af to grunde: (1) render-neutralitet er
   garanteret ved nul-match frem for at afhænge af fallback-lighed; (2) slotted-
   nulstillingen KRÆVER en selektor der slår WA's shadow-::slotted på SPECIFICITET
   (se nedenfor) — klassen leverer den nødvendige vægt naturligt.

   Takt-valg: en modifikator peger de generiske «aktiv-takt»-tokens mod sin rå
   takt, og .ug-knap-basen læser KUN de generiske. C.4 sætter altså
   class="ug-knap ug-knap-m" (etc.) på wa-button'en — ét sted, ingen literaler. */
.ug-knap-l { --ug-knap-h: var(--ug-knap-h-l); --ug-knap-font: var(--ug-knap-font-l); --ug-knap-pad: var(--ug-knap-pad-l); --ug-knap-gap: var(--ug-knap-gap-l); }
.ug-knap-m { --ug-knap-h: var(--ug-knap-h-m); --ug-knap-font: var(--ug-knap-font-m); --ug-knap-pad: var(--ug-knap-pad-m); --ug-knap-gap: var(--ug-knap-gap-m); }
.ug-knap-s { --ug-knap-h: var(--ug-knap-h-s); --ug-knap-font: var(--ug-knap-font-s); --ug-knap-pad: var(--ug-knap-pad-s); --ug-knap-gap: var(--ug-knap-gap-s); }

/* Takt-mekanik: højde-tokenet overstyrer WA's size-afledte højde OG nulstiller
   den size-koblede interne padding (A1) ved at wire de aktive takt-tokens ind i
   WA's egne form-control-variabler — så takt 2 og takt 3 (begge size="s")
   ikke kan drive fra hinanden. Font sættes på hosten (WA's .button arver
   font-size: inherit). C7: ::part(base) er den eneste vej til den interne knap-
   flade — ingen WA-utility dækker per-takt højde/padding, så ::part er korrekt. */
.ug-knap {
  font-size: var(--ug-knap-font);
  --wa-form-control-height: var(--ug-knap-h);
  --wa-form-control-padding-inline: var(--ug-knap-pad);
}

/* Række-takten (ug3-pf5e7): Rediger-knappen er delt mellem kort-foden og
   tabelrækkens afsluttende celle, og en handling i en RÆKKE er én takt under
   den samme handling i en kort-fod (takt-doktrinen,
   docs/audit/2026-07-16-knap-hierarki-analyse.md). Takt-skiftet bor
   HER og ikke i tabel-kassens celle-kontekst: modifikatoren deklarerer de
   generiske aktiv-takt-tokens PÅ selve wa-button'en, så en nedarvet værdi fra
   cellen taber til klodsens egen klasse-deklaration uanset hvor dybt cellen
   sætter den. Scopet til rækkens handlings-vært, så kort-foden er uændret. */
ug-tabel-flade ug-rediger-button .ug-knap {
  --ug-knap-h: var(--ug-knap-h-s);
  --ug-knap-font: var(--ug-knap-font-s);
  --ug-knap-pad: var(--ug-knap-pad-s);
  --ug-knap-gap: var(--ug-knap-gap-s);
}

/* Slotted-margin-nulstilling (A3): WA's shadow-CSS lægger en fast ikon-til-tekst-
   afstand på det slottede led — `slot[name=start]::slotted(*){margin-inline-end:
   .75em}` og end-varianten (verbatim fra den chunk button.styles.js importerer;
   slå den op med `grep -rl "slot\[name='start'\]::slotted" cmd/gallery/static/wa/`).
   Vi ERSTATTER den med gap-tokenet, så tokenet er den ENESTE afstand. Det slottede
   led er glyph-wrapperen i LYS DOM (`<ug-*-glyph slot="start">…`), så en dokument-
   regel rammer den direkte. Cascade: WA's ::slotted-regel har specificitet (0,1,2)
   [slot-type + [name]-attribut + ::slotted-pseudoelement]; `.ug-knap [slot=…]` har
   (0,2,0) [klasse + attribut] og VINDER på specificitet (sammenlignes før tree-
   order). En `wa-button [slot=…]`-regel ville derimod TABE (0,1,1) < (0,1,2) — derfor
   klassen. (Verificeret mod den vendorede WA-kilde; ingen browser i worktree,
   men reglen er spec-deterministisk, ikke miljø-afhængig.) */
.ug-knap > [slot='start'] { margin-inline-end: var(--ug-knap-gap); }
.ug-knap > [slot='end']   { margin-inline-start: var(--ug-knap-gap); }

/* vE: intet at gøre — wa-icon sætter selv vertical-align, og knap-basen er
   inline-flex/align-items:center, så ikonet centreres via flex (vertical-align
   har ingen effekt på flex-items). Verificeret mod den vendorede WA-kilde. */

/* Koncentrisk-reglen (A3): et CIRKULÆRT ikon i en pille lægges koncentrisk med
   endebuen. Opt-in helper — en klods med et rundt LEDENDE ikon bærer
   .ug-knap-koncentrisk sammen med sin takt; padding-inline-start = (højde−ikon)/2
   pr. takt (--ug-knap-koncentrisk-*). Kantede ikoner bruger takt-paddingen og
   sætter IKKE denne klasse. C.4 påfører den på de relevante runde-ikon-klodser. */
.ug-knap-koncentrisk.ug-knap-l::part(base) { padding-inline-start: var(--ug-knap-koncentrisk-l); }
.ug-knap-koncentrisk.ug-knap-m::part(base) { padding-inline-start: var(--ug-knap-koncentrisk-m); }
.ug-knap-koncentrisk.ug-knap-s::part(base) { padding-inline-start: var(--ug-knap-koncentrisk-s); }

/* ══ Rund ikon-knap (delt form) — knap-og-ikon-domme A2/A5/A7, bundt C.4 ══════
   Den ikon-only runde knap: en 28px cirkel (takt 3) med bart, koncentrisk
   centreret ikon. C.4 leverer FORMEN delt her; hver mål-klods bærer markøren på
   sin wa-button (data-ug-knap-rund) og sætter selv sin FLADE (accent/danger/
   neutral efter rolle) + ink-sæt i sin egen CSS (A5/A7) — samme opdeling som
   C.3's takt-anatomi (form ét sted, rolle hos klodsen).

   MARKØR = data-attribut, IKKE class: grammatik-regel E2 tillader kun ÉN class,
   der matcher ^wa-[a-z-]+$, på et element (WA-utility) — en ug-*-class fanges af
   E2. Data-attributter (som de eksisterende data-hoved/data-caret/data-ov-anker
   på wa-buttons) er frie, så markøren bæres som `data-ug-knap-rund`.

   A2: cirklen sættes med BUTTON-styling (border-radius, lige høj og bred),
   ALDRIG med FA's cirkel-ikoner. Centrering: en ikon-only knap har INGEN tekst,
   så det barte ikon centreres koncentrisk i cirklen (WA's egen flex-base +
   align/justify-center) — dette er IKKE en fravigelse af vE-dommen (A3), der
   forbyder flex-centrering af glyphs der står INLINE med tekst; her er der ingen
   tekst. Fase-1-lint B.3 undtager netop ikon-only-knapper (knapHasTextWaButton →
   false) fra vE-kravet, og centreringen ligger på ::part(base), ikke på glyph-
   selektoren. */
/* Standalone-defaulten for den runde form. IKKE en invariant for alle bærere:
   kort-fodens ug-overblik-button skalerer op til takt-m (34px cirkel, 20px øje)
   i sin EGEN element-CSS, fordi den står ved siden af en takt-m Rediger-pille. */
[data-ug-knap-rund] {
  --wa-form-control-height: var(--ug-knap-h-s);       /* 28px cirkel-diameter (takt 3) */
  --wa-form-control-padding-inline: 0;                /* bart ikon → ingen inline-pad */
  --ug-glyph-size: var(--ug-knap-ikon-s);             /* 16px ikon i 28px cirkel (A3 koncentrisk) — virker kun på størrelses-renset glyph-atom */
}
/* Basis-cirkelgeometrien under :where() (specificitet 0,0,1) så en klods' egen
   ::part(base)-regel ALTID vinder — de tre række-handlingsklodser (raekke-menu,
   tidspunkt-kopier, tidspunkt-rediger) samler i en fælles kontekst deres inder-
   hjørner/bredde via --ug-handling-*-tokens; den runde cirkel er STANDALONE-
   defaulten som den kontekst overstyrer. Hver pille-klods bærer selv sin
   border-radius: var(--ug-radius-pill) (B1-kravet); på en 28×28 flade ER pille-
   radius en cirkel, så den runde form og B1 er det samme udtryk. 50% her er den
   klods-uafhængige backstop. */
:where([data-ug-knap-rund])::part(base) {
  inline-size: var(--ug-knap-h-s);
  block-size: var(--ug-knap-h-s);
  padding: 0;
  border-radius: 50%;
}
[data-ug-knap-rund]::part(base) {
  align-items: center;
  justify-content: center;                            /* bart ikon centreret koncentrisk (ikon-only; B.3/vE undtaget) */
  line-height: 0;                                     /* WA-kanonisk (github.com/shoelace-style/webawesome#2280): nulstiller line-box'en så det slottede ikons vertical-align:-0.125em ikke skubber glyffen ~1,5px op i cirklen. WA zeroer selv line-height på [part=start]/[part=end], men ikon-only runde knapper lægger glyffen i default-(label-)slotten, som WA ikke rører — derfor her. */
  position: relative;                                 /* anker for touch-target + ring */
  transition: box-shadow 0.12s ease;
}
/* Usynligt touch-target ≥44px (A2): en centreret, gennemsigtig klik-flade der
   udvider hit-arealet uden at vokse den 28px synlige cirkel. ::after arver
   ::part(base)'s pointer-events, så et klik i det udvidede felt rammer knappen. */
[data-ug-knap-rund]::part(base)::after {
  content: "";
  position: absolute;
  inset: 50%;
  inline-size: var(--ug-knap-touch-min);
  block-size: var(--ug-knap-touch-min);
  translate: -50% -50%;
}
/* Hover/fokus: en tydelig ring (A2 «hover-/fokus-feedback»; dommens flade-tint-
   eller-ring). Ringen erstatter WA's default-outline, så feedbacken er konsistent
   på tværs af hele det runde knap-sæt. */
[data-ug-knap-rund]::part(base):hover,
[data-ug-knap-rund]::part(base):focus-visible {
  box-shadow: 0 0 0 var(--ug-knap-rund-ring-bredde) var(--ug-knap-rund-ring);
}
[data-ug-knap-rund]::part(base):focus-visible { outline: none; }
/* Slotted-margin-nulstilling for den runde form: en ikon-only knap der bærer sin
   glyph i start-/end-slotten (B.5 kræver positions-argumentet på nye klodser)
   arver ellers WA's `::slotted(*){margin-inline-end:.75em}` — se nulstillingen
   for .ug-knap ovenfor for cascade-argumentet — og glyffen sidder da op ad
   cirklens ene kant i stedet for koncentrisk (målt på ug-logo-skift-button).
   Ingen tekst, ingen afstand: marginen er 0, base'ns justify-content centrerer. */
[data-ug-knap-rund] > [slot='start'] { margin-inline-end: 0; }
[data-ug-knap-rund] > [slot='end']   { margin-inline-start: 0; }

/* ── Glyph-dommen C.2: context glyph sizes (A4) ─────────────────────────────
   The 60 glyph atoms no longer own their size (docs/platform/knap-og-ikon-domme.md
   §A4): the atom ships `font-size: var(--ug-glyph-size)` (fallback-free — C8 rejects
   a literal inside var(), so an uncovered glyph inherits its parent size rather than
   a 1em default), and the size is set by the CONTEXT. Every glyph used on a surface
   IS covered below or in its element CSS. Most consumers pin the pre-cleanse rendered
   size in their own element
   CSS; the rules below cover the contexts that have NO element-CSS home:
     • display glyphs placed directly by a composition GROUP or the login screen
       (ADR-0043: the group/context wrapper is the channel for pure arrangement —
       same precedent as the group-scoped rules above);
     • three consumers whose element CSS is currently frozen by the tombstone
       guard (logo-/wordmark-pill, themetoggle: paths git-rm'd 2026-06-23 then
       legitimately re-created — a guard false-positive an agent may not self-
       approve), so their glyph-size pin lives here instead.
   Every value reproduces the measured pre-cleanse size — no visual change in this
   bundle; the takt tokens replace these in C.3. */
[data-ug-id="grp-claim-kort"] ug-claim-glyph { --ug-glyph-size: var(--ug-glyph-display); }
[data-ug-id="grp-tom-liste"] ug-inbox-glyph { --ug-glyph-size: var(--ug-glyph-display); }
[data-ug-id="grp-intro-slide"] ug-intro-slide-glyph { --ug-glyph-size: var(--ug-text-3xl); }
[data-ug-id="grp-krummesti"] ug-krumme-skiller-glyph { --ug-glyph-size: var(--ug-text-2xs); }
[data-ug-id="grp-stab-tom"] ug-users-glyph { --ug-glyph-size: var(--ug-text-2xl-s); }
/* Display glyphs placed directly by the login screen (no group/element wrapper). */
ug-link-sendt-glyph { --ug-glyph-size: var(--ug-glyph-display); }
ug-totp-glyph { --ug-glyph-size: var(--ug-glyph-display); }
/* Consumers whose element CSS is tombstone-frozen (see note above). */
ug-logo-pill ug-brand-glyph,
ug-wordmark-pill ug-brand-glyph { --ug-glyph-size: var(--ug-text-2xl); }
ug-themetoggle ug-maane-glyph,
ug-themetoggle ug-sol-glyph { --ug-glyph-size: var(--ug-text-xl); }

/* Tegn-tælleren i rediger-hovedets meta-række pinnes ALTID til højre (Johannes
   2026-07-17) — ADR-0043: ren arrangering bor på gruppens wrapper-kontekst, ikke
   på det delte ug-tegn-taeller (som også bor i inviter-beskeden). rel-rediger-hoved
   er en wa-split (space-between): med krumme'n til stede står krumme venstre /
   tæller højre, men når posten ingen forældre-entitet har omittes krummen og
   space-between glider den lone tæller til VENSTRE. margin-inline-start:auto
   lader tælleren opsluge al fri plads til venstre for sig, så den hugger højre
   uanset om krummen er der — identisk med space-between-udfaldet når begge er
   der. Tælleren er selv wa-split'ens flex-item, så margin'en virker som
   flex-item-margin. Rammer både gruppe-kompositionen (skærmene) og
   relations-preview'et (galleriets rel-rediger-hoved-side). */
[data-ug-id="grp-rediger-hoved"] > ug-tegn-taeller,
[data-ug-id="rel-rediger-hoved"] > ug-tegn-taeller {
  margin-inline-start: auto;
}

/* Fane-zone-skift (ug-rediger-fane.js, review #2178 Important 3): gør hidden
   universel på composerens noder. (1) [data-ug-status][hidden] — medlemmets
   status-bærende rod (closest('[data-ug-status]')), hvis egen display (fx en
   klods' inline-flex eller en utility-klasse) ellers slår UA-stylesheetets
   [hidden]{display:none}. (2) [data-ug-scope][hidden] dækker zoneRoot's
   identity-node-FALLBACK. !important fordi noden er medlemmets EGEN rod, og
   klodsens egne display-regler konkurrerer. Pinnet af
   TestLookCSS_StatusAttributGiverIngenBoks. */
[data-ug-status][hidden], [data-ug-scope][hidden] { display: none !important; }
/* (3) ug-fane-aktivstreg[hidden]: the active-tab indicator bar the SAME JS hides
   on inactive tabs (streg.hidden = true). Its own element CSS declares
   `display: block`, an AUTHOR rule that beats the UA [hidden]{display:none}
   regardless of specificity — without this every tab's streg stays painted, so
   all tabs read as active. The zone rules above never match it: the JS hides the
   raw <ug-fane-aktivstreg> element, which carries neither data-ug-status nor
   data-ug-scope. Element-scoped [hidden] override, mirroring ug-gem-button.css. */
ug-fane-aktivstreg[hidden] { display: none; }

/* ── Galleriets egen chrome (IKKE et element — almindelig HTML/CSS) ───────── */

body {
  font-family: var(--wa-font-family-body, system-ui, sans-serif);
  color: var(--wa-color-neutral-20);
  background: var(--wa-color-neutral-95);
  margin: 0;
  line-height: 1.5;
}

.gal-topbar {
  background: var(--ug-brand);
  color: var(--ug-on-brand);
  padding: 1rem 1.5rem;
  display: flex;
  align-items: center;
  gap: 0.5rem 1.5rem;
  flex-wrap: wrap; /* ug3-s76ra: 8 nav-punkter overløb på 390px uden wrap */
}
.gal-topbar a { color: var(--ug-on-brand); text-decoration: none; font-weight: 600; }
.gal-topbar a:hover { text-decoration: underline; }
.gal-topbar .gal-brand { font-weight: 800; font-size: 1.1rem; margin-right: auto; }
/* Global lys/mørk-toggle i topbaren (base.gohtml #gal-tema-toggle). */
.gal-tema-toggle { background: none; border: 1px solid var(--ug-on-brand); border-radius: var(--ug-radius); color: var(--ug-on-brand); cursor: pointer; font-size: 1rem; line-height: 1; padding: 0.2rem 0.45rem; }
.gal-tema-toggle:hover { background: color-mix(in srgb, var(--ug-on-brand) 15%, transparent); }
/* Global søgning i topbaren (base.gohtml [data-globalsoeg], static/globalsoeg.js).
   Panelet er galleri-chrome som .gal-nav-menu; det skjules med hidden-attributten,
   så det må ikke få en display-regel. */
.gal-globalsoeg { position: relative; flex: 0 1 18rem; min-width: 12rem; }
.gal-globalsoeg wa-input { width: 100%; }
.gal-globalsoeg-panel { position: absolute; top: calc(100% + 0.45rem); right: 0; width: min(34rem, calc(100vw - 2rem)); max-height: min(70vh, 36rem); overflow-y: auto; background: var(--ug-surface); color: var(--ug-text); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius); box-shadow: var(--ug-shadow-pop, var(--ug-shadow)); padding: var(--ug-space-2xs); z-index: 100; }
.gal-gs-gruppe + .gal-gs-gruppe { border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); margin-top: var(--ug-space-2xs); padding-top: var(--ug-space-2xs); }
.gal-gs-etiket { margin: var(--ug-space-2xs) var(--ug-space-s); font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ug-text-quiet); }
.gal-gs-antal { font-weight: 600; color: var(--ug-text-faint); }
.gal-topbar .gal-gs-hit { display: flex; flex-direction: column; gap: 0.1rem; color: var(--ug-text); font-weight: 500; padding: var(--ug-space-2xs) var(--ug-space-s); border-radius: var(--ug-radius-s); }
.gal-topbar .gal-gs-hit:hover,
.gal-topbar .gal-gs-hit:focus-visible { background: var(--ug-brand-quiet); text-decoration: none; }
.gal-gs-top { display: flex; align-items: center; gap: var(--ug-space-xs); }
.gal-gs-top .gal-badge { font-size: 0.65rem; padding: 0.05rem 0.45rem; }
.gal-gs-under { display: flex; flex-wrap: wrap; gap: 0 var(--ug-space-xs); font-size: 0.8rem; color: var(--ug-text-quiet); }
.gal-gs-navn { font-size: 0.78rem; overflow-wrap: anywhere; }
.gal-gs-flere,
.gal-gs-besked { margin: var(--ug-space-2xs) var(--ug-space-s); font-size: 0.82rem; color: var(--ug-text-quiet); }
@media (max-width: 640px) {
  /* Smal skærm: søgningen får sin egen række nederst i topbaren og panelet fuld bredde. */
  .gal-globalsoeg { flex: 1 1 100%; order: 1; }
  .gal-globalsoeg-panel { left: 0; width: auto; }
}

/* ── Tematiske undermenuer i topbaren (native <details>/<summary>) ───────────────
   Bespoke nav-chrome, ikke et registry-element. Vi bruger native <details> frem for
   <wa-dropdown> fordi nav-punkter er ÆGTE <a href>: åbn-i-ny-fane / midterklik /
   ingen-JS virker (galleriets statiske eksport skal kunne navigeres uden at WA-
   loaderen er kørt). <wa-dropdown> fyrer wa-select og kræver JS for at navigere.
   <details> er click/tap-toggle (mobil-sikkert) + tastatur-tilgængeligt natively.
   Spejler gal-topbar-mønstret (selv hand-rullet); alt på --ug-tokens. */
/* Reset WA's native-element styling of <details>/<summary> (it gives them a white
   card background + border + 16px padding) so the trigger reads as a plain teal
   topbar link, not a white box on the teal bar. */
.gal-nav-group { position: relative; background: transparent; border: 0; border-radius: 0; padding: 0; margin: 0; box-shadow: none; }
.gal-nav-group > summary { color: var(--ug-on-brand); font-weight: 600; cursor: pointer; list-style: none; display: inline-flex; align-items: center; gap: 0.3rem; padding: 0; background: transparent; border: 0; border-radius: 0; white-space: nowrap; }
.gal-nav-group > summary::-webkit-details-marker { display: none; }
/* NO-LAYOUT-SHIFT on open (ug3): WA's native.css gives `details[open] summary` a
   `margin-inline: calc(-1 * var(--wa-space-m))` (its accordion style, where the open
   summary bleeds into the panel padding). On a topbar trigger that −16px each side
   yanked the summary left and shrank the <details> box by 32px, reflowing every
   other nav item sideways the instant a menu opened. Pin it back to zero so the
   trigger box is byte-identical open and closed. The inset box-shadow is the
   open-state indicator — it lives in the paint layer only, so (unlike
   text-decoration/font-weight) it can never reflow the box. */
.gal-nav-group[open] > summary { margin-inline: 0; box-shadow: inset 0 -2px 0 0 var(--ug-on-brand); }
/* Chevron: our own ▾ glyph in a fixed-width slot, centred so it occupies the SAME
   space regardless of state and rotates in place — no horizontal nudge on toggle.
   `content`/`width`/`background`/`mask` override WA's native SVG-mask marker; the
   `rotate: 0deg` reset neutralises WA's `details[open] summary::after { rotate: 90deg }`
   so only our `transform` drives the flip (two rotate sources would compound). */
.gal-nav-group > summary::after { content: "▾"; display: inline-flex; justify-content: center; width: 0.8em; height: auto; font-size: 0.7em; opacity: 0.85; background: none; mask: none; rotate: 0deg; transition: transform 0.12s ease; }
.gal-nav-group[open] > summary::after { transform: rotate(180deg); }
.gal-nav-menu { position: absolute; top: calc(100% + 0.45rem); left: 0; min-width: 12rem; background: var(--ug-surface); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius); box-shadow: var(--ug-shadow-l, var(--ug-shadow)); padding: var(--ug-space-2xs); display: flex; flex-direction: column; gap: 2px; z-index: 100; }
.gal-topbar .gal-nav-menu a { color: var(--ug-text); font-weight: 500; padding: var(--ug-space-2xs) var(--ug-space-s); border-radius: var(--ug-radius-s); white-space: nowrap; }
.gal-topbar .gal-nav-menu a:hover { background: var(--ug-brand-quiet); text-decoration: none; }
@media (max-width: 640px) {
  /* Narrow screen: a menu opening rightwards from its summary could reach past
     the viewport, so it drops below the whole topbar at full width and long
     links wrap. Check: scripts/gallery-mobil-overflow.sh. */
  .gal-topbar { position: relative; }
  .gal-nav-group { position: static; }
  .gal-nav-menu { top: 100%; left: var(--ug-space-m); right: var(--ug-space-m); min-width: 0; }
  .gal-topbar .gal-nav-menu a { white-space: normal; }
}

.gal-main { max-width: 1100px; margin: 0 auto; padding: 2rem 1.5rem; }
.gal-main h1 { margin-top: 0; }
@media (max-width: 640px) {
  /* A one-word page name can be wider than a narrow screen at h1 size; it
     breaks instead of widening the page. */
  .gal-main h1 { overflow-wrap: break-word; hyphens: auto; }
}
.gal-section { margin: 2.5rem 0; }
@media (max-width: 640px) {
  /* A data table wider than a narrow screen scrolls inside its focusable
     region wrapper instead of widening the page; the table itself stays
     display: table, so it keeps its table semantics. */
  .gal-tabel-rul { max-width: 100%; overflow-x: auto; }
}
/* Keeps a wrapped table's block spacing when the wrapper is followed by
   something; :where keeps it weaker than a table's own margin. */
:where(.gal-tabel-rul:has(+ *)) > table { margin-block-end: var(--wa-content-spacing); }

/* ── Sanktionerede inline-emphasis-direktiver (ADR-0060 Mekanisme B) ─────────
   Hvert {{em/staerk/kode/kbd/tal/stille}}-direktiv renderer til ÉN kanonisk frase-tag
   (uiregistry.DirektivFuncs). Looket er ÉN central regel pr. tag her — så et
   direktiv-kald ser ens ud overalt uden per-call-site-CSS. Positionel
   fremhævning i VORES EGNE OVERSKRIFTER (Mekanisme A) styles derimod af
   forælder-elementets egen CSS (fx `ug-titel-fremhaevet ug-em`) og overrider
   denne default via descendant-specificitet — bevidst. */
ug-em { font-weight: var(--ug-weight-bold); color: var(--ug-text-accent); }
ug-staerk { font-weight: var(--ug-weight-bold); }
ug-kode { font-family: var(--ug-mono); }
ug-kbd { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); border: var(--wa-border-width-s) solid var(--ug-border); border-radius: var(--ug-radius-s); padding-block: var(--wa-space-3xs); padding-inline: var(--wa-space-2xs); color: var(--ug-text-quiet); }
ug-tal { font-variant-numeric: tabular-nums; letter-spacing: var(--ug-tracking-tight); }
/* ug-stille — dæmpet under-etiket (de-emphasis), ADR-0060 Mekanisme B. Spejler det
   <small>-rolle-look ug-menu-header tidligere bar rå: mindre + faint ink. */
ug-stille { font-size: var(--ug-text-2xs); color: var(--ug-text-faint); }

/* ── F4-5 Del 2.4 + 3.6h: delt element-CSS-substrat (element-laget) ──────────
   Byte-identiske element-regler single-sources HER (samme element-lag som
   ug-tal/ug-stille) i stedet for at copy-paste-drifte pr. element (galleri-audit
   Del 2.4). Kun det VARIERENDE bliver i elementets egen CSS: LED-prik-farven
   (--ug-status-led) og den B1-målte kort-radius (LintElementCSS måler form mod
   elementets EGEN border-radius, så den kan ikke flyttes hertil). Look.css
   loades globalt af BÅDE galleriet og alle cockpits, så substratet gælder begge
   steder. Elementsplittene består (ADR-0065 / DDR-0002); kun substratet deles. */

/* (a) Tidspunkt-status-badges (DDR-0002 ug-tidspunktstatus-familie): plain badges
   uden LED-prik; klodserne hugger start i status-kolonnens spor (afløser den gamle
   `ug-tidspunkt-visning > wa-badge { justify-self: start }`). Den B1-målte kort-
   radius bor i hver badge-klods' egen CSS; ug-tidspunktstatus-tom er ren ug-stille. */
ug-tidspunktstatus-ny,
ug-tidspunktstatus-flyttet,
ug-tidspunktstatus-aflyst,
ug-tidspunktstatus-afholdt,
ug-tidspunktstatus-tom {
  display: inline-flex;
  align-items: center;
  justify-self: start;
}

/* (b) Avatar-fliser (galleri-audit Del 2.4): 4 ikon-fliser med byte-identisk
   flise-CSS. Elementsplittet består (ADR-0065 — bruger/invitation/post/
   invitationsstatus er distinkte identiteter); kun den fælles flise-flade deles
   her. Kun border-radius (var(--ug-radius-s), lovlig kort-variant) bliver i hver
   flises egen CSS — B1 måler form mod elementets EGEN radius. */
ug-bruger-type-avatar,
ug-invitation-type-avatar,
ug-post-type-avatar,
ug-invitationsstatus-avatar {
  display: grid;
  place-items: center;
  inline-size: var(--ug-avatar-size);
  block-size: var(--ug-avatar-size);
  background: var(--ug-icon-tile);
  font-size: var(--ug-text-l);
  flex: none;
  --ug-ink-icon-primary: var(--ug-brand-strong);
  --ug-ink-icon-secondary: var(--ug-icon-accent);
}

/* (c) Status-badges (DDR-0002, galleri-audit Del 2.4): status-badges på tværs af
   serierne deler byte-identisk struktur — celle-kontekst-wrapperen (DDR-0007) +
   LED-prik-geometrien. Legitime som separate elementer (statussen VÆLGER
   elementet); INGEN fusion — kun strukturen single-sources. Det VARIERENDE bliver
   i hver badges egen CSS: LED-prik-FARVEN (--ug-status-led) + den B1-målte kort-
   radius. Custom properties arver ind i wa-badge's shadow DOM, så --ug-status-led
   sat på værts-tag'et når ::part(base)::before-prikken.
   OMFANG: de 24 afventer-badges nedenfor. Den GODKENDTE ug-status-*-serie (4
   badges i grp-post-hoved/-linje) holdes bevidst på sin reviewede CSS: at reducere
   den ville mekanisk demotere hele post-liste-visnings-kæden (grp-post-krop/-kort/
   -liste/-tabel) til afventer uden nogen visuel ændring. Den folder ind i
   substratet ved sin næste re-godkendelse (dens egen CSS matcher allerede formen,
   så det er en 2-linjers ændring). Se F4-5-rapporten. */
ug-aftalestatus-aktiv,
ug-aftalestatus-annulleret,
ug-aftalestatus-fejlet,
ug-brugerstatus-aktiv,
ug-brugerstatus-inviteret,
ug-brugerstatus-udloebet,
ug-medlemskabsstatus-afventer,
ug-medlemskabsstatus-afventer-betaling,
ug-medlemskabsstatus-afvist,
ug-medlemskabsstatus-aktiv,
ug-medlemskabsstatus-opsagt,
ug-medlemskabsstatus-udloebet,
ug-medlemsstatus-afventer,
ug-medlemsstatus-afvist,
ug-medlemsstatus-aktiv,
ug-medlemsstatus-inaktiv,
ug-medlemsstatus-udmeldt,
ug-metodestatus-aktiv,
ug-metodestatus-ikke-sat-op,
ug-metodestatus-slaaet-fra,
ug-opkraevningsstatus-afventer-betaling,
ug-opkraevningsstatus-annulleret,
ug-opkraevningsstatus-betalt,
ug-opkraevningsstatus-fejlet {
  display: inline-flex;
  align-items: center;
  align-self: var(--ug-celle-align, auto);
  border-block-end: var(--ug-celle-kant, none);
  padding-inline: var(--ug-celle-pad-i, 0);
}
ug-aftalestatus-aktiv wa-badge::part(base)::before,
ug-aftalestatus-annulleret wa-badge::part(base)::before,
ug-aftalestatus-fejlet wa-badge::part(base)::before,
ug-brugerstatus-aktiv wa-badge::part(base)::before,
ug-brugerstatus-inviteret wa-badge::part(base)::before,
ug-brugerstatus-udloebet wa-badge::part(base)::before,
ug-medlemskabsstatus-afventer wa-badge::part(base)::before,
ug-medlemskabsstatus-afventer-betaling wa-badge::part(base)::before,
ug-medlemskabsstatus-afvist wa-badge::part(base)::before,
ug-medlemskabsstatus-aktiv wa-badge::part(base)::before,
ug-medlemskabsstatus-opsagt wa-badge::part(base)::before,
ug-medlemskabsstatus-udloebet wa-badge::part(base)::before,
ug-medlemsstatus-afventer wa-badge::part(base)::before,
ug-medlemsstatus-afvist wa-badge::part(base)::before,
ug-medlemsstatus-aktiv wa-badge::part(base)::before,
ug-medlemsstatus-inaktiv wa-badge::part(base)::before,
ug-medlemsstatus-udmeldt wa-badge::part(base)::before,
ug-metodestatus-aktiv wa-badge::part(base)::before,
ug-metodestatus-ikke-sat-op wa-badge::part(base)::before,
ug-metodestatus-slaaet-fra wa-badge::part(base)::before,
ug-opkraevningsstatus-afventer-betaling wa-badge::part(base)::before,
ug-opkraevningsstatus-annulleret wa-badge::part(base)::before,
ug-opkraevningsstatus-betalt wa-badge::part(base)::before,
ug-opkraevningsstatus-fejlet wa-badge::part(base)::before {
  content: "";
  inline-size: var(--ug-space-2xs);
  block-size: var(--ug-space-2xs);
  border-radius: var(--ug-radius-pill);
  background: var(--ug-status-led);
  margin-inline-end: var(--ug-space-3xs);
}

/* ── Forklaringer-siden: tier-triage-kort (governance-forklaring) ──────────── */

/* ── Forklaringer-siden: tier-triage-kort (governance-forklaring) ──────────── */
.gal-fk-sub { margin: var(--ug-space-l) 0 var(--ug-space-2xs); font-size: var(--ug-text-s); font-weight: var(--ug-weight-bold); letter-spacing: var(--ug-tracking-label); text-transform: uppercase; color: var(--ug-text-quiet); }
.gal-fk-q { display: flex; flex-wrap: wrap; gap: var(--ug-space-s); margin-bottom: var(--ug-space-s); }
.gal-fk-qbox { flex: 1; min-width: 14rem; padding: var(--ug-space-s) var(--ug-space-m); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius); background: var(--ug-surface); }
.gal-fk-qn { margin: 0 0 var(--ug-space-3xs); font-weight: var(--ug-weight-bold); color: var(--ug-brand-strong); }
.gal-fk-tier { margin: 0 0 var(--ug-space-s); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-left: var(--wa-border-width-l, 4px) solid var(--ug-border); border-radius: var(--ug-radius); overflow: hidden; background: var(--ug-surface); box-shadow: var(--ug-shadow); }
.gal-fk-tier[data-tier="A"] { border-left-color: var(--wa-color-danger-50); }
.gal-fk-tier[data-tier="B"] { border-left-color: var(--wa-color-warning-50); }
.gal-fk-tier[data-tier="C"] { border-left-color: var(--wa-color-lys-brand-50); }
.gal-fk-tier[data-tier="D"] { border-left-color: var(--wa-color-success-50); }
.gal-fk-thead { display: flex; align-items: center; flex-wrap: wrap; gap: var(--ug-space-s); padding: var(--ug-space-s) var(--ug-space-m); }
.gal-fk-badge { flex: none; width: 1.9rem; height: 1.9rem; display: grid; place-items: center; border-radius: var(--ug-radius-s); font-weight: var(--ug-weight-bold); color: #fff; }
/* Tier-badges = rene familie-core-farver (faldende alvor) — IDENTISKE med panel-fyldet
   (--ug-surface-<familie>), så badge og panel aldrig divergerer. Tekstfarve = familiens
   on-ink: danger/info mørk core → hvid; warning/ok lys core → sort. Trin-50 undgået
   (AA-dødzonen); alle ≥7:1 AAA. C=info bruger --ug-info (lys-brand-40), = info-panelet. */
.gal-fk-tier[data-tier="A"] .gal-fk-badge { background: var(--ug-surface-danger);  color: var(--ug-on-danger-surface); }  /* danger #b6000e + hvid 7.0:1 */
.gal-fk-tier[data-tier="B"] .gal-fk-badge { background: var(--ug-surface-warning); color: var(--ug-on-warning-surface); } /* warning #fff075 + sort 18:1 */
.gal-fk-tier[data-tier="C"] .gal-fk-badge { background: var(--ug-surface-info);    color: var(--ug-on-info-surface); }    /* info lys-brand-40 #4a5c62 + hvid 7.0:1 (= info-panel) */
.gal-fk-tier[data-tier="D"] .gal-fk-badge { background: var(--ug-surface-success); color: var(--ug-on-success-surface); } /* ok #63b375 + sort 8.2:1 */
.gal-fk-tname { font-weight: var(--ug-weight-bold); }
.gal-fk-count { margin-left: auto; font-size: var(--ug-text-2xs); font-family: var(--ug-mono); color: var(--ug-text-quiet); }
.gal-fk-trow { display: grid; grid-template-columns: 1fr 1fr 1fr; border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); }
.gal-fk-trow > div { padding: var(--ug-space-s) var(--ug-space-m); border-right: var(--wa-border-width-s) solid var(--ug-border-quiet); font-size: var(--ug-text-s); }
.gal-fk-trow > div:last-child { border-right: none; }
.gal-fk-trow p { margin: 0; }
.gal-fk-lab { font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-text-faint); font-weight: var(--ug-weight-bold); margin-bottom: var(--ug-space-3xs) !important; }
.gal-fk-act { font-weight: var(--ug-weight-semibold); color: var(--ug-brand-strong); }
.gal-fk-ex { margin: 0; padding: var(--ug-space-xs) var(--ug-space-m); border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); background: var(--ug-surface-sunk, transparent); font-size: var(--ug-text-s); color: var(--ug-text-quiet); }
.gal-fk-purpose { margin: var(--ug-space-2xs) 0 0; padding-left: var(--ug-space-m); }
.gal-fk-purpose li { margin-bottom: var(--ug-space-2xs); font-size: var(--ug-text-s); }
.gal-fk-foot { margin-top: var(--ug-space-m); font-size: var(--ug-text-2xs); color: var(--ug-text-faint); }
@media (max-width: 720px) { .gal-fk-trow { grid-template-columns: 1fr; } .gal-fk-trow > div { border-right: none; border-bottom: var(--wa-border-width-s) solid var(--ug-border-quiet); } }

/* ── Forklaringer: ADR-livscyklus-pipeline (8 stationer, 2 koral-gates) ──────────
   Bespoke pipeline-visual (lodret konnektor-linje + cirkel-noder) — ingen WA-utility
   dækker den. Teal=maskine/flow → --ug-brand*; koral=menneske-gate → --ug-accent*
   (galleriets accent ER koral, #EA7246). Spejler gal-fk-mønstret: alt på --ug-tokens,
   hand-rolled flex, dark-mode-sikkert (brand-panel = topbar-mønstret). */
.gal-lc-gateword { color: var(--ug-text-accent); font-weight: var(--ug-weight-semibold); }
.gal-lc-banner { margin: var(--ug-space-m) 0 0; padding: var(--ug-space-s) var(--ug-space-m); border: var(--wa-border-width-s) solid var(--ug-brand-line); border-radius: var(--ug-radius); background: var(--ug-brand-quiet); font-size: var(--ug-text-s); color: var(--ug-text); }
.gal-lc-legend { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ug-space-2xs) var(--ug-space-s); margin: var(--ug-space-l) 0 0; }
.gal-lc-leg-lab { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-text-faint); }
.gal-lc-chip { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); padding: var(--ug-space-4xs) var(--ug-space-2xs); border-radius: var(--ug-radius-pill); border: var(--wa-border-width-s) solid var(--ug-brand-line); color: var(--ug-brand-strong); background: var(--ug-surface); white-space: nowrap; }
.gal-lc-chip-gate { border-color: var(--ug-accent-line); color: var(--ug-text-accent); background: var(--ug-accent-quiet); }

.gal-lc-pipeline { list-style: none; margin: var(--ug-space-xl) 0 0; padding: 0; position: relative; }
.gal-lc-pipeline::before { content: ""; position: absolute; left: 1.45rem; top: 1rem; bottom: 1rem; width: 2px; background: var(--ug-brand-line); }
.gal-lc-station { position: relative; padding: 0 0 var(--ug-space-l) 4rem; }
.gal-lc-station:last-child { padding-bottom: 0; }
.gal-lc-node { position: absolute; left: 0; top: 0; width: 3rem; height: 3rem; border-radius: 50%; display: grid; place-items: center; background: var(--ug-surface); border: 2px solid var(--ug-brand); color: var(--ug-brand-strong); font-family: var(--ug-mono); font-weight: var(--ug-weight-bold); font-size: 1.05rem; z-index: 1; }
.gal-lc-gate .gal-lc-node { border-color: var(--ug-accent); color: var(--ug-text-accent); box-shadow: 0 0 0 5px var(--ug-accent-quiet); }

.gal-lc-card { background: var(--ug-surface); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-left: var(--wa-border-width-l, 4px) solid var(--ug-brand); border-radius: var(--ug-radius); padding: var(--ug-space-s) var(--ug-space-m); box-shadow: var(--ug-shadow); }
.gal-lc-gate .gal-lc-card { border-left-color: var(--ug-accent); }
.gal-lc-top { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ug-space-3xs) var(--ug-space-s); }
.gal-lc-top h3 { margin: 0; font-size: 1.05rem; }
.gal-lc-gatetag { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); font-weight: var(--ug-weight-semibold); color: var(--ug-text-accent); }
.gal-lc-actor { margin-left: auto; font-family: var(--ug-mono); font-size: var(--ug-text-2xs); padding: var(--ug-space-4xs) var(--ug-space-2xs); border-radius: var(--ug-radius-s); background: var(--ug-brand-quiet); color: var(--ug-brand-strong); white-space: nowrap; }
.gal-lc-gate .gal-lc-actor { background: var(--ug-accent-quiet); color: var(--ug-text-accent); }
.gal-lc-flow { display: flex; align-items: flex-start; flex-wrap: wrap; gap: var(--ug-space-s); margin-top: var(--ug-space-s); }
.gal-lc-io { flex: 1 1 11rem; min-width: 10rem; }
.gal-lc-iot { margin: 0 0 var(--ug-space-4xs); font-family: var(--ug-mono); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-text-faint); }
.gal-lc-iov { margin: 0; font-size: var(--ug-text-s); }
.gal-lc-arrow { padding-top: 1rem; color: var(--ug-brand-strong); font-weight: var(--ug-weight-bold); }
.gal-lc-repo { margin-top: var(--ug-space-s); padding-top: var(--ug-space-xs); border-top: var(--wa-border-width-s) dashed var(--ug-border-quiet); display: flex; gap: var(--ug-space-s); align-items: baseline; }
.gal-lc-repot { flex: 0 0 auto; font-family: var(--ug-mono); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-text-faint); }
.gal-lc-repov { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); line-height: 1.5; overflow-wrap: anywhere; }
.gal-lc-repov code { font-size: inherit; }

.gal-lc-closing { margin: var(--ug-space-xl) 0 0; padding: var(--ug-space-l); border-radius: var(--ug-radius-l); background: var(--ug-brand); color: var(--ug-on-brand); }
.gal-lc-closing-eyebrow { margin: 0 0 var(--ug-space-2xs); font-family: var(--ug-mono); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-on-brand-soft); }
.gal-lc-closing h3 { margin: 0 0 var(--ug-space-2xs); color: var(--ug-on-brand); }
.gal-lc-closing p { margin: 0; color: var(--ug-on-brand-quiet); max-width: 60ch; }
.gal-lc-accent { color: var(--ug-accent); font-weight: var(--ug-weight-semibold); }

@media (max-width: 560px) {
  .gal-lc-station { padding-left: 3.25rem; }
  .gal-lc-pipeline::before { left: 1.15rem; }
  .gal-lc-node { width: 2.4rem; height: 2.4rem; font-size: var(--ug-text-s); }
  .gal-lc-actor { margin-left: 0; }
  .gal-lc-arrow { display: none; }
}

/* ── Forklaringer: grammatik-begrebsgraf (indlejring + forbindelser) ──────────────
   Bespoke node-graph visual; node-type colour comes from --ug-graf-* (data-t set
   per type). Mirrors gal-fk/gal-lc: panel-fyld/ink/borders on --ug- tokens, hand-
   rolled layout, dark-mode-safe (the graf hues have their own .wa-dark variants). */
.gal-bg-hint { color: var(--ug-text-quiet); font-size: var(--ug-text-s); margin: var(--ug-space-2xs) 0 var(--ug-space-m); }
.gal-bg-panel { background: var(--ug-surface-sunk, var(--ug-surface-2)); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius); padding: var(--ug-space-m) var(--ug-space-l); margin: var(--ug-space-s) 0; }
.gal-bg-legend { display: flex; gap: var(--ug-space-2xs) var(--ug-space-m); flex-wrap: wrap; font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); margin: var(--ug-space-s) 0 var(--ug-space-l); align-items: center; }
.gal-bg-legend span { display: inline-flex; align-items: center; gap: var(--ug-space-3xs); }
.gal-bg-dot { width: 0.7rem; height: 0.7rem; border-radius: var(--ug-radius-s); display: inline-block; }

.gal-bg-node { border: 1.5px solid var(--ug-graf-c, var(--ug-border)); border-radius: var(--ug-radius); margin: var(--ug-space-2xs) 0; background: var(--ug-surface); padding: var(--ug-space-s); position: relative; }
.gal-bg-node > .gal-bg-lbl { font-weight: var(--ug-weight-bold); font-size: var(--ug-text-s); color: var(--ug-graf-c, var(--ug-text)); display: flex; align-items: baseline; gap: var(--ug-space-2xs); flex-wrap: wrap; }
.gal-bg-form { font-weight: var(--ug-weight-normal, 400); color: var(--ug-text-quiet); font-family: var(--ug-mono); font-size: var(--ug-text-2xs); }
.gal-bg-rn { font-weight: var(--ug-weight-semibold); font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); background: var(--ug-surface-sunk, var(--wa-color-neutral-90)); padding: 1px var(--ug-space-2xs); border-radius: var(--ug-radius-pill); font-family: var(--ug-mono); }
.gal-bg-kids { margin: var(--ug-space-2xs) 0 0 var(--ug-space-s); padding-left: var(--ug-space-s); border-left: 2px dashed var(--ug-border-quiet); }
.gal-bg-mark { font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); font-weight: var(--ug-weight-semibold); margin-left: auto; }
.gal-bg-desc { font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); margin-top: var(--ug-space-3xs); }
.gal-bg-node[data-t="skaerm"]{--ug-graf-c:var(--ug-graf-skaerm)} .gal-bg-node[data-t="ramme"]{--ug-graf-c:var(--ug-graf-ramme)} .gal-bg-node[data-t="tilstand"]{--ug-graf-c:var(--ug-graf-tilstand)} .gal-bg-node[data-t="indhold"]{--ug-graf-c:var(--ug-graf-indhold)} .gal-bg-node[data-t="rel"]{--ug-graf-c:var(--ug-graf-rel)} .gal-bg-node[data-t="gruppe"]{--ug-graf-c:var(--ug-graf-gruppe)} .gal-bg-node[data-t="element"]{--ug-graf-c:var(--ug-graf-element)} .gal-bg-node[data-t="slice"]{--ug-graf-c:var(--ug-graf-slice)} .gal-bg-node[data-t="familie"]{--ug-graf-c:var(--ug-graf-familie)} .gal-bg-node[data-t="token"]{--ug-graf-c:var(--ug-graf-token)} .gal-bg-node[data-t="overlay"]{--ug-graf-c:var(--ug-graf-overlay)}
.gal-bg-choice { display: flex; gap: var(--ug-space-s); flex-wrap: wrap; margin-top: var(--ug-space-2xs); align-items: flex-start; }
.gal-bg-choice .gal-bg-node { flex: 1; min-width: 12rem; margin: 0; }
.gal-bg-orlabel { font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); text-align: center; margin: var(--ug-space-3xs) 0; font-weight: var(--ug-weight-semibold); letter-spacing: var(--ug-tracking-label); }

.gal-bg-page { border: 2px solid var(--ug-graf-ramme); border-radius: var(--ug-radius); padding: var(--ug-space-s); background: var(--ug-surface); }
.gal-bg-slot { border: 1.4px solid var(--ug-border-quiet); border-radius: var(--ug-radius-s); padding: var(--ug-space-xs) var(--ug-space-s); margin: var(--ug-space-2xs) 0; font-size: var(--ug-text-s); }
.gal-bg-slot.is-head, .gal-bg-slot.is-foot { border-color: var(--ug-graf-rel); }
.gal-bg-slot.is-main { border-color: var(--ug-graf-skaerm); }
.gal-bg-slot b { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); }

.gal-bg-refrow { display: flex; align-items: center; gap: var(--ug-space-s); flex-wrap: wrap; padding: var(--ug-space-xs) 0; border-bottom: var(--wa-border-width-s) solid var(--ug-border-quiet); }
.gal-bg-refrow:last-child { border-bottom: none; }
.gal-bg-chip { font-weight: var(--ug-weight-bold); font-size: var(--ug-text-2xs); padding: var(--ug-space-3xs) var(--ug-space-s); border-radius: var(--ug-radius-s); border: 1.5px solid var(--ug-graf-c, var(--ug-border)); color: var(--ug-graf-c, var(--ug-text)); white-space: nowrap; }
.gal-bg-chip[data-t="skaerm"]{--ug-graf-c:var(--ug-graf-skaerm)} .gal-bg-chip[data-t="ramme"]{--ug-graf-c:var(--ug-graf-ramme)} .gal-bg-chip[data-t="rel"]{--ug-graf-c:var(--ug-graf-rel)} .gal-bg-chip[data-t="familie"]{--ug-graf-c:var(--ug-graf-familie)} .gal-bg-chip[data-t="element"]{--ug-graf-c:var(--ug-graf-element)} .gal-bg-chip[data-t="slice"]{--ug-graf-c:var(--ug-graf-slice)} .gal-bg-chip[data-t="overlay"]{--ug-graf-c:var(--ug-graf-overlay)} .gal-bg-chip[data-t="indhold"]{--ug-graf-c:var(--ug-graf-indhold)} .gal-bg-chip[data-t="token"]{--ug-graf-c:var(--ug-graf-token)}
.gal-bg-verb { color: var(--ug-text-quiet); font-size: var(--ug-text-2xs); font-style: italic; }
.gal-bg-note { color: var(--ug-text-quiet); font-size: var(--ug-text-2xs); flex: 1; min-width: 11rem; }

.gal-bg-lay { display: flex; align-items: center; gap: var(--ug-space-s); padding: var(--ug-space-xs) 0; }
.gal-bg-laynum { width: 3.5rem; font-weight: var(--ug-weight-bold); color: var(--ug-graf-token); font-size: var(--ug-text-2xs); text-align: right; flex-shrink: 0; }
.gal-bg-laybox { flex: 1; border: 1.4px solid var(--ug-graf-token); border-radius: var(--ug-radius-s); padding: var(--ug-space-xs) var(--ug-space-s); background: var(--ug-surface); font-size: var(--ug-text-s); }
.gal-bg-laydown { text-align: center; color: var(--ug-text-quiet); }
/* long mono code-paths must break, or they force horizontal scroll at 390px */
.gal-bg-desc, .gal-bg-note, .gal-bg-slot, .gal-bg-laybox, .gal-bg-lbl, .gal-bg-axv { overflow-wrap: anywhere; }

.gal-bg-axes { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--ug-space-s); margin-top: var(--ug-space-2xs); }
.gal-bg-axis { border: 1.5px solid var(--ug-graf-element); border-radius: var(--ug-radius-s); padding: var(--ug-space-s); background: var(--ug-surface); }
.gal-bg-axf { font-weight: var(--ug-weight-bold); color: var(--ug-graf-element); font-size: var(--ug-text-s); }
.gal-bg-axq { font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); margin: var(--ug-space-3xs) 0; }
.gal-bg-axv { font-size: var(--ug-text-2xs); font-family: var(--ug-mono); color: var(--ug-text); }
@media (max-width: 760px) { .gal-bg-axes { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .gal-bg-choice .gal-bg-node { min-width: 100%; } }

/* ── Kontrakter: levende BDR-status (genereret fra docs/contracts/) ──────────────
   All on --ug- tokens → inherits the gallery's light + .wa-dark themes. KPI cards
   + distribution bars + integrity-flag lists + the full contract table. */
.gal-bdr-kpis { display: flex; flex-wrap: wrap; gap: var(--ug-space-s); margin: var(--ug-space-l) 0; }
.gal-bdr-kpi { flex: 1; min-width: 7.5rem; padding: var(--ug-space-s) var(--ug-space-m); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-left: var(--wa-border-width-l, 4px) solid var(--ug-brand); border-radius: var(--ug-radius); background: var(--ug-surface); box-shadow: var(--ug-shadow); }
.gal-bdr-kpi.gal-bdr-warn { border-left-color: var(--ug-warning-50); } /* -50 (ikke den lyse core #fff075, der er usynlig på hvid KPI-kort); border bærer ikke tekst → trin-50 lovligt */
.gal-bdr-num { display: block; font-size: var(--ug-text-2xl, 1.6rem); font-weight: var(--ug-weight-bold); line-height: 1.1; }
.gal-bdr-lab { font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); }

.gal-bdr-hint { color: var(--ug-text-quiet); font-size: var(--ug-text-s); margin: var(--ug-space-2xs) 0 var(--ug-space-s); }
.gal-bdr-row { display: flex; align-items: center; gap: var(--ug-space-s); margin: var(--ug-space-3xs) 0; }
.gal-bdr-rlab { flex: 0 0 12rem; font-size: var(--ug-text-s); overflow-wrap: anywhere; }
.gal-bdr-bar { flex: 1; height: 0.7rem; background: var(--ug-surface-sunk, var(--wa-color-neutral-90)); border-radius: var(--ug-radius-pill); overflow: hidden; }
.gal-bdr-fill { height: 100%; background: var(--ug-brand); }
.gal-bdr-fill-v { background: var(--ug-accent); }
.gal-bdr-rn { flex: 0 0 2rem; text-align: right; font-family: var(--ug-mono); font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); }

.gal-bdr-flags { margin: var(--ug-space-2xs) 0 0; padding-left: var(--ug-space-m); font-size: var(--ug-text-s); }
.gal-bdr-flags li { margin-bottom: var(--ug-space-3xs); overflow-wrap: anywhere; }
.gal-bdr-flags-cols { columns: 2 16rem; }

.gal-bdr-tablewrap { overflow-x: auto; }
.gal-bdr-table { width: 100%; border-collapse: collapse; font-size: var(--ug-text-s); }
.gal-bdr-table th { text-align: left; padding: var(--ug-space-2xs) var(--ug-space-s); border-bottom: 2px solid var(--ug-border); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-text-quiet); white-space: nowrap; }
.gal-bdr-table td { padding: var(--ug-space-2xs) var(--ug-space-s); border-bottom: var(--wa-border-width-s) solid var(--ug-border-quiet); vertical-align: top; }
.gal-bdr-confrow { background: var(--ug-warning-surface, transparent); }
.gal-bdr-faint { color: var(--ug-text-faint); }
@media (max-width: 560px) { .gal-bdr-rlab { flex-basis: 7rem; } .gal-bdr-table { font-size: var(--ug-text-2xs); } .gal-bdr-flags-cols { columns: 1; } }

/* ── CI-siden: hvad godkendes vs. afvises (kørende fixtures + lint-regler) ──────
   All on --ug- tokens → inherits the gallery's light + .wa-dark themes. The 5+5
   headline (two columns) + the per-rule reference cards. Mirrors gal-fk/gal-bdr:
   panel-fyld/ink/borders on tokens, subtle success/danger tints via color-mix so the
   green/red column reading survives both themes. */
.gal-ci-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ug-space-l); margin: var(--ug-space-l) 0; }
.gal-ci-colhead { display: flex; align-items: center; gap: var(--ug-space-2xs); font-weight: var(--ug-weight-bold); font-size: var(--ug-text-l, 1.1rem); margin-bottom: var(--ug-space-s); }
.gal-ci-ico { width: 1.6rem; height: 1.6rem; display: grid; place-items: center; border-radius: var(--ug-radius-s); font-weight: var(--ug-weight-bold); flex: none; }
.gal-ci-col-ok .gal-ci-colhead { color: var(--wa-color-success-40, var(--wa-color-success-50)); }
.gal-ci-col-no .gal-ci-colhead { color: var(--wa-color-danger-40, var(--wa-color-danger-50)); }
/* Glyf-fyld = familiens fulde core + låst on-blæk (ADR-0047 §2: trin 50 bærer aldrig
   tekst). Samme token-par som .gal-fk-badge: success #63b375 + sort (8.2:1), danger
   #b6000e + hvid (7.0:1) — AAA i begge temaer (fladerne er tema-invariante). ug3-eb7lt */
.gal-ci-col-ok .gal-ci-ico { background: var(--ug-surface-success); color: var(--ug-on-success-surface); }
.gal-ci-col-no .gal-ci-ico { background: var(--ug-surface-danger); color: var(--ug-on-danger-surface); }

.gal-ci-ex { border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius); background: var(--ug-surface); box-shadow: var(--ug-shadow); margin-bottom: var(--ug-space-s); overflow: hidden; }
.gal-ci-ex-ok { border-left: var(--wa-border-width-l, 4px) solid var(--wa-color-success-50); }
.gal-ci-ex-no { border-left: var(--wa-border-width-l, 4px) solid var(--wa-color-danger-50); }
.gal-ci-lab { display: flex; justify-content: space-between; align-items: center; gap: var(--ug-space-2xs); padding: var(--ug-space-2xs) var(--ug-space-s); font-size: var(--ug-text-s); color: var(--ug-text-quiet); }
.gal-ci-rule { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); font-weight: var(--ug-weight-bold); padding: var(--ug-space-4xs) var(--ug-space-2xs); border-radius: var(--ug-radius-s); background: var(--ug-surface-sunk, var(--ug-surface-2)); border: var(--wa-border-width-s) solid var(--ug-border-quiet); color: var(--ug-text-quiet); white-space: nowrap; }
.gal-ci-code { margin: 0; padding: var(--ug-space-s); background: var(--ug-surface-sunk, var(--ug-surface-2)); border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); font-family: var(--ug-mono); font-size: var(--ug-text-2xs); line-height: 1.5; overflow-x: auto; color: var(--ug-text); white-space: pre; }
.gal-ci-why { padding: var(--ug-space-2xs) var(--ug-space-s); font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); }
.gal-ci-bad { color: var(--wa-color-danger-50); font-weight: var(--ug-weight-bold); }

.gal-ci-note { margin: var(--ug-space-l) 0 0; padding: var(--ug-space-s) var(--ug-space-m); border: var(--wa-border-width-s) solid var(--ug-brand-line); border-left: var(--wa-border-width-l, 4px) solid var(--ug-brand); border-radius: var(--ug-radius); background: var(--ug-brand-quiet); font-size: var(--ug-text-s); color: var(--ug-text); }

.gal-ci-rcard { margin: 0 0 var(--ug-space-s); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius); overflow: hidden; background: var(--ug-surface); box-shadow: var(--ug-shadow); }
.gal-ci-rtop { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--ug-space-3xs) var(--ug-space-s); padding: var(--ug-space-s) var(--ug-space-m); }
.gal-ci-rid { font-family: var(--ug-mono); font-weight: var(--ug-weight-bold); color: var(--ug-text-accent); }
.gal-ci-rname { font-weight: var(--ug-weight-bold); }
.gal-ci-rdesc { flex-basis: 100%; color: var(--ug-text-quiet); font-size: var(--ug-text-s); }
.gal-ci-rbody { display: grid; grid-template-columns: 1fr 1fr; border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); }
.gal-ci-rb { padding: var(--ug-space-s) var(--ug-space-m); }
.gal-ci-rb-ok { background: color-mix(in srgb, var(--wa-color-success-50) 7%, var(--ug-surface)); }
.gal-ci-rb-no { background: color-mix(in srgb, var(--wa-color-danger-50) 7%, var(--ug-surface)); border-left: var(--wa-border-width-s) solid var(--ug-border-quiet); }
.gal-ci-rb h4 { margin: 0 0 var(--ug-space-2xs); font-size: var(--ug-text-2xs); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); }
.gal-ci-rb-ok h4 { color: var(--wa-color-success-40, var(--wa-color-success-50)); }
.gal-ci-rb-no h4 { color: var(--wa-color-danger-40, var(--wa-color-danger-50)); }
.gal-ci-snip { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); line-height: 1.5; background: var(--ug-surface-sunk, var(--ug-surface-2)); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-radius: var(--ug-radius-s); padding: var(--ug-space-2xs) var(--ug-space-s); margin: 0 0 var(--ug-space-2xs); overflow-wrap: anywhere; color: var(--ug-text); }
.gal-ci-snip:last-child { margin-bottom: 0; }
.gal-ci-mini { font-size: var(--ug-text-2xs); color: var(--ug-text-faint); font-style: italic; margin-top: var(--ug-space-2xs); }
.gal-ci-foot { margin-top: var(--ug-space-m); font-size: var(--ug-text-2xs); color: var(--ug-text-faint); }
@media (max-width: 760px) { .gal-ci-rbody { grid-template-columns: 1fr; } .gal-ci-rb-no { border-left: none; border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); } }
@media (max-width: 900px) { .gal-ci-split { grid-template-columns: 1fr; } }
/* A 1fr track does not shrink below its widest content (a long code line); on
   a narrow screen it may, so the code block scrolls inside itself. */
@media (max-width: 640px) { .gal-ci-split { grid-template-columns: minmax(0, 1fr); } }

/* ── Forsiden: "Dele af UI-systemet" — ét kort pr. grammatik-begreb ─────────── */
.gal-del { margin: 0 0 var(--ug-space-xl, 2rem); padding: var(--ug-space-m) var(--ug-space-l); border: var(--wa-border-width-s) solid var(--ug-border-quiet); border-left: var(--wa-border-width-l, 4px) solid var(--ug-brand); border-radius: var(--ug-radius); background: var(--ug-surface); box-shadow: var(--ug-shadow); }
.gal-del > h3 { margin: 0 0 var(--ug-space-2xs); font-size: var(--ug-text-l, 1.15rem); }
.gal-del > h3 a { text-decoration: none; color: var(--ug-brand-strong); }
.gal-del > h3 a:hover { text-decoration: underline; }
.gal-del-abstract { margin: 0 0 var(--ug-space-s); color: var(--ug-text); }
.gal-del-fold { margin: 0 0 var(--ug-space-s); }
.gal-del-count { font-family: var(--ug-mono); font-size: var(--ug-text-2xs); font-weight: var(--ug-weight-normal, 400); color: var(--ug-text-quiet); }
.gal-del-exlist { margin: 0; padding-left: var(--ug-space-m); }
.gal-del-exlist li { margin-bottom: var(--ug-space-2xs); font-size: var(--ug-text-s); }
.gal-del-tag { display: inline-block; margin-left: var(--ug-space-3xs); padding: 0 var(--ug-space-2xs); border-radius: var(--ug-radius-s); font-family: var(--ug-mono); font-size: var(--ug-text-2xs); color: var(--ug-text-quiet); background: var(--ug-surface-sunk, var(--wa-color-neutral-95)); }
.gal-del-status { margin: var(--ug-space-2xs) 0 0; font-size: var(--ug-text-2xs); color: var(--ug-text-faint); }
.gal-del-ikke { margin: var(--ug-space-2xs) 0 0; padding: var(--ug-space-xs) var(--ug-space-m); border-left: var(--wa-border-width-l, 4px) solid var(--ug-warning-50); border-radius: 0 var(--ug-radius-s) var(--ug-radius-s) 0; background: var(--ug-surface-sunk, var(--wa-color-neutral-95)); font-size: var(--ug-text-s); color: var(--ug-text-quiet); }
.gal-del-ikke + .gal-del-ikke { margin-top: var(--ug-space-2xs); }
.gal-del-ikke-lab { display: inline-block; margin-right: var(--ug-space-2xs); font-size: var(--ug-text-2xs); font-weight: var(--ug-weight-bold); text-transform: uppercase; letter-spacing: var(--ug-tracking-label); color: var(--ug-warning-40); }
.gal-del-ikke-vigtig { border-left-color: var(--ug-brand); }
.gal-del-ikke-vigtig .gal-del-ikke-lab { color: var(--ug-brand-strong); }
.gal-del-seogsaa { margin-top: var(--ug-space-l); padding-top: var(--ug-space-s); border-top: var(--wa-border-width-s) solid var(--ug-border-quiet); font-size: var(--ug-text-s); color: var(--ug-text-quiet); }

.gal-section > h2 {
  border-bottom: 2px solid var(--wa-color-neutral-80);
  padding-bottom: 0.4rem;
}
.gal-count { color: var(--wa-color-neutral-50); font-weight: 400; font-size: 0.9rem; }

.gal-empty {
  padding: 1.5rem;
  border: 2px dashed var(--wa-color-neutral-70);
  border-radius: 0.5rem;
  color: var(--wa-color-neutral-50);
  text-align: center;
}

.gal-card {
  background: #fff;
  border: 1px solid var(--wa-color-neutral-80);
  border-radius: 0.6rem;
  margin: 1rem 0;
  overflow: hidden;
}
/* Two-row card head: the name (+ optional copy-button) and badge share the top
   row (badge pushed right by .gal-badge's margin-left:auto), the description
   wraps to its own full-width row below. Shared by every type-page card head
   (kompositionsrelationer/kompositionsgrupper/familier/overlays/slices/begreber). */
.gal-card-head {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
  padding: 0.75rem 1rem;
  background: var(--wa-color-neutral-95);
  border-bottom: 1px solid var(--wa-color-neutral-80);
}
.gal-card-head-top {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.gal-card-head code { font-weight: 700; font-size: 0.95rem; }
.gal-card-head .gal-kontekst,
.gal-card-head .gal-hint { color: var(--wa-color-neutral-50); font-size: 0.85rem; }

.gal-badge {
  margin-left: auto;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 0.2rem 0.55rem;
  border-radius: 9999px;
}
.gal-badge-ok   { background: var(--wa-color-success-90); color: var(--wa-color-success-30); }
.gal-badge-fejl { background: var(--wa-color-danger-90);  color: var(--wa-color-danger-30); }

.gal-preview { padding: 1.5rem 1rem; }
.gal-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 0; border-top: 1px solid var(--wa-color-neutral-80); }
.gal-detail > div { padding: 1rem; min-width: 0; }
.gal-detail > div + div { border-left: 1px solid var(--wa-color-neutral-80); }
.gal-detail h3 { margin: 0 0 0.5rem; font-size: 0.8rem; text-transform: uppercase; color: var(--wa-color-neutral-50); }

/* Kode-felter: pretty-printet + syntaks-farvet (mørk blok). white-space:pre-wrap
   så lange linjer ombrydes ved whitespace frem for at scrolle vandret (se .gal-code). */
.gal-code {
  margin: 0;
  background: #1b1e23;
  color: #cdd3de;
  padding: 0.85rem 1rem;
  border-radius: 0.45rem;
  /* Ombryd korrekt: pre-wrap bevarer linjeskift + indrykning (CSS er pretty-
     printet) OG ombryder lange linjer ved whitespace (template-tag-linjen)
     i stedet for vandret scroll. break-word fanger ekstreme uafbrudte strenge. */
  white-space: pre-wrap;
  overflow-wrap: break-word;
  tab-size: 2;
  font-family: var(--wa-font-family-code, ui-monospace, "SF Mono", Menlo, monospace);
  font-size: 0.8rem;
  line-height: 1.55;
}
.gal-code .hl-sel     { color: #7fd1b9; font-weight: 600; }   /* selector */
.gal-code .hl-prop    { color: #9cc7ff; }                     /* property */
.gal-code .hl-val     { color: #e6dcb3; }                     /* value */
.gal-code .hl-token   { color: #e89b6c; font-weight: 600; }   /* --design-token */
.gal-code .hl-punct   { color: #707a89; }                     /* { } : ; */
.gal-code .hl-comment { color: #6c7888; font-style: italic; }
.gal-code .hl-tag     { color: #7fd1b9; }                     /* <tag> */
.gal-code .hl-attr    { color: #9cc7ff; }                     /* attr= */
.gal-code .hl-action  { color: #e89b6c; }                     /* {{ … }} */
.gal-findings { list-style: none; margin: 0; padding: 0; }
.gal-findings li {
  background: var(--wa-color-danger-95);
  border-left: 3px solid var(--wa-color-danger-40);
  padding: 0.4rem 0.6rem;
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
}
.gal-findings li code { color: var(--wa-color-danger-30); font-weight: 700; }
.gal-ok-line { color: var(--wa-color-success-30); font-weight: 600; }

/* ── Regler-panel: status-farvede rækker ──────────────────────────────────
   The Regler list reuses .gal-findings for layout but each row is a RULE, not
   a finding — a passed rule must NOT inherit the danger-95 red background that
   .gal-findings li gives (that made every green ✓ rule read as a failure). Each
   row is tinted by its own status so the operator sees at a glance which rules
   passed, plus WHAT each rule checks (gal-rule-kort) and HOW it passed
   (gal-rule-detalje, the positive evidence). */
.gal-rules-panel .gal-rule {
  background: var(--wa-color-neutral-95);
  border-left: 3px solid var(--wa-color-neutral-70);
  padding: 0.45rem 0.65rem;
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
}
.gal-rule-ok   { background: var(--wa-color-success-95); border-left-color: var(--wa-color-success-50); }
.gal-rule-fejl { background: var(--wa-color-danger-95);  border-left-color: var(--wa-color-danger-40); }
.gal-rule-na   { background: var(--wa-color-neutral-95); border-left-color: var(--wa-color-warning-50); }
.gal-rule-top { display: flex; align-items: center; gap: 0.55rem; }
.gal-rule-id code { font-weight: 700; }
.gal-rule-ok   .gal-rule-id code { color: var(--wa-color-success-30); }
.gal-rule-fejl .gal-rule-id code { color: var(--wa-color-danger-30); }
.gal-rule-na   .gal-rule-id code { color: var(--wa-color-neutral-40); }
.gal-rule-kort { color: var(--wa-color-neutral-30); font-weight: 600; }
.gal-rule-detalje {
  margin: 0.25rem 0 0;
  padding-left: 0.1rem;
  color: var(--wa-color-neutral-40);
  font-size: 0.8rem;
  overflow-wrap: break-word;
}
.gal-badge-warn { background: var(--wa-color-warning-90); color: var(--wa-color-warning-30); }

@media (max-width: 640px) {
  .gal-detail { grid-template-columns: 1fr; }
  .gal-detail > div + div { border-left: none; border-top: 1px solid var(--wa-color-neutral-80); }
}

/* ── Element-søgefelt: fritekst-filter på element-navn (skifter til Vis alle) ── */
.gal-soegefelt { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; margin: 1.25rem 0 0.25rem; }
.gal-soegefelt[hidden] { display: none; } /* author display:flex would otherwise beat [hidden] */
.gal-soegefelt wa-input { flex: 1 1 320px; max-width: 480px; }
.gal-soege-status { font-size: 0.78rem; color: var(--wa-color-neutral-40); font-weight: 600; }

/* ── Kategori-vælger (element-/skærmkategori; genbrugt som tier-vælger på /parity): én kategori ad gangen, eller "Vis alle" (default) ──── */
.gal-katvaelger { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.6rem 0 1rem; }
/* "Vis alle"-pillen står først og er default-aktiv; ekstra højremargin sætter
   den visuelt fra de enkelte kategori-pills (den er view-mode, ikke en kategori). */
.gal-katpil-alle { font-weight: 700; margin-right: 0.5rem; }
.gal-katpil {
  font: inherit; font-size: 0.85rem; cursor: pointer;
  background: #fff; color: var(--wa-color-neutral-30);
  border: 1px solid var(--wa-color-neutral-80);
  border-radius: 9999px; padding: 0.3rem 0.85rem;
  display: inline-flex; align-items: center; gap: 0.4rem;
  transition: background 0.1s ease, border-color 0.1s ease, color 0.1s ease;
}
.gal-katpil:hover { border-color: var(--wa-color-brand-50); }
.gal-katpil.aktiv { background: var(--wa-color-brand-40); color: #fff; border-color: var(--wa-color-brand-40); }
.gal-katpil-antal {
  font-size: 0.72rem; font-weight: 700;
  background: var(--wa-color-neutral-90); color: var(--wa-color-neutral-40);
  border-radius: 9999px; padding: 0 0.4rem;
}
.gal-katpil.aktiv .gal-katpil-antal { background: rgba(255,255,255,0.25); color: #fff; }
/* The list filter's roles, hidden via the hidden attribute: an author display
   rule would otherwise beat the UA [hidden]{display:none}. */
[data-soeg][hidden],
[data-filter-sektion][hidden],
[data-filter-overskrift][hidden],
[data-filter-status][hidden],
[data-filter-tom][hidden] { display: none; }
/* Underkategori-sub-overskrift inde i en kategori-sektion (fx WA-appearance for Knap). */
.gal-underkat { display: flex; align-items: center; gap: 0.4rem; margin: 1.6rem 0 0.6rem; padding-bottom: 0.3rem; font-size: 0.9rem; font-weight: 700; color: var(--wa-color-neutral-30); border-bottom: 1px solid var(--wa-color-neutral-85); }
.gal-katsektion > .gal-underkat:first-child { margin-top: 0.4rem; }
.gal-underkat code { font-size: 0.82rem; background: var(--wa-color-neutral-95); padding: 0.05rem 0.45rem; border-radius: 0.35rem; }
.gal-underkat-antal { font-size: 0.72rem; font-weight: 700; background: var(--wa-color-neutral-90); color: var(--wa-color-neutral-40); border-radius: 9999px; padding: 0 0.4rem; }
.gal-badge-godkendt { background: var(--wa-color-brand-90); color: var(--wa-color-brand-30); }
.gal-badge-afventer { background: var(--wa-color-neutral-90); color: var(--wa-color-neutral-40); }
/* kandidat: relations/groups/screens vokabularet (godkendt|kandidat|kladde, ADR-0067)
   — bygget men ikke godkendt. Solid amber, distinkt fra kladdes dashede outline og
   godkendts brand (jf. look.css' "kandidat's solid amber tag"-konvention). */
.gal-badge-kandidat { background: var(--wa-color-warning-90); color: var(--wa-color-warning-30); }
/* kladde (ug3-j60cc.7): a name reserved before the design is built. Visually
   distinct from afventer (built, awaiting approval) and kandidat — a dashed
   warning-tone outline reads as "placeholder, not real yet". */
.gal-badge-kladde { background: var(--wa-color-warning-95); color: var(--wa-color-warning-30); outline: 1px dashed var(--wa-color-warning-50); outline-offset: -1px; }

/* Del-status-chips på et "afventer godkendelse"-skærmkort (/skaerme): kandidat-
   vs kladde-optælling af de refererede medlemmer, så GATE-blokeringen ses direkte
   på kortet. Farverne ekko'er gal-badge-kandidat (solid amber) / gal-badge-kladde
   (dashet amber), men chippene er mindre og uden .gal-badge's margin-left:auto. */
.gal-delkat-gruppe { display: inline-flex; align-items: center; gap: 0.3rem; }
.gal-delkat { font-size: 0.68rem; font-weight: 700; padding: 0.12rem 0.45rem; border-radius: 9999px; white-space: nowrap; }
.gal-delkat-kandidat { background: var(--wa-color-warning-90); color: var(--wa-color-warning-30); }
.gal-delkat-kladde   { background: var(--wa-color-warning-95); color: var(--wa-color-warning-30); outline: 1px dashed var(--wa-color-warning-50); outline-offset: -1px; }

/* Status-filter: alle / godkendt / afventer / kladde */
.gal-statusfilter,
.gal-artfilter,
.gal-wadfilter,
.gal-helsefilter,
.gal-vpfilter { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; margin: 0 0 1rem; }
.gal-statusfilter,
.gal-artfilter,
.gal-wadfilter { margin-bottom: 0.4rem; } /* tættere på det parallelle filter under det */
.gal-sf-label { font-size: 0.85rem; color: var(--wa-color-neutral-40); font-weight: 600; }
.gal-sf-pil,
.gal-art-pil,
.gal-wad-pil,
.gal-helse-pil,
.gal-vp-pil {
  font: inherit; font-size: 0.8rem; cursor: pointer;
  background: #fff; color: var(--wa-color-neutral-30);
  border: 1px solid var(--wa-color-neutral-80); border-radius: 9999px;
  padding: 0.25rem 0.75rem;
}
.gal-sf-pil:hover,
.gal-art-pil:hover,
.gal-wad-pil:hover,
.gal-helse-pil:hover,
.gal-vp-pil:hover { border-color: var(--wa-color-brand-50); }
/* .gal-vp-pil er MULTI-select toggles (hvert viewport til/fra uafhængigt), ikke
   single-select som status/art/wad/helse — men .aktiv = "vist" deler den samme
   visuelle pressed-state, så der er ingen særskilt stil. */
.gal-sf-pil.aktiv,
.gal-art-pil.aktiv,
.gal-wad-pil.aktiv,
.gal-helse-pil.aktiv,
.gal-vp-pil.aktiv { background: var(--wa-color-neutral-30); color: #fff; border-color: var(--wa-color-neutral-30); }
/* WA-dækning-badge (ADR-0073): wa-badge bærer sin egen farve via variant; her kun
   afstand fra status-badgen i kort-summaryens flex-række. */
.gal-el-sum .gal-wa-badge { margin-left: 0.4rem; }

/* ── Tre container-bredde-previews, stablet i rækker, FULD størrelse ─────
   Ingen skalering: hver body har sin reelle container-bredde. Desktop (1280)
   er bredere end siden → vandret scroll på den række (ærlig fuld-bredde).
   container-type:inline-size gør body til en query-container, så et elements
   @container-regler fyrer på den reelle bredde. */
.gal-viewports {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1rem;
  padding: 1.25rem 1rem;
  background: var(--wa-color-neutral-97, #f4f5f7);
  overflow-x: auto; /* desktop-cardet (1280) er bredere end siden → vandret scroll her */
}
/* Cardet ER container-bredden, så den faktiske bredde er synlig (768/390/1280). */
.gal-viewport {
  flex: none; margin: 0;
  border: 1px solid var(--wa-color-neutral-80);
  border-radius: 0.5rem; background: #fff; overflow: hidden;
}
.gal-viewport.gal-vp-desktop { width: 1280px; }
.gal-viewport.gal-vp-tablet  { width: 768px; }
.gal-viewport.gal-vp-mobil   { width: 390px; }
/* Global viewport-vælger (/klodser-toolbar, husket i localStorage): en rod-klasse
   skjuler den valgte bredde på tværs af alle korts previews. .gal-viewport er ren HTML
   (<figure>), IKKE en web-komponent — display:none er korrekt her og kolliderer ikke
   med nogen wa-*-komponents interne flex/grid (som er dét CLAUDE.md's "brug hidden,
   ikke display:none"-regel værner om). En rod-klasse (frem for hidden-attribut på hver
   figur) lader ét toggle skjule alle matchende previews på én gang.
   SCOPET til `.gal-viewports` (den tre-op preview-strip på /klodser, hvor mindst ét
   viewport altid vises) — så modalens STANDALONE enkelt-preview
   (.gal-nodemodal-preview, uden for .gal-viewports) aldrig kan blive helt tom. */
html.gal-vp-hide-desktop .gal-viewports .gal-viewport.gal-vp-desktop,
html.gal-vp-hide-tablet  .gal-viewports .gal-viewport.gal-vp-tablet,
html.gal-vp-hide-mobil   .gal-viewports .gal-viewport.gal-vp-mobil { display: none; }
.gal-viewport figcaption {
  font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--wa-color-neutral-50);
  padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--wa-color-neutral-90);
  background: var(--wa-color-neutral-95);
}
.gal-viewport-body {
  container-type: inline-size; /* @container fyrer på cardets reelle bredde */
  padding: 1.25rem 1rem;
  box-sizing: border-box;
}

/* ── Kompositionsrelationer: eksempel-komposition (premium preview) + Bruges af ───────── */
/* Foldbar live-preview pr. relation, vist side om side i lys + mørk. Genbruger
   .gal-viewport-chromet men dropper de faste device-bredder — de to celler deler
   grid-sporets bredde. Mørk-cellen får .wa-dark dark + samme #131211-flade som
   parity-dark (samme hus-mønster, ikke et gættet token). */
.gal-rel-preview { margin: 0.75rem 1rem 0; }
.gal-rel-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.75rem;
  margin-top: 0.5rem;
}
.gal-rel-preview-grid .gal-viewport { width: auto; }
.gal-rel-preview-grid .gal-viewport-light { background: var(--wa-color-surface-default, #fff); }
.gal-rel-preview-grid .gal-viewport-dark { background: #131211; color: var(--wa-color-neutral-90); }
.gal-rel-preview-grid .gal-viewport-dark figcaption {
  background: rgba(255, 255, 255, 0.05); color: var(--wa-color-neutral-60);
  border-bottom-color: rgba(255, 255, 255, 0.12);
}
/* Neutrale filler-fliser for en medlemsløs relations eksempel (rel-login-split,
   hvis sider ejes af login-rammen) — gør arrangeringen synlig uden at fingere
   registry-medlemskab. */
.gal-rel-flise {
  flex: 1 1 0; min-width: 0;
  padding: 1rem; border: 1px dashed var(--wa-color-neutral-60);
  border-radius: 0.4rem; text-align: center;
  font-size: 0.82rem; color: var(--wa-color-neutral-50);
  background: var(--wa-color-neutral-95);
}

/* ── Skærm-kort (/skaerme): foldbar live composed-render i et iframe ───────── */
/* Fluid-bredt preview (ikke de faste device-bredder), så kortet fylder grid-sporet
   som relations-/familie-previewet. Iframe'et viser /skaerm/<navn>/render i fuld
   bredde — et hurtigt overblik, ikke en pixel-perfekt device-ramme; den fulde
   composed-side åbnes via "Åbn render i ny fane". */
.gal-skaermkort-preview { width: auto; margin: 0.75rem 1rem 0; }
.gal-skaermkort-vp { padding: 0; }
.gal-skaerm-iframe {
  display: block; width: 100%; height: 460px; border: 0;
  background: var(--wa-color-surface-default, #fff); /* matcher rel-preview; undgår hvid flash i dark-mode før render maler */
}
.gal-skaermkort-links { margin: 0.75rem 1rem; }
/* Ramme-badge på skærm-kortet: ramme faldt fra grupperings-akse (nu skærmkategori) til
   en diskret annotation. Monospace + neutral, så den ikke konkurrerer med status-badges. */
.gal-el-sum .gal-skaerm-ramme {
  font-family: var(--ug-mono); font-size: var(--ug-text-2xs);
  color: var(--ug-text-quiet); white-space: nowrap;
}

/* Bruges af — hvor relationen optræder (dele to: medlems-elementer + skærme). */
.gal-rel-brugesaf {
  margin: 0.5rem 1rem 1rem; padding-top: 0.6rem;
  border-top: 1px solid var(--wa-color-neutral-90);
}
.gal-rel-brugesaf h3 { margin: 0.2rem 0 0.5rem; font-size: 0.95rem; }
.gal-rel-brugesaf-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.6rem 1.5rem;
}
.gal-rel-brugesaf h4 {
  margin: 0 0 0.4rem; font-size: 0.78rem; text-transform: uppercase;
  letter-spacing: 0.03em; color: var(--wa-color-neutral-50);
}
.gal-chiprow { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.gal-chip,
.gal-chiprow a.gal-noderef {
  display: inline-flex; align-items: baseline; gap: 0.35rem;
  padding: 0.2rem 0.5rem; border-radius: 0.35rem;
  border: 1px solid var(--wa-color-neutral-80); background: var(--wa-color-neutral-95);
  text-decoration: none; color: inherit; font-size: 0.82rem;
}
.gal-chip:hover,
.gal-chiprow a.gal-noderef:hover { border-color: var(--wa-color-neutral-50); }
.gal-chip[data-status="knækket"],
.gal-chip[data-status="mangler"],
.gal-chiprow a.gal-noderef[data-status="knækket"],
.gal-chiprow a.gal-noderef[data-status="mangler"] { border-color: var(--wa-color-danger-40); }
.gal-chip-sub { color: var(--wa-color-neutral-50); font-size: 0.72rem; }

/* ── Fælles relations-modal (gal-relmodal, relmodal.js) ─────────────────── */
.gal-relmodal { --width: min(46rem, 100vw); }
.gal-relmodal-titel { font-family: var(--wa-font-family-code); outline: none; }
.gal-relmodal-titel:focus-visible { outline: var(--wa-focus-ring); outline-offset: 2px; }
.gal-relmodal-nav { margin: 0 0 0.5rem; }
.gal-relmodal-henter,
.gal-relmodal-fejl p { margin: 0 0 0.5rem; }
.gal-relmodal-indhold[aria-busy="true"] { opacity: 0.5; }
.gal-relmodal-indhold .gal-nodeinfo-kant h3,
.gal-relmodal-indhold .gal-nodeinfo-brugesaf > h3 { margin: 1rem 0 0.35rem; font-size: 0.95rem; }
.gal-relmodal-indhold .gal-nodeinfo-kant h4 { margin: 0.6rem 0 0.25rem; font-size: 0.85rem; }
.gal-relmodal-indhold .gal-viewport-body { overflow-x: auto; }

/* ── Forside: farvepalette ─────────────────────────────────────────────── */
.gal-pal-label { margin: 1.25rem 0 0.4rem; font-size: 0.95rem; }
.gal-palette-row { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.gal-swatch {
  width: 72px; height: 56px;
  border: 1px solid rgba(0,0,0,0.12);
  border-radius: 0.4rem;
  cursor: pointer;
  display: flex; align-items: flex-end; justify-content: flex-end;
  padding: 0.25rem;
  position: relative;
  transition: transform 0.08s ease, box-shadow 0.08s ease;
}
.gal-swatch:hover { transform: translateY(-2px); box-shadow: 0 3px 8px rgba(0,0,0,0.25); }
.gal-swatch-step {
  font-size: 0.7rem; font-weight: 700;
  color: #fff; mix-blend-mode: difference;
  background: rgba(0,0,0,0.0);
}
/* Click-tooltip: clicking a swatch shows its hex (and copies it to clipboard).
   A floating bubble above the swatch, fades in/out via .gal-tip-vis from JS. */
.gal-swatch-tip {
  position: absolute; left: 50%; bottom: calc(100% + 6px);
  transform: translateX(-50%);
  background: var(--wa-color-neutral-10); color: #fff;
  font: 700 0.72rem var(--ug-mono, ui-monospace, monospace);
  padding: 0.2rem 0.45rem; border-radius: 0.3rem; white-space: nowrap;
  pointer-events: none; z-index: 10;
  opacity: 0; transition: opacity 0.12s ease;
}
.gal-swatch-tip::after {
  content: ""; position: absolute; top: 100%; left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent; border-top-color: var(--wa-color-neutral-10);
}
.gal-swatch-tip.gal-tip-vis { opacity: 1; }
/* Ren identitetsfarve: shown ABOVE its tint ramp (brand/accent). The swatch
   reuses .gal-swatch sizing; a ring + meta label set it apart from the ramp,
   making clear it is the core-colour identity, not a tint step (ADR-0047). */
.gal-ren-row { display: flex; align-items: center; gap: 0.6rem; margin: 0.1rem 0 0.5rem; }
.gal-ren-swatch { box-shadow: 0 0 0 2px var(--wa-color-neutral-95), 0 0 0 3px var(--wa-color-neutral-40); }
.gal-ren-meta { font-size: 0.8rem; color: var(--wa-color-neutral-40); }
.gal-ren-meta code { font-size: 0.78rem; }

/* ── Forside: ikon-fliser ──────────────────────────────────────────────── */
.gal-icon-tiles { display: flex; flex-wrap: wrap; gap: 1rem; }
.gal-icon-tile {
  flex: 1 1 200px;
  border: 1px solid var(--wa-color-neutral-80);
  border-radius: 0.6rem;
  padding: 1.5rem 1rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.75rem;
  text-align: center;
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.gal-icon-tile:hover { transform: translateY(-3px); box-shadow: 0 4px 14px rgba(0,0,0,0.18); }
.gal-icon-tile wa-icon { transition: transform 0.1s ease; }
.gal-icon-tile:hover wa-icon { transform: scale(1.12); }
.gal-tile-label { font-size: 0.8rem; font-weight: 600; }
.gal-hint { color: var(--wa-color-neutral-50); font-size: 0.85rem; }

/* Forsidens flade-demo: ikoner på hvid/brand/accent via semantiske tokens.
   .on-brand (look.css kontekst-lag) re-mapper ink-rollerne til hvid på brand.
   Accent-fladen følger ADR-0047's kanoniske ikon-på-accent-behandling: §1
   ("brand-teal primær + hvid sekundær, aldrig sort — designvalg 2026-06-15")
   + §2 amendment 2026-06-25 ("sekundær re-mappes til brand-teal/hvid — accent-
   core ville være coral-på-coral"). LABELEN er derimod TEKST og bærer sort
   on-tekst per §2-tabellen (accent | sort | 7.0:1). ug3-eb7lt */
.gal-tile-hvid   { background: var(--ug-surface); }
.gal-tile-brand  { background: var(--ug-brand); }
.gal-tile-accent { background: var(--ug-accent); --ug-ink-icon-primary: var(--ug-brand); --ug-ink-icon-secondary: var(--ug-on-brand); }
.gal-tile-brand .gal-tile-label { color: var(--ug-on-brand); }
.gal-tile-accent .gal-tile-label { color: var(--ug-on-accent); }
.gal-demo-icon { font-size: 2.5rem; }

/* ── Forside: farve-dialog (klik på swatch) ────────────────────────────── */
.gal-fm-preview {
  height: 96px;
  border-radius: 0.5rem;
  border: 1px solid var(--wa-color-neutral-80);
}
.gal-fm-dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1.25rem;
  margin: 1rem 0 0;
}
.gal-fm-dl dt { font-weight: 700; color: var(--wa-color-neutral-50); }
.gal-fm-dl dd { margin: 0; }
.gal-fm-dl code { font-size: 0.95rem; }

/* ── Elementer-side: toolbar + element-kategori + fold-bare kort ───────────────── */
.gal-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem;
  margin: 1rem 0 2rem;
}
.gal-toolbar wa-input { flex: 1 1 280px; max-width: 440px; }
.gal-kat {
  margin: 1.5rem 0 0.5rem;
  font-size: 1rem;
  color: var(--wa-color-neutral-40);
}
.gal-katgruppe[hidden] { display: none; }
.gal-el {
  margin: 0.6rem 0;
  background: #fff;
  border: 1px solid var(--wa-color-neutral-80);
  border-radius: 0.6rem;
  scroll-margin-top: 1rem; /* deep-link scrollIntoView clears any sticky chrome */
}
/* Perf (2026-07-06): 265 kort × 3 container-previews gør /klodser tung.
   content-visibility lader browseren springe layout/paint over for kort uden
   for viewporten; contain-intrinsic-size reserverer ca. lukket-kort-højde så
   scrollbaren ikke hopper når kort strømmer ind. */
wa-details.gal-el { content-visibility: auto; contain-intrinsic-size: auto 3.5rem; }
/* Deep-link puls: når en #el-<navn>-hash (fx fra /tokens "bruges af") åbner et
   kort, fremhæves det kortvarigt så øjet finder det, og falder så til ro. */
.gal-el-fremhaev { outline: 2px solid var(--wa-color-brand-40); outline-offset: 2px; box-shadow: 0 0 0 4px var(--wa-color-brand-95); transition: outline-color 0.3s ease, box-shadow 0.3s ease; }
.gal-el::part(header) { padding: 0.6rem 0.9rem; }
.gal-el::part(content) { padding: 0; }
.gal-el-sum { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; width: 100%; }
.gal-el-sum code { font-weight: 700; }
.gal-el-copy,
.gal-card-copy { font-size: 0.95rem; color: var(--wa-color-neutral-50); }
.gal-fa-label { font-size: 0.85rem; color: var(--wa-color-neutral-40); font-weight: 600; }
.gal-fa-select { min-width: 16rem; }
.gal-duo-kontrol {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0.75rem;
  margin: 0 0 1rem; padding: 0.75rem 1rem;
  background: var(--wa-color-neutral-95);
  border: 1px solid var(--wa-color-neutral-80); border-radius: 0.5rem;
}
.gal-duo-kontrol > strong { flex-basis: 100%; font-size: 0.85rem; color: var(--wa-color-neutral-40); }
.gal-duo-felt { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.78rem; color: var(--wa-color-neutral-40); }
.gal-duo-felt wa-input { width: 6rem; }
.gal-el-sum .gal-kontekst { color: var(--wa-color-neutral-50); font-size: 0.85rem; }
.gal-el-sum .gal-badge { margin-left: auto; }
.gal-rulecheck { padding: 1rem; border-top: 1px solid var(--wa-color-neutral-80); }
.gal-rulecheck h3 { margin: 0 0 0.5rem; font-size: 0.8rem; text-transform: uppercase; color: var(--wa-color-neutral-50); }

/* ── Skærm-struktur-træ (skaerm.gohtml "Består af") ─────────────────────────
   Mørk monospace komposit-visning: ÉN node pr. række — connector-præfiks (.gal-pre)
   + type-farvet node-label (.gal-node) + dæmpet annotation (.gal-ann) til højre.
   Spejler det visuelle sprog fra grammatik-i-praksis.html's .tree/.trow (panel ⑤/⑦):
   node-typefarver, slot-/dybde-/status-badges. Præsentation-only — træet forbruger
   samme Tilstande-data som den tidligere flade gal-bestaraf-liste, kun tegnet om. */
.gal-tree {
  font-family: var(--wa-font-family-code, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 0.8rem;
  background: #0f1720;
  color: #dce6ef;
  border-radius: 0.75rem;
  padding: 1.1rem 1.4rem;
  margin: 1rem 0;
  overflow-x: auto;
}
.gal-thead {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-bottom: 0.65rem; padding-bottom: 0.65rem;
  border-bottom: 1px solid #24303d;
}
.gal-thead .gal-tt { font-weight: 700; font-size: 0.82rem; color: #dce6ef; }
.gal-thead .gal-tt code { color: #c4d2e2; font-weight: 700; }
.gal-tbadge {
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.3px;
  padding: 0.12rem 0.55rem; border-radius: 9999px; white-space: nowrap;
}
.gal-tbadge-ramme { background: #16252f; color: #7fd0ff; }

.gal-trow { display: flex; align-items: baseline; padding: 0.18rem 0; }
.gal-pre { white-space: pre; color: #56657a; flex: none; }
.gal-node { flex: none; font-weight: 700; white-space: nowrap; }
.gal-ann {
  flex: 1 1 0; min-width: 0; margin-left: 1rem;
  color: #7c8a99; font-size: 0.72rem; line-height: 1.4;
}
/* Node-typefarver (reference panel ⑤/⑦): Ramme = næsten-hvid, slot = grålig blå,
   Skærm/Skærmtilstand/Indhold = blå, Kompositionsrelation = orange, Kompositionsgruppe = pink,
   Element = teal, Familie = lilla. Mangler = dæmpet rød. */
.gal-node-ram  { color: #eaf0f7; }
.gal-node-slot { color: #9fb3c4; font-weight: 600; }
.gal-node-scr  { color: #9db8d6; }
.gal-node-ind  { color: #c4d2e2; }
.gal-node-rel  { color: #f0b169; }
.gal-node-grp  { color: #f5a3c7; }
.gal-node-el   { color: #7ee0d2; }
.gal-node-fam  { color: #c9a8f0; }
.gal-node-mangler { color: #e88f86; }

/* A node rendered as a trigger/link (opens its modal, or links to its type-page /
   ramme). Shared gallery primitive — used by the skaerm connector-tree AND the
   ramme pages (/rammer, /ramme/<navn>); keep it here, not in a page-scoped style. */
.gal-node-aabn { appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 2px; text-decoration-style: dotted; }
.gal-node-aabn:hover, .gal-node-aabn:focus-visible { text-decoration-style: solid; }

/* Et noderef-link inde i en type-farvet node i connector-træet arver nodens farve,
   så træets type-farver (relation/klods/gruppe) består. */
.gal-node .gal-noderef { color: inherit; }
.gal-node .gal-noderef code { background: none; padding: 0; font: inherit; color: inherit; }

/* Hovedet og forhåndsvisningen i node-info-fragmentet i den fælles modal. */
.gal-nodemodal-top { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0 0 0.6rem; }
.gal-nodemodal-top code { font-weight: 700; }
/* "Åbn detaljeside →" — pushed to the far right of the header row via margin-left:
   auto on the flex row above (no new WA utility needed for a single flex-item).
   Color reuses the brand link token already used elsewhere for gal-* deep-links. */
.gal-nodemodal-detalje { margin-left: auto; white-space: nowrap; color: var(--wa-color-brand-40); }
.gal-nodemodal-preview { margin: 0; }
/* Fit the dialog width instead of gal-vp-desktop's fixed 1280px, so a full-width
   element (inline-size:100%) renders fully inside the modal rather than overflowing. */
.gal-nodemodal-preview.gal-vp-desktop { width: 100%; }

/* Member-rows: en <ul> så :last-child kan bytte connector ├─ → └─ uden
   template-aritmetik (galleriets FuncMap har ingen len/sub). Connector-præfikset
   tegnes UDELUKKENDE i CSS via ::before — .gal-pre i member-template'en er tom. */
.gal-tmembers { list-style: none; margin: 0; padding: 0; }
.gal-tmember .gal-pre::before { content: "│           ├─ "; }
.gal-tmember:last-child .gal-pre::before { content: "│           └─ "; }

/* Relationsmedlemmer inline (ADR-0067): den nested <ul> sidder ÉT
   niveau dybere under sin gruppe-node. flex-wrap på member-rækken + flex-basis:100%
   på .gal-tsub tvinger listen ned på sin egen linje under rækken (uden :has()), så
   nesten virker på enhver Chrome. Connector tegnes igen i CSS via ::before.
   BÅDE .gal-tmember (top-niveau gruppe) OG .gal-tsubmember (en gruppe der selv er
   medlem af en gruppe) skal wrappe — ellers renderer en nestet gruppes egne
   medlemmer i samme flex-række til HØJRE for noden i stedet for indrykket nedenunder. */
.gal-tmember, .gal-tsubmember { flex-wrap: wrap; }
.gal-tsub { flex-basis: 100%; list-style: none; margin: 0; padding: 0; }
.gal-tsubmember .gal-pre::before { content: "│              ├─ "; }
.gal-tsubmember:last-child .gal-pre::before { content: "│              └─ "; }
/* Dybere nesting (gruppe-i-gruppe-i-gruppe): connector-præfikset er fast pr. klasse,
   så dybden vises i stedet ved at rykke hver nestet <ul> ÉT trin til højre. Padding
   componder pr. niveau (en .gal-tsub inde i en .gal-tsubmember), så niveau 2, 3, …
   trapper visuelt — uden at røre niveau-1-layoutet (en .gal-tsub direkte under en
   .gal-tmember har ingen .gal-tsubmember-forælder og rammes derfor ikke). */
.gal-tsubmember > .gal-tsub { padding-left: 1.5rem; }

/* Position-mærke (1-baseret Plads-binding). Lille dæmpet pille foran medlems-noden. */
.gal-tpos {
  flex: none; align-self: center; margin-right: 0.4rem;
  min-width: 1.15rem; text-align: center;
  font-size: 0.6rem; font-weight: 700; line-height: 1.3;
  padding: 0.04rem 0.3rem; border-radius: 9999px;
  background: #1b2630; color: #9fb3c4; border: 1px solid #2c3b49;
}

/* Familie-tilhør (⬡): element-metadata, IKKE en node. Familie-farve (jf. .gal-node-fam). */
.gal-tfam {
  font-size: 0.6rem; font-weight: 700; letter-spacing: 0.3px;
  padding: 0.05rem 0.45rem; border-radius: 0.35rem; margin-left: 0.45rem;
  white-space: nowrap; background: #241a33; color: #c9a8f0;
}

/* "arrangeret af rel-X · følge" — gruppens arrangerende kompositionsrelation, dæmpet annotation. */
.gal-tarr { margin-left: 0.55rem; color: #8a97a6; font-size: 0.68rem; }
.gal-tarr code { color: #f0b169; font-weight: 700; }

/* Betingelse på en valgfri relationsmedlem-Plads (ADR-0067). */
.gal-tcond { margin-left: 0.45rem; color: #9a8ab0; font-size: 0.66rem; font-style: italic; }

/* Annotation-tags (slot-fyldning, dybde, status) — reference .fill/.free/.koster. */
.gal-tag {
  font-size: 0.6rem; font-weight: 700; letter-spacing: 0.3px;
  padding: 0.05rem 0.45rem; border-radius: 0.35rem; margin-left: 0.45rem;
  white-space: nowrap;
}
.gal-tag-fill { background: #13352f; color: #54d6a0; }
.gal-tag-fri  { background: #3a3320; color: #e7c07a; }
.gal-tag-kand { background: #2a2c1a; color: #d4d07a; }
.gal-tag-fejl { background: #3a2330; color: #f5a3c7; }
/* kladde (ug3-j60cc.7): reserved-but-unbuilt — dashed amber outline reads as
   "placeholder, not real yet", distinct from kandidat's solid amber tag. */
.gal-tag-kladde { background: #2a2410; color: #e7c060; outline: 1px dashed #8a7320; outline-offset: -1px; }

.gal-tfoot {
  margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px solid #24303d;
  display: flex; gap: 1.25rem; flex-wrap: wrap;
}
.gal-tfoot .gal-okk { color: #54d6a0; font-weight: 700; font-size: 0.72rem; }

/* Byg-flade (byg.gohtml): spacing for the tegnebræt's control row above the
   live gal-tree. Spacing-only — the tree itself reuses the gal-tree block above. */
.gal-byg-kontrol { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1rem 0; }

/* Slice-picker fejl-besked (ug3-j60cc.2.3): a WRAPPING red error paragraph in the
   dialog — distinct from the neutral grey .gal-hint tom-tekst. A full sentence,
   so it must wrap (the .gal-tag pill is white-space:nowrap and overflows on 390px),
   hence a block paragraph rather than a status pill. */
.gal-byg-fejl { color: var(--wa-color-danger-40); font-size: 0.85rem; font-weight: 600; margin: 0; }

/* Realisér-flip-knap (ug3-j60cc.2.5): a compact inline button that toggles a node's
   realiseret state (KOMMER ↔ FINDES). Rendered BOTH inside the dark tree row's
   .gal-ann AND in the light mangler-liste, so it carries its own contrast (dark
   background + light text) and reads on either. Spacing/affordance only — no WA-utility
   covers an inline tree-row action button. */
.gal-byg-flip {
  font: inherit; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.3px;
  cursor: pointer; margin-left: 0.45rem; white-space: nowrap;
  background: #16252f; color: #7fd0ff;
  border: 1px solid #2c4456; border-radius: 0.35rem;
  padding: 0.08rem 0.5rem;
}
.gal-byg-flip:hover { border-color: #7fd0ff; }
.gal-byg-flip:focus-visible { outline: 2px solid #7fd0ff; outline-offset: 1px; }
/* In the light mangler-liste row the same button sits on a pale background, so swap to
   a light-on-brand-tint skin for contrast. */
.gal-findings .gal-byg-flip { background: var(--wa-color-brand-95); color: var(--wa-color-brand-30); border-color: var(--wa-color-brand-80); }

/* ── UG semantic tokens (--ug-*: det ene projekt-semantik-namespace, ADR-0047) ──
   Roller, on-tekst, type/space/tracking/weight/radius. Bygger på --wa-* primitiver.
   Konsolideret fra de tidligere app- og ca-navne (ADR-0047, 2026-06-20). */
:root, .wa-light {
  --ug-bg:            var(--wa-color-neutral-95);
  --ug-surface:       #ffffff;
  --ug-text:          var(--wa-color-neutral-10);
  --ug-text-quiet:    var(--wa-color-neutral-40);
  /* --ug-text-soft sits between quiet and faint on the LIGHT background (most→least
     visible: text > quiet > soft > faint). On a brand-flade a kompositionsrelation re-maps
     it to --ug-on-brand-soft (see brand-surface override below). color-mix gives
     a genuine neutral-45 without inventing a named palette step. ADR-0047. */
  --ug-text-soft:     color-mix(in srgb, var(--wa-color-neutral-40), var(--wa-color-neutral-50));
  --ug-text-faint:    var(--wa-color-neutral-50);
  /* Context-neutral ICON-ink roles (ADR-0047 tier-2). Elements read these and
     NEVER --ug-brand/--ug-accent directly, so a kompositionsrelation/kompositionsgruppe-flade can
     re-map them via the cascade. Default context = dark-on-light: primary teal,
     secondary the RENE accent-core. The duotone foundation below consumes these. */
  --ug-ink-icon-primary:           var(--ug-brand);
  --ug-ink-icon-secondary:         var(--ug-icon-accent);
  /* Duotone-ikoners accent-sekundærfarve = den RENE accent-core (--ug-icon-accent
     = --ug-accent = #EA7246) ved fuld opacity (1), ALDRIG en lysere tint (fx
     accent-70). Identitetsfarven bærer duotone-laget; opacity er et token så en
     kontekst-flade kan re-mappe den, men defaulter til 1. ADR-0047 §2. */
  --ug-ink-icon-secondary-opacity: 1;
  --ug-brand:         #00483e; /* ren brand-identitet (seed, oklch 0.36 0.065 180; jf. :7) — IKKE et tint-trin */
  --ug-brand-strong:  var(--ug-brand); /* brand-TEKST (titler/links): mørk core #00483e på lys flade. Brand-SURFACE (split-panel/CTA) bruger --ug-brand DIREKTE, ikke dette. Dark-mode → brand-80 (lys teal) for kontrast (l.1268). */
  --ug-accent:        var(--wa-color-accent-60); /* ren accent-identitet #EA7246 (farve-token-arkitektur.md:68 + ADR-0047: trin 60, AAA-kravet "accent=sort tekst" loeftede den fra ren mid-coral) */
  /* Rene core-identitetsfarver for ALLE familier (ADR-0047 core-colour, kanonisk
     farve-spec). Hver families "base" — den rene identitet, IKKE et kontrast-stige-trin.
     Kontekst-invariant: ingen .wa-dark-override (jf. --ug-brand/--ug-accent). De familier
     hvis base falder PÅ et trin peger på trinnet; success/warning ligger MELLEM trin (hhv.
     over hele stigen) og er derfor rå hex. */
  --ug-danger:        var(--wa-color-danger-40);     /* #b6000e — danger-base = trin 40 */
  --ug-success:       #63b375;                        /* ren success-base (oklch 0.70 0.120 150) — mellem trin 70/60 */
  --ug-warning:       #fff075;                        /* ren warning-base (oklch 0.94 0.144 102) — lysere end hele stigen */
  --ug-neutral:       var(--wa-color-neutral-50);     /* #787573 — neutral-base = trin 50 */
  --ug-lys-accent:    var(--wa-color-lys-accent-50);  /* #946c5c — lys-accent-base = trin 50 */
  --ug-lys-brand:     var(--wa-color-lys-brand-50);   /* #66797f — lys-brand-base = trin 50 */
  --ug-info:          var(--wa-color-lys-brand-40);   /* #4a5c62 — info-tone (lys-brand trin 40, hvid tekst 7.0:1 AAA). Core-anker; badge + panel afspejler værdien via --ug-surface-info. Distinkt fra brand (CTA/store grafiske flader). */
  /* Accent paa TEKST (ADR-0060 semantisk use-tier). Aliaserer den raa
     --ug-accent-primitiv, saa accent-TEKST senere kan divergere (fx goeres
     moerkere) ET sted uden at roere accent-baggrunde/ikon-fyld. Elementer
     bruger DETTE for color:, ALDRIG den raa --ug-accent (konvention, ikke lintet). Vaerdi-identisk med
     --ug-accent i dag. */
  --ug-text-accent:   var(--ug-accent);
  /* Accent paa duotone-IKON-FYLD (ADR-0060 semantisk use-tier; ADR-0047
     §Consequences-1). Aliaserer den raa --ug-accent-primitiv for den 3.
     divergerbare use-kontekst: duotone-ikon-fyld via wa-icon --secondary-color
     (13 knap-elementer). Parallelt med --ug-text-accent (tekst) saa accent-
     ikon-fyld senere kan divergere fra accent-tekst/-baggrund ET sted uden at
     roere de andre. Elementer peger paa DETTE for --secondary-color, ALDRIG den
     raa --ug-accent. Vaerdi-identisk med --ug-accent i dag (intet dark-override
     -> konstant i begge temaer, som accent-primitiven). */
  --ug-icon-accent:   var(--ug-accent);
  --ug-border:        var(--wa-color-neutral-80);
  --ug-border-quiet:  var(--wa-color-neutral-90);

  /* Grammatik-begrebsgraf node-type-farver (forklaringer/#begrebsgraf). One hue
     per grammar node-type is the doc's pedagogical key — read the graph by colour.
     Lifted verbatim from the source doc's vetted light/dark palettes; the dark
     variants live in the .wa-dark block. Scoped to the graf section only. */
  --ug-graf-skaerm:   #1769aa;  --ug-graf-ramme:    #5a6776;
  --ug-graf-tilstand: #0d7a92;  --ug-graf-indhold:  #48586a;
  --ug-graf-rel:      #6b46c1;  --ug-graf-gruppe:   #8b3fd1;
  --ug-graf-element:  #1a8b5a;  --ug-graf-slice:    #9a5b00;
  --ug-graf-familie:  #c0306a;  --ug-graf-token:    #0d8b6f;
  --ug-graf-overlay:  #9a6b00;

  /* Prik-paletten: the identity tones a visitor-surface tile can wear. A sender has
     no brand of its own, so the tone is derived from the row id — a FIXED, enumerated
     set rather than a free colour, because E5 forbids an inline style on element
     markup. Farve-1..4 and --ug-prik-samling are the design oracle's own hues for
     flade dit-program-samlet; farve-0 is the quiet tone for a tile whose key is
     missing. All pair with --ug-on-prik-farve, which puts them in the AA band rather
     than the AAA one the --ug-on-* roles above hold — a deliberate trade for keeping
     the oracle's hues, open to the gallery review. The guest's own tile takes no
     palette key: ug-egen-prik fills from --ug-accent, the surface's own accent. */
  --ug-prik-farve-0:  #5b5957;
  --ug-prik-farve-1:  #9c660a;
  --ug-prik-farve-2:  #c14e33;
  --ug-prik-farve-3:  #a8326e;
  --ug-prik-farve-4:  #00836d;
  --ug-prik-samling:  #0e7a5f;
  --ug-on-prik-farve: #fff;

  /* type scale — extracted from auth.css literals */
  --ug-text-2xl: 1.5625rem;   /* 25px — login title */
  --ug-text-14:  0.875rem;    /* 14px — topbar label (search/user/langswitch/logo) */
  --ug-text-m:   0.90625rem;  /* 14.5px — subtitle */
  --ug-text-s:   0.78125rem;  /* 12.5px — footnote */
  --ug-text-xs:  0.6875rem;   /* 11px — eyebrow/divider */
  --ug-text-2xs: 0.65625rem;  /* 10.5px — placeholder label */
  --ug-text-3xs:  0.53125rem; /* 8.5px — micro-label (redform.css) */
  --ug-text-2xs-s:0.59375rem; /* 9.5px — dense meta (samlet/liste.css) */
  --ug-text-xs-s: 0.625rem;   /* 10px — small mono/badge (liste.css) */
  --ug-text-s-d:  0.71875rem; /* 11.5px — table-head/footnote (samlet.css) */
  --ug-text-s-u:  0.75rem;    /* 12px — most-used body-small (37x liste/samlet/redform) */
  --ug-text-ms:   0.8125rem;  /* 13px — 2nd-most-used (31x) row/label text */
  --ug-text-md:   0.84375rem; /* 13.5px — control text (liste.css) */
  --ug-text-m-u:  0.875rem;   /* 14px — input text (samlet.css) */
  --ug-text-l-d:  0.96875rem; /* 15.5px — rare (samlet.css) */
  --ug-text-l:    0.9375rem;  /* 15px — section lead (samlet/liste.css) */
  --ug-text-base: 1rem;       /* 16px — body base (liste/samlet.css) */
  --ug-text-l-u:  1.0625rem;  /* 17px — subheading (samlet.css) */
  --ug-text-xl:   1.125rem;   /* 18px — card title (samlet.css) */
  --ug-text-2xl-xs:1.25rem;   /* 20px — number (redform/samlet.css) */
  --ug-text-2xl-s:1.3125rem;  /* 21px — stat number (redform/samlet.css) */
  --ug-text-2xl-m:1.375rem;   /* 22px — KPI number (samlet.css) */
  --ug-text-2xl-l:1.5rem;     /* 24px — large stat (samlet.css) */
  --ug-text-3xl-s:1.625rem;   /* 26px — hero number (samlet.css) */
  --ug-text-3xl-m:1.75rem;    /* 28px — hero number (samlet.css) */

  /* space scale — from auth.css gaps */
  --ug-space-m:   1rem;     /* 16px */
  --ug-space-s:   0.75rem;  /* 12px */
  --ug-space-xs:  0.5625rem;/* 9px */
  --ug-space-2xs: 0.4375rem;/* 7px */
  --ug-space-4xs: 0.0625rem;  /* 1px — hairline (liste.css) */
  --ug-space-3xs: 0.125rem;   /* 2px — micro gap (samlet/liste.css) */
  --ug-space-2xs-s:0.1875rem; /* 3px — tight gap (liste.css) */
  --ug-space-2xs-u:0.25rem;   /* 4px — tile gap (samlet.css) */
  --ug-space-xs-d:0.3125rem;  /* 5px — chip gap (samlet.css) */
  --ug-space-xs-s:0.375rem;   /* 6px — most-used gap (samlet/liste.css) */
  --ug-space-s-d: 0.5rem;     /* 8px — most-used gap (samlet/liste.css) */
  --ug-space-s-u: 0.625rem;   /* 10px — row gap (samlet.css) */
  --ug-space-s-m: 0.6875rem;  /* 11px — most-used padding (liste.css) */
  --ug-space-m-d: 0.8125rem;  /* 13px — most-used padding (samlet.css) */
  --ug-space-m-u: 0.875rem;   /* 14px — card padding (samlet.css) */
  --ug-space-ml:  0.9375rem;  /* 15px — note padding (samlet.css) */
  --ug-space-l:   1.125rem;   /* 18px — card padding (samlet.css) */
  --ug-space-xl:  1.25rem;    /* 20px — section gap (samlet.css) */
  --ug-space-xl-m:1.375rem;   /* 22px — card padding (samlet.css) */
  --ug-space-2xl: 1.5rem;     /* 24px — block padding (samlet.css) */
  --ug-space-2xl-m:1.625rem;  /* 26px — gap (samlet.css) */
  --ug-space-2xl-l:1.75rem;   /* 28px — gap (samlet.css) */
  --ug-space-3xl: 1.875rem;   /* 30px — block padding (samlet.css) */
  --ug-space-3xl-l:2rem;      /* 32px — block padding (samlet.css) */
  --ug-space-4xl: 2.125rem;   /* 34px — gap (samlet.css) */
  --ug-space-4xl-l:2.25rem;   /* 36px — block padding (samlet.css) */
  --ug-space-5xl: 4rem;       /* 64px — large pad (samlet.css) */
  --ug-space-6xl: 7.5rem;     /* 120px — hero pad (samlet.css) */
  --ug-space-none: 0rem;      /* 0 — flush stack (første brug: fane-aktivstreg, ug3-6nqle) */

  /* tracking scale — from auth.css letter-spacing */
  --ug-tracking-tight: -0.022em;
  --ug-tracking-wide:  0.1em;
  --ug-tracking-wider: 0.12em;
  --ug-tracking-label: 0.08em;
  --ug-tracking-tightest: -0.025em; /* -.025em (samlet.css) */
  --ug-tracking-tighter:  -0.02em;  /* -.02em — most-used negative (6x) */
  --ug-tracking-snug:     -0.01em;  /* -.01em (liste/samlet.css) */
  --ug-tracking-flush:     0.01em;  /* .01em (samlet.css) */
  --ug-tracking-xs:        0.02em;  /* .02em (samlet.css) */
  --ug-tracking-s:         0.03em;  /* .03em (liste.css) */
  --ug-tracking-m:         0.04em;  /* .04em — most-used positive (7x) */
  --ug-tracking-ml:        0.05em;  /* .05em (samlet.css) */
  --ug-tracking-l:         0.06em;  /* .06em — table-head (samlet.css) */
  --ug-tracking-xl:        0.09em;  /* .09em (samlet.css) */
  --ug-tracking-2xl:       0.11em;  /* .11em (samlet.css) */
  --ug-tracking-3xl:       0.14em;  /* .14em (samlet.css) */

  /* weight scale (--fw-* is NOT C8-valid; these are) */
  --ug-weight-light:    300;
  --ug-weight-medium:   500;
  --ug-weight-semibold: 600;
  --ug-weight-bold:     700;

  /* fonts */
  --ug-font: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --ug-mono: 'IBM Plex Mono', ui-monospace, monospace;
  /* The display face: headings and titles on the visitor surface. The gallery
     shows them in the body face; a customer theme sets its own (a serif for a
     book fair) through the embed's token bridge. */
  --ug-font-display: var(--ug-font);

  /* ── Token-runde: surface/border, brand/accent, status, radius, brand-panel ── */
  --ug-surface-2:    var(--wa-color-neutral-95);
  --ug-surface-sunk: var(--wa-color-neutral-90);
  --ug-border-strong: var(--wa-color-neutral-70);
  --ug-icon-tile:    var(--wa-color-neutral-95);
  --ug-brand-line:   var(--wa-color-brand-80);
  --ug-brand-quiet:  var(--wa-color-lys-brand-95);
  --ug-accent-line:  var(--wa-color-accent-80);
  --ug-accent-quiet: var(--wa-color-accent-95);
  --ug-row-hover:    var(--wa-color-neutral-95);
  --ug-shadow:     0 1px 2px rgba(16,19,19,.06), 0 4px 16px -8px rgba(16,19,19,.14);
  --ug-shadow-pop: 0 8px 30px -8px rgba(16,19,19,.26), 0 2px 6px rgba(16,19,19,.10);
  --ug-radius-l: 16px;

  /* brand-panel hvid-på-mørk — kontekst-invariant (KUN her, IKKE gentaget i .wa-dark) */
  --ug-on-brand:       #fff;
  --ug-on-brand-quiet: rgba(255,255,255,.92);
  --ug-on-brand-soft:  rgba(255,255,255,.78);
  --ug-on-brand-faint: rgba(255,255,255,.62);
  /* accent-fladens on-blæk — SORT per ADR-0047 §2-tabellen (accent-familien er låst
     til sort on-tekst, AAA 7.0:1 på ren accent #EA7246). Kontekst-invariant som
     --ug-on-brand: --ug-accent har intet dark-override, så sort holder i begge temaer. */
  --ug-on-accent:      #000;
  --ug-text-3xl: 1.875rem;
}

/* ── Token-runde: mørk-mode-overrides for de nye semantiske tokens ─────────── */
.wa-dark {
  --ug-surface-2:    #1b1a19;
  --ug-surface-sunk: #100f0e;
  --ug-border-strong: var(--wa-color-neutral-30);
  --ug-icon-tile:    var(--wa-color-neutral-20);
  --ug-brand-line:   var(--wa-color-brand-30);
  --ug-brand-quiet:  var(--wa-color-lys-brand-10);
  --ug-accent-line:  var(--wa-color-accent-30);
  --ug-accent-quiet: #2a1610;
  --ug-row-hover:    #1b1a19;
  --ug-shadow:     0 1px 2px rgba(0,0,0,.4), 0 6px 20px -10px rgba(0,0,0,.6);
  --ug-shadow-pop: 0 10px 34px -8px rgba(0,0,0,.7), 0 2px 8px rgba(0,0,0,.5);
  --ug-radius-l: 16px;

  /* Token-runde 2 (2026-06-21): the original .wa-dark flipped the *background*
     roles (surface-2/sunk, brand/accent-quiet) but NOT the base --ug-surface or the
     *ink* roles, so any tinted panel (banner, gal-fk-ex, chips) rendered
     dark-bg + dark-text. Complete the theme: the WA neutral scale is fixed
     lightness (neutral-10=dark … neutral-95=light), so dark mode picks the
     light end for ink and a dark hex for the base --ug-surface. Brand/accent text
     move to their light tints so they stay legible on the now-dark panel fills. */
  --ug-surface:       #1f1d1c;                    /* base card/panel-fyld → dark (elevated above surface-2) */
  --ug-text:          var(--wa-color-neutral-90); /* primary ink → light */
  --ug-text-quiet:    var(--wa-color-neutral-70);
  --ug-text-soft:     var(--wa-color-neutral-80);
  --ug-text-faint:    var(--wa-color-neutral-60);
  --ug-border:        var(--wa-color-neutral-30);
  --ug-border-quiet:  var(--wa-color-neutral-20);
  --ug-brand-strong:  var(--wa-color-brand-80);   /* brand text/links on dark → light teal */
  --ug-text-accent:   var(--wa-color-accent-70);  /* accent text → light coral on dark */
  --ug-warning-text:  var(--wa-color-warning-70); /* warning ink → light tint on dark (facit 30↔70-flip) */
  --ug-ink-icon-primary: var(--wa-color-brand-80);

  /* Begrebsgraf node-type hues — dark variants (source doc's dark palette). */
  --ug-graf-skaerm:   #7cc4ff;  --ug-graf-ramme:    #8a96a6;
  --ug-graf-tilstand: #6fd0e6;  --ug-graf-indhold:  #b6c2cf;
  --ug-graf-rel:      #c4a7ff;  --ug-graf-gruppe:   #d6a4ff;
  --ug-graf-element:  #5ad19a;  --ug-graf-slice:    #ffb454;
  --ug-graf-familie:  #ff8fb1;  --ug-graf-token:    #5fd0b0;
  --ug-graf-overlay:  #ffd479;
}

/* body sets color/background from RAW --wa-color tokens (look.css:201), so the
   --ug- indirection above cannot reach it; flip the page background + ink directly. */
.wa-dark body { background: #131211; color: var(--wa-color-neutral-90); }

/* ── LAG 3 — KONTEKST: brand-surface ink-override (ADR-0047 keystone) ───────────
   A brand-flade re-maps the context-neutral ink-role tokens for its whole
   subtree via the cascade. Elements underneath read the ug-text and ug-ink-icon
   roles exactly as on a light background — they NEVER know they sit on brand; the
   flade alone flips the ink to white. This single block lets a brand-flade
   flip ink for its whole subtree, replacing the per-element hardcoded ug-on-brand
   references AS elements adopt the neutral roles (foundation here migrates ONE
   proof-element; the messe-* sweep is tracked as a follow-up).

   Hooks (pick whichever marks a brand-flade):
     .split-brand       — the co-brand login panel (ramme-login.css render-chrome)
     [data-surface="brand"], .on-brand — generic hooks so future kompositionsrelationer/
       kompositionsgrupper can declare a brand-flade without a bespoke class.

   Icon ink on brand (designregel 2026-06-19): primary white, secondary an
   opaque accent-70 coral-tint — never the .4-blend (went muddy on green). */
.split-brand,
[data-surface="brand"],
.on-brand {
  --ug-text:        var(--ug-on-brand);
  --ug-text-quiet:  var(--ug-on-brand-quiet);
  --ug-text-soft:   var(--ug-on-brand-soft);
  --ug-text-faint:  var(--ug-on-brand-faint);
  --ug-ink-icon-primary:   var(--ug-on-brand);   /* white on brand */
  --ug-ink-icon-secondary: var(--ug-icon-accent); /* rene accent-core @ opacity 1 (ADR-0047 §2) — kontekst-invariant */
  --ug-border:      rgba(255, 255, 255, .22);      /* on-brand hairline */
}

/* ── LAG 3 — KONTEKST: per-familie panel-fyld-surface (ADR-0047 §Consequences-1 /
   ADR-0061 §5 / ug3-njo2o) ─────────────────────────────────────────────────────
   A tone-bearing panel marks its flade with [data-surface="<familie>"]; that
   single hook re-maps the context-neutral panel-fyld role --ug-surface to the
   family's --ug-surface-<familie> flade for its whole subtree, exactly as the
   brand hook above re-maps ink. A panel-element's CSS already reads the neutral
   `background: var(--ug-surface)` (ug-noegletal-flise, ug-stat-blok, …) and stays
   tone-agnostic — it NEVER hardcodes a family name; the flade alone tints it,
   and a panel with no [data-surface] keeps the global --ug-surface (fallback
   iboende i cascaden). On-tekst flips to the AAA-calibrated --ug-on-<familie>-surface
   (white/black per familie: success/warning sort, danger/info/plan hvid) so text
   stays legible on the fulde familie-flade.
   This is the panel-fyld counterpart to the brand-surface keystone; status
   families (success/warning/danger/info/plan) get the same treatment as a set. */
[data-surface="success"] {
  --ug-surface:    var(--ug-surface-success);
  --ug-text:       var(--ug-on-success-surface);
}
[data-surface="warning"] {
  --ug-surface:    var(--ug-surface-warning);
  --ug-text:       var(--ug-on-warning-surface);
}
[data-surface="danger"] {
  --ug-surface:    var(--ug-surface-danger);
  --ug-text:       var(--ug-on-danger-surface);
}
[data-surface="info"] {
  --ug-surface:    var(--ug-surface-info);
  --ug-text:       var(--ug-on-info-surface);
}
[data-surface="plan"] {
  --ug-surface:    var(--ug-surface-plan);
  --ug-text:       var(--ug-on-plan-surface);
}

/* ── Duotone icon foundation (sharp-duotone) ──────────────────────────────── */
/* The duotone fill-colors are read from context-neutral ink-role tokens, NOT
   hardcoded to --ug-brand/--ug-accent. A kompositionsrelation/kompositionsgruppe-flade re-maps
   --ug-ink-icon-* for its subtree (ADR-0047 tier-3); the icon CSS stays
   context-free. */
wa-icon {
  --primary-color:     var(--ug-ink-icon-primary);
  --secondary-color:   var(--ug-ink-icon-secondary);
  --secondary-opacity: var(--ug-ink-icon-secondary-opacity);
}
/* ── LAG 3 — KONTEKST: glyph-ink on a loud button fill ──────────────────────
   A duotone glyph on a brand/loud CTA does NOT pick its colours here. Per the
   foundation above, the FLADE re-maps --ug-ink-icon-* for its subtree and the
   glyph stays context-free (ADR-0047 tier-3). The brand CTA buttons
   (ug-confirm-button, ug-magic-link-button, ug-send-nulstilling-button) supply
   the on-fill ink in their own element CSS: white primary + accent secondary on a
   brand-core fill — per docs/arkitektur/farve-token-arkitektur.md (2026-06-15):
   "på brand-fladen: hvid primær + accent sekundær".
   A prior version force-mapped BOTH layers to --wa-color-on-loud here, flattening
   the duotone to solid white. That global component-selector is the anti-pattern
   the foundation comment warns against; the decision belongs on the flade. */

/* ── Gruppe vs. familie forklaringsside (gal-gvf-*) ──────────────────────────
   Alt scopet under .gal-gvf så mockup/visning-CSS ikke lækker. Lokale --ug-gvf-*
   aliasser mapper på de kanoniske --ug-* tokens (graf-farver + semantiske), så
   light/dark flipper automatisk gennem token-systemet. Ingen rå literaler. */
.gal-gvf{
  --ug-gvf-gruppe:var(--ug-graf-gruppe); --ug-gvf-familie:var(--ug-graf-familie);
  --ug-gvf-element:var(--ug-graf-element); --ug-gvf-rel:var(--ug-graf-rel);
  --ug-gvf-ok:var(--ug-success); --ug-gvf-no:var(--ug-danger); --ug-gvf-warn:var(--ug-graf-slice);
  --ug-gvf-panel:var(--ug-surface); --ug-gvf-ink:var(--ug-text);
  --ug-gvf-muted:var(--ug-text-quiet); --ug-gvf-line:var(--ug-border-quiet);
  --ug-gvf-line2:var(--ug-border); --ug-gvf-mono:var(--ug-mono);
}
.gal-gvf .gvf-lead{color:var(--ug-gvf-muted);margin:0 0 12px;max-width:72ch}
.gal-gvf .gvf-legend{display:flex;gap:18px;flex-wrap:wrap;margin:0 0 4px;font-size:0.9rem}
.gal-gvf .gvf-legend span{display:inline-flex;align-items:center;gap:7px}
.gal-gvf .gvf-dot{width:11px;height:11px;border-radius:50%;flex:none;display:inline-block}
.gal-gvf .is-g{color:var(--ug-gvf-gruppe)} .gal-gvf .is-f{color:var(--ug-gvf-familie)}
.gal-gvf .gvf-dot.is-g{background:var(--ug-gvf-gruppe)}
.gal-gvf .gvf-dot.is-f{background:var(--ug-gvf-familie)}
.gal-gvf .gvf-dot.is-e{background:var(--ug-gvf-element)}

/* bordered panel + accent modifiers */
.gal-gvf .gvf-card{background:var(--ug-gvf-panel);border:1px solid var(--ug-gvf-line);
  border-radius:14px;padding:20px 22px;margin:0 0 22px}
.gal-gvf .gvf-card.is-fam{border-color:color-mix(in oklab,var(--ug-gvf-familie) 35%,var(--ug-gvf-line))}
.gal-gvf .gvf-card.is-bad{border-color:color-mix(in oklab,var(--ug-gvf-no) 38%,var(--ug-gvf-line))}
.gal-gvf .gvf-card.is-quiet{border-color:var(--ug-gvf-line2)}
.gal-gvf .gvf-card > h2{margin:0 0 14px;font-size:1.1rem}
.gal-gvf .gvf-sub{color:var(--ug-gvf-muted);font-size:0.92rem;margin:0 0 12px}
.gal-gvf .gvf-key{font-weight:600;color:var(--ug-gvf-ink);font-size:0.92rem;margin:14px 0 0}

/* two- and three-column grids */
.gal-gvf .gvf-vs{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.gal-gvf .gvf-three{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px}
@media (max-width:760px){.gal-gvf .gvf-vs{grid-template-columns:1fr}}
@media (max-width:680px){.gal-gvf .gvf-three{grid-template-columns:1fr}}
.gal-gvf .gvf-mid{align-self:center}

/* concept columns */
.gal-gvf .gvf-col{border:1.5px solid var(--ug-gvf-line2);border-radius:14px;padding:18px;background:var(--ug-gvf-panel)}
.gal-gvf .gvf-col.is-g{border-color:color-mix(in oklab,var(--ug-gvf-gruppe) 55%,var(--ug-gvf-line))}
.gal-gvf .gvf-col.is-f{border-color:color-mix(in oklab,var(--ug-gvf-familie) 55%,var(--ug-gvf-line))}
.gal-gvf .gvf-col.is-ok{border-color:color-mix(in oklab,var(--ug-gvf-ok) 50%,var(--ug-gvf-line))}
.gal-gvf .gvf-col.is-bad{border-color:color-mix(in oklab,var(--ug-gvf-no) 50%,var(--ug-gvf-line))}
.gal-gvf .gvf-col h3{margin:0 0 2px;font-size:1rem;display:flex;align-items:center;gap:8px}
.gal-gvf .gvf-col.is-g h3{color:var(--ug-gvf-gruppe)} .gal-gvf .gvf-col.is-f h3{color:var(--ug-gvf-familie)}
.gal-gvf .gvf-q{font-size:0.85rem;color:var(--ug-gvf-muted);margin:0 0 4px;font-style:italic}
.gal-gvf .gvf-path{font-family:var(--ug-gvf-mono);font-size:0.76rem;color:var(--ug-gvf-muted);margin:0 0 14px;word-break:break-word}

/* viz: composition stack vs family selector */
.gal-gvf .gvf-viz{background:color-mix(in oklab,var(--ug-gvf-ink) 4%,transparent);
  border:1px dashed var(--ug-gvf-line2);border-radius:11px;padding:16px;margin-bottom:12px}
.gal-gvf .gvf-cap{font-size:0.72rem;text-transform:uppercase;letter-spacing:0.05em;color:var(--ug-gvf-muted);margin-bottom:11px;font-weight:600}
.gal-gvf .gvf-stack{display:grid;gap:7px;position:relative;
  border-left:3px solid color-mix(in oklab,var(--ug-gvf-rel) 60%,transparent);padding-left:13px}
.gal-gvf .gvf-rl{position:absolute;left:-6px;top:50%;transform:translate(-100%,-50%) rotate(-90deg);
  transform-origin:center;font-size:0.6rem;color:var(--ug-gvf-rel);font-family:var(--ug-gvf-mono);white-space:nowrap}
.gal-gvf .gvf-mem{border:1px solid color-mix(in oklab,var(--ug-gvf-gruppe) 40%,var(--ug-gvf-line));
  background:color-mix(in oklab,var(--ug-gvf-gruppe) 9%,var(--ug-gvf-panel));border-radius:8px;
  padding:8px 11px;font-size:0.83rem;display:flex;align-items:center;gap:8px}
.gal-gvf .gvf-mem.is-ok{border-color:color-mix(in oklab,var(--ug-gvf-ok) 50%,var(--ug-gvf-line));background:color-mix(in oklab,var(--ug-gvf-ok) 9%,var(--ug-gvf-panel))}
.gal-gvf .gvf-mem.is-bad{border-color:color-mix(in oklab,var(--ug-gvf-no) 55%,var(--ug-gvf-line));background:color-mix(in oklab,var(--ug-gvf-no) 10%,var(--ug-gvf-panel));flex-direction:column;align-items:stretch;gap:7px}
.gal-gvf .gvf-mem .gvf-d,.gal-gvf .gvf-fopt .gvf-d{width:8px;height:8px;border-radius:2px;background:var(--ug-gvf-element);flex:none}
.gal-gvf .gvf-slot{display:flex;align-items:center;gap:8px;font-family:var(--ug-gvf-mono);font-size:0.78rem}
.gal-gvf .gvf-chips{display:flex;gap:5px;flex-wrap:wrap;padding-left:16px}
.gal-gvf .gvf-chips span{font-size:0.66rem;font-family:var(--ug-gvf-mono);border:1px dashed var(--ug-gvf-line2);border-radius:5px;padding:2px 6px;color:var(--ug-gvf-muted);background:var(--ug-gvf-panel)}
.gal-gvf .gvf-gnote{font-size:0.77rem;color:var(--ug-gvf-muted);margin-top:9px;text-align:center}

/* family pick-one selector (kernen) */
.gal-gvf .gvf-fam{display:grid;gap:7px}
.gal-gvf .gvf-fopt{border:1px solid var(--ug-gvf-line2);border-radius:8px;padding:8px 11px;font-size:0.83rem;display:flex;align-items:center;gap:8px;opacity:0.42}
.gal-gvf .gvf-fopt .gvf-d{opacity:0.5}
.gal-gvf .gvf-fopt.is-pick{opacity:1;border-color:color-mix(in oklab,var(--ug-gvf-familie) 60%,var(--ug-gvf-line));background:color-mix(in oklab,var(--ug-gvf-familie) 11%,var(--ug-gvf-panel))}
.gal-gvf .gvf-fopt.is-pick .gvf-d{background:var(--ug-gvf-familie);opacity:1}
.gal-gvf .gvf-pin{margin-left:auto;font-size:0.67rem;font-family:var(--ug-gvf-mono);color:var(--ug-gvf-muted)}
.gal-gvf .gvf-fopt.is-pick .gvf-pin{color:var(--ug-gvf-familie);font-weight:700}

.gal-gvf .gvf-dl{margin:0;display:grid;grid-template-columns:auto 1fr;gap:6px 12px;font-size:0.85rem}
.gal-gvf .gvf-dl dt{color:var(--ug-gvf-muted)} .gal-gvf .gvf-dl dd{margin:0;font-weight:600}

/* concrete login mockups */
.gal-gvf .gvf-mock{border:1px solid var(--ug-gvf-line2);border-radius:12px;padding:13px;background:var(--ug-gvf-panel)}
.gal-gvf .gvf-mh{font-size:0.82rem;font-weight:700;margin:0 0 10px}
.gal-gvf .gvf-field{border:1.5px solid var(--ug-gvf-line2);border-radius:8px;padding:9px 10px;font-size:0.76rem;color:var(--ug-gvf-muted);margin-bottom:8px;display:flex;align-items:center;gap:7px;background:color-mix(in oklab,var(--ug-gvf-ink) 3%,var(--ug-gvf-panel))}
.gal-gvf .gvf-btn{border-radius:8px;padding:8px;text-align:center;font-size:0.76rem;font-weight:600;margin-bottom:7px}
.gal-gvf .gvf-btn.is-primary{background:color-mix(in oklab,var(--ug-gvf-rel) 16%,var(--ug-gvf-panel));color:var(--ug-gvf-rel)}
.gal-gvf .gvf-btn.is-ghost{border:1px solid var(--ug-gvf-line2);color:var(--ug-gvf-ink)}
.gal-gvf .gvf-mock .gvf-btn:last-child,.gal-gvf .gvf-slotgrp .gvf-field:last-child,.gal-gvf .gvf-slotgrp .gvf-btn:last-child{margin-bottom:0}
.gal-gvf .gvf-field.is-slotfam{outline:2px solid var(--ug-gvf-familie);outline-offset:2px}
.gal-gvf .gvf-slotgrp{outline:2px solid var(--ug-gvf-gruppe);outline-offset:3px;border-radius:9px;padding:4px;margin-bottom:8px}
.gal-gvf .gvf-mockcap{font-size:0.71rem;font-family:var(--ug-gvf-mono);color:var(--ug-gvf-muted);text-align:center;margin:8px 0 0}
.gal-gvf .gvf-row{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--ug-gvf-line2);border-radius:8px;margin-bottom:7px;font-size:0.78rem}
.gal-gvf .gvf-row:last-child{margin-bottom:0}
.gal-gvf .gvf-row .gvf-nm{flex:1}
.gal-gvf .gvf-pill{font-size:0.67rem;font-weight:700;padding:2px 9px;border-radius:999px;outline:2px solid var(--ug-gvf-familie);outline-offset:2px}
.gal-gvf .gvf-pill.is-admin{background:color-mix(in oklab,var(--ug-gvf-no) 16%,var(--ug-gvf-panel));color:var(--ug-gvf-no)}
.gal-gvf .gvf-pill.is-red{background:color-mix(in oklab,var(--ug-gvf-rel) 16%,var(--ug-gvf-panel));color:var(--ug-gvf-rel)}
.gal-gvf .gvf-pill.is-mem{background:color-mix(in oklab,var(--ug-gvf-ink) 9%,var(--ug-gvf-panel));color:var(--ug-gvf-muted)}

/* rule / violation cards */
.gal-gvf .gvf-rules{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px}
.gal-gvf .gvf-rules.is-two{grid-template-columns:1fr 1fr}
@media (max-width:820px){.gal-gvf .gvf-rules,.gal-gvf .gvf-rules.is-two{grid-template-columns:1fr}}
.gal-gvf .gvf-rc{border:1.5px solid var(--ug-gvf-line2);border-radius:12px;padding:15px 16px;background:var(--ug-gvf-panel)}
.gal-gvf .gvf-rc.is-ok{border-color:color-mix(in oklab,var(--ug-gvf-ok) 50%,var(--ug-gvf-line))}
.gal-gvf .gvf-rc.is-bad{border-color:color-mix(in oklab,var(--ug-gvf-no) 50%,var(--ug-gvf-line))}
.gal-gvf .gvf-rc h4{margin:0 0 3px;font-size:0.94rem;display:flex;align-items:center;gap:7px}
.gal-gvf .gvf-rc.is-ok h4{color:var(--ug-gvf-ok)} .gal-gvf .gvf-rc.is-bad h4{color:var(--ug-gvf-no)}
.gal-gvf .gvf-why{font-size:0.83rem;color:var(--ug-gvf-muted);margin:0 0 11px}
.gal-gvf .gvf-badge{font-size:0.63rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;padding:2px 7px;border-radius:5px;margin-left:auto;white-space:nowrap}
.gal-gvf .gvf-badge.is-ok{background:color-mix(in oklab,var(--ug-gvf-ok) 18%,transparent);color:var(--ug-gvf-ok)}
.gal-gvf .gvf-badge.is-bad{background:color-mix(in oklab,var(--ug-gvf-no) 20%,transparent);color:var(--ug-gvf-no)}
.gal-gvf .gvf-code{font-family:var(--ug-gvf-mono);font-size:0.73rem;line-height:1.55;background:color-mix(in oklab,var(--ug-gvf-ink) 6%,transparent);border:1px solid var(--ug-gvf-line);border-radius:8px;padding:9px 11px;margin:0 0 10px;white-space:pre-wrap;word-break:break-word}
.gal-gvf .gvf-ann{color:var(--ug-gvf-muted)}
.gal-gvf .gvf-hlbad{color:var(--ug-gvf-no);font-weight:700}
.gal-gvf .gvf-hlok{color:var(--ug-gvf-ok);font-weight:700}
.gal-gvf .gvf-err{font-family:var(--ug-gvf-mono);font-size:0.72rem;line-height:1.5;color:var(--ug-gvf-no);background:color-mix(in oklab,var(--ug-gvf-no) 9%,transparent);border-left:3px solid var(--ug-gvf-no);border-radius:0 6px 6px 0;padding:8px 10px;margin:0}
.gal-gvf .gvf-okline{font-family:var(--ug-gvf-mono);font-size:0.72rem;color:var(--ug-gvf-ok);background:color-mix(in oklab,var(--ug-gvf-ok) 9%,transparent);border-left:3px solid var(--ug-gvf-ok);border-radius:0 6px 6px 0;padding:8px 10px;margin:0}
.gal-gvf .gvf-x{color:var(--ug-gvf-no);font-weight:700} .gal-gvf .gvf-ck{color:var(--ug-gvf-ok);font-weight:700}

/* deciding-test callout */
.gal-gvf .gvf-test{margin:16px 0 0;padding:13px 15px;border:1.5px solid color-mix(in oklab,var(--ug-gvf-familie) 45%,var(--ug-gvf-line));border-radius:11px;background:color-mix(in oklab,var(--ug-gvf-familie) 7%,var(--ug-gvf-panel))}
.gal-gvf .gvf-test p{margin:0;font-size:0.88rem;line-height:1.6}
.gal-gvf .gvf-test .gvf-th{font-weight:700;font-size:0.93rem;margin:0 0 7px}

/* side-by-side table */
.gal-gvf table{width:100%;border-collapse:collapse;font-size:0.89rem}
.gal-gvf th,.gal-gvf td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--ug-gvf-line);vertical-align:top}
.gal-gvf thead th{font-size:0.76rem;text-transform:uppercase;letter-spacing:0.04em;color:var(--ug-gvf-muted)}
.gal-gvf thead th.is-g{color:var(--ug-gvf-gruppe)} .gal-gvf thead th.is-f{color:var(--ug-gvf-familie)}
.gal-gvf td.gvf-ax{color:var(--ug-gvf-muted);font-size:0.83rem;width:24%}
.gal-gvf tbody tr:last-child td{border-bottom:none}
.gal-gvf ul.gvf-flat{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.gal-gvf ul.gvf-flat li{display:flex;gap:10px;align-items:flex-start;font-size:0.92rem}
.gal-gvf ul.gvf-flat li .gvf-mk{flex:none;font-weight:700;width:18px;text-align:center}

/* ── Slice forklaringsside (gal-slc-*) ──────────────────────────────────────
   Alt scopet under .gal-slc så mockup/visning-CSS ikke lækker (egne slc-*-klasser,
   genbruger IKKE gvf-*). Lokale --ug-slc-* aliasser mapper på de kanoniske --ug-*
   tokens (graf-farver + semantiske), så light/dark flipper automatisk gennem token-
   systemet. Ingen rå literaler. Farve-roller: slice=graf-slice (amber) · data=graf-
   skaerm (blå, = kildens --data) · viewer=graf-familie (magenta, = kildens --view) ·
   grundet=success · forslag=warning · host=info. */
.gal-slc{
  --ug-slc-slice:var(--ug-graf-slice); --ug-slc-data:var(--ug-graf-skaerm);
  --ug-slc-view:var(--ug-graf-familie); --ug-slc-host:var(--ug-info);
  --ug-slc-ok:var(--ug-success); --ug-slc-no:var(--ug-danger); --ug-slc-warn:var(--ug-warning);
  --ug-slc-panel:var(--ug-surface); --ug-slc-ink:var(--ug-text);
  --ug-slc-muted:var(--ug-text-quiet); --ug-slc-line:var(--ug-border-quiet);
  --ug-slc-line2:var(--ug-border); --ug-slc-mono:var(--ug-mono);
}
.gal-slc .slc-lead{color:var(--ug-slc-muted);margin:0 0 12px;max-width:78ch}
.gal-slc .slc-lead .slc-is-s{color:var(--ug-slc-slice)}
.gal-slc .slc-is-data{color:var(--ug-slc-data)} .gal-slc .slc-is-view{color:var(--ug-slc-view)}
.gal-slc .slc-x{color:var(--ug-slc-no);font-weight:700} .gal-slc .slc-ck{color:var(--ug-slc-ok);font-weight:700}

/* GRUNDET / FORSLAG legend + inline tags */
.gal-slc .slc-legend{display:flex;gap:18px;flex-wrap:wrap;margin:0 0 8px;font-size:0.9rem}
.gal-slc .slc-legend span{display:inline-flex;align-items:center;gap:7px}
.gal-slc .slc-tag{font-style:normal;font-size:0.63rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;padding:2px 7px;border-radius:5px;white-space:nowrap;flex:none}
.gal-slc .slc-tag.slc-is-grundet{background:color-mix(in oklab,var(--ug-slc-ok) 18%,transparent);color:var(--ug-slc-ok);border:1px solid color-mix(in oklab,var(--ug-slc-ok) 45%,transparent)}
.gal-slc .slc-tag.slc-is-forslag{background:color-mix(in oklab,var(--ug-slc-warn) 24%,transparent);color:var(--ug-slc-ink);border:1px solid color-mix(in oklab,var(--ug-slc-warn) 60%,var(--ug-slc-line))}

/* cards */
.gal-slc .slc-card{background:var(--ug-slc-panel);border:1px solid var(--ug-slc-line);
  border-radius:14px;padding:20px 22px;margin:0 0 22px}
.gal-slc .slc-card.is-quiet{border-color:var(--ug-slc-line2)}
.gal-slc .slc-card.is-bad{border-color:color-mix(in oklab,var(--ug-slc-no) 35%,var(--ug-slc-line))}
.gal-slc .slc-card > h2{margin:0 0 12px;font-size:1.1rem}
.gal-slc .slc-card > h2::before{content:"";display:inline-block;width:4px;height:0.95em;margin-right:9px;vertical-align:-0.08em;border-radius:2px;background:var(--ug-slc-slice)}
.gal-slc .slc-sub{color:var(--ug-slc-muted);font-size:0.92rem;margin:0 0 12px}

/* cite chip */
.gal-slc .slc-cite{font-family:var(--ug-slc-mono);font-size:0.68rem;color:var(--ug-slc-host);background:color-mix(in oklab,var(--ug-slc-host) 12%,transparent);padding:1px 6px;border-radius:5px;white-space:nowrap}

/* definition block */
.gal-slc .slc-def{border-left:3px solid var(--ug-slc-slice);padding:6px 0 6px 15px;margin:6px 0 14px;font-size:0.95rem}
.gal-slc .slc-def b{color:var(--ug-slc-slice)}

/* flat note + lists */
.gal-slc .slc-note{background:color-mix(in oklab,var(--ug-slc-no) 8%,transparent);border:1px solid color-mix(in oklab,var(--ug-slc-no) 30%,var(--ug-slc-line));border-radius:11px;padding:12px 15px;font-size:0.9rem;margin:12px 0}
.gal-slc ul.slc-flat{list-style:none;margin:8px 0;padding:0;display:grid;gap:9px}
.gal-slc ul.slc-flat li{display:flex;gap:10px;align-items:flex-start;font-size:0.9rem;line-height:1.55}
.gal-slc ul.slc-flat li .slc-mk{flex:none;font-weight:700;width:16px;text-align:center}

/* trigger → slice → presentation flow */
.gal-slc .slc-flow{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:12px 0;font-family:var(--ug-slc-mono);font-size:0.78rem}
.gal-slc .slc-node{border:1.5px solid var(--ug-slc-line2);border-radius:9px;padding:9px 12px;background:var(--ug-slc-panel);text-align:center}
.gal-slc .slc-node small{color:var(--ug-slc-muted);font-size:0.92em}
.gal-slc .slc-node.slc-n-trig{border-color:color-mix(in oklab,var(--ug-slc-host) 55%,var(--ug-slc-line))}
.gal-slc .slc-node.slc-n-src{border-color:color-mix(in oklab,var(--ug-slc-slice) 55%,var(--ug-slc-line))}
.gal-slc .slc-node.slc-n-pres{border:1.5px dashed var(--ug-slc-slice);background:color-mix(in oklab,var(--ug-slc-slice) 9%,var(--ug-slc-panel));color:var(--ug-slc-slice)}
.gal-slc .slc-ar{color:var(--ug-slc-muted);font-size:1.05rem}

/* 2×3 modi axis grid */
.gal-slc .slc-axis{display:grid;grid-template-columns:64px 1fr 1fr 1fr;gap:1px;background:var(--ug-slc-line2);border:1px solid var(--ug-slc-line2);border-radius:10px;overflow:hidden;margin:12px 0;font-size:0.82rem}
.gal-slc .slc-axis > div{background:var(--ug-slc-panel);padding:9px 11px}
.gal-slc .slc-axis .slc-h{font-weight:700;color:var(--ug-slc-muted);font-size:0.7rem;text-transform:uppercase;letter-spacing:0.03em}
.gal-slc .slc-axis .slc-on{background:color-mix(in oklab,var(--ug-slc-slice) 11%,var(--ug-slc-panel));color:var(--ug-slc-slice);font-weight:600}
.gal-slc .slc-axis .slc-on.slc-deleg{background:color-mix(in oklab,var(--ug-slc-warn) 16%,var(--ug-slc-panel));color:var(--ug-slc-ink)}
@media (max-width:640px){.gal-slc .slc-axis{grid-template-columns:54px 1fr 1fr 1fr;font-size:0.72rem}.gal-slc .slc-axis > div{padding:7px 6px}}

/* modi mockup grid */
.gal-slc .slc-modi{display:grid;grid-template-columns:1fr 1fr 1fr;gap:14px;margin-top:14px}
@media (max-width:920px){.gal-slc .slc-modi{grid-template-columns:1fr 1fr}}
@media (max-width:620px){.gal-slc .slc-modi{grid-template-columns:1fr}}
.gal-slc .slc-m{border:1px solid var(--ug-slc-line2);border-radius:13px;padding:0;overflow:hidden;background:var(--ug-slc-panel);display:flex;flex-direction:column}
.gal-slc .slc-m.slc-m-deleg{border-color:color-mix(in oklab,var(--ug-slc-warn) 55%,var(--ug-slc-line))}
.gal-slc .slc-mhd{padding:11px 14px;border-bottom:1px solid var(--ug-slc-line);display:flex;flex-direction:column;gap:2px}
.gal-slc .slc-mhd b{font-size:0.98rem;color:var(--ug-slc-slice)}
.gal-slc .slc-m.slc-m-deleg .slc-mhd b{color:color-mix(in oklab,var(--ug-slc-warn) 70%,var(--ug-slc-ink))}
.gal-slc .slc-cell{font-size:0.72rem;color:var(--ug-slc-muted)}

/* mockup host chrome */
.gal-slc .slc-host{border:1.5px solid color-mix(in oklab,var(--ug-slc-host) 60%,var(--ug-slc-line));border-radius:0;background:color-mix(in oklab,var(--ug-slc-ink) 3%,var(--ug-slc-panel));margin:13px 14px;border-radius:10px;position:relative;overflow:hidden}
.gal-slc .slc-host .slc-bar{background:color-mix(in oklab,var(--ug-slc-host) 13%,var(--ug-slc-panel));color:var(--ug-slc-host);font-size:0.66rem;font-weight:700;padding:5px 10px;border-bottom:1px solid color-mix(in oklab,var(--ug-slc-host) 45%,var(--ug-slc-line))}
.gal-slc .slc-host .slc-content{padding:11px;font-size:0.74rem;color:var(--ug-slc-muted);line-height:1.7}
.gal-slc .slc-host.slc-h-data{border-color:color-mix(in oklab,var(--ug-slc-data) 60%,var(--ug-slc-line))}
.gal-slc .slc-host.slc-h-data .slc-bar{background:color-mix(in oklab,var(--ug-slc-data) 13%,var(--ug-slc-panel));color:var(--ug-slc-data);border-bottom-color:color-mix(in oklab,var(--ug-slc-data) 45%,var(--ug-slc-line))}
.gal-slc .slc-host.slc-h-view{border-color:color-mix(in oklab,var(--ug-slc-view) 60%,var(--ug-slc-line))}
.gal-slc .slc-host.slc-h-view .slc-bar{background:color-mix(in oklab,var(--ug-slc-view) 13%,var(--ug-slc-panel));color:var(--ug-slc-view);border-bottom-color:color-mix(in oklab,var(--ug-slc-view) 45%,var(--ug-slc-line))}
.gal-slc .slc-trig{display:inline-block;border:1.5px solid color-mix(in oklab,var(--ug-slc-host) 60%,var(--ug-slc-line));color:var(--ug-slc-host);border-radius:7px;padding:4px 9px;font-size:0.72rem;font-weight:600;margin:5px 0;background:var(--ug-slc-panel)}
.gal-slc .slc-mu{color:var(--ug-slc-muted);opacity:0.8}

/* slice-flader (drawer/dialog/popover/inline) */
.gal-slc .slc-surf{background:color-mix(in oklab,var(--ug-slc-slice) 11%,var(--ug-slc-panel));border:1.5px solid var(--ug-slc-slice);border-radius:9px;padding:8px 9px;font-size:0.7rem;color:var(--ug-slc-ink);line-height:1.7}
.gal-slc .slc-surf.slc-inline{border-style:dashed;margin:6px 0 0}
.gal-slc .slc-surf.slc-drawer{box-shadow:-4px 0 10px color-mix(in oklab,var(--ug-slc-ink) 10%,transparent)}
.gal-slc .slc-surf.slc-dialog{box-shadow:0 6px 18px color-mix(in oklab,var(--ug-slc-ink) 18%,transparent)}
.gal-slc .slc-surf.slc-popover{box-shadow:0 4px 12px color-mix(in oklab,var(--ug-slc-ink) 14%,transparent)}
.gal-slc .slc-slab{color:var(--ug-slc-slice);font-weight:700;font-size:0.62rem;text-transform:uppercase;letter-spacing:0.04em;display:block;margin-bottom:4px}
.gal-slc .slc-mcap{font-size:0.78rem;color:var(--ug-slc-muted);line-height:1.55;padding:0 14px 13px;margin:0}
.gal-slc .slc-mcap b{color:var(--ug-slc-ink)}

/* §6 field grid */
.gal-slc .slc-dl{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:0 0 14px}
@media (max-width:680px){.gal-slc .slc-dl{grid-template-columns:1fr}}
.gal-slc .slc-field{border:1px solid var(--ug-slc-line2);border-radius:11px;padding:13px 15px;background:var(--ug-slc-panel)}
.gal-slc .slc-field.slc-is-grundet-b{border-color:color-mix(in oklab,var(--ug-slc-ok) 40%,var(--ug-slc-line))}
.gal-slc .slc-field h3{margin:0 0 5px;font-size:0.92rem;display:flex;align-items:center;gap:8px}
.gal-slc .slc-field p{margin:0;font-size:0.84rem;color:var(--ug-slc-muted)}

/* toml-style code blocks */
.gal-slc .slc-code{font-family:var(--ug-slc-mono);font-size:0.73rem;line-height:1.6;background:color-mix(in oklab,var(--ug-slc-ink) 6%,transparent);border:1px solid var(--ug-slc-line);border-radius:8px;padding:10px 12px;margin:0 0 12px;white-space:pre-wrap;word-break:break-word}
.gal-slc .slc-ann{color:var(--ug-slc-muted)}
.gal-slc .slc-hlok{color:var(--ug-slc-ok);font-weight:700}
.gal-slc .slc-hlbad{color:var(--ug-slc-no);font-weight:700}

/* scope: mantra + data/viewer columns */
.gal-slc .slc-mantra{background:color-mix(in oklab,var(--ug-slc-slice) 8%,var(--ug-slc-panel));border:1px solid color-mix(in oklab,var(--ug-slc-slice) 45%,var(--ug-slc-line));border-radius:12px;padding:13px 16px;margin:12px 0 18px;text-align:center;font-size:0.95rem}
.gal-slc .slc-mantra small{display:block;font-size:0.72rem;color:var(--ug-slc-muted);margin-top:6px}
.gal-slc .slc-vs{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media (max-width:800px){.gal-slc .slc-vs{grid-template-columns:1fr}}
.gal-slc .slc-col{border:1.5px solid var(--ug-slc-line2);border-radius:14px;padding:16px 18px;background:var(--ug-slc-panel)}
.gal-slc .slc-col.slc-c-data{border-color:color-mix(in oklab,var(--ug-slc-data) 55%,var(--ug-slc-line))}
.gal-slc .slc-col.slc-c-view{border-color:color-mix(in oklab,var(--ug-slc-view) 55%,var(--ug-slc-line))}
.gal-slc .slc-col.slc-c-ok{border-color:color-mix(in oklab,var(--ug-slc-ok) 50%,var(--ug-slc-line))}
.gal-slc .slc-col.slc-c-bad{border-color:color-mix(in oklab,var(--ug-slc-no) 50%,var(--ug-slc-line))}
.gal-slc .slc-col > h3{margin:0 0 8px;font-size:1rem}
.gal-slc .slc-col.slc-c-data > h3{color:var(--ug-slc-data)} .gal-slc .slc-col.slc-c-view > h3{color:var(--ug-slc-view)}
.gal-slc .slc-col > .slc-q{font-size:0.85rem;color:var(--ug-slc-muted);margin:0 0 12px}
.gal-slc .slc-split{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media (max-width:480px){.gal-slc .slc-split{grid-template-columns:1fr}}
.gal-slc .slc-split .slc-host{margin:0}
.gal-slc .slc-keep{color:var(--ug-slc-ok);font-weight:600}
.gal-slc .slc-drop{color:var(--ug-slc-muted);text-decoration:line-through;opacity:0.65}

/* Frys-vieweren-testen callout + table */
.gal-slc .slc-frys{margin:18px 0 0;padding:16px 18px;border:1px solid color-mix(in oklab,var(--ug-slc-ok) 45%,var(--ug-slc-line));border-radius:14px;background:color-mix(in oklab,var(--ug-slc-ok) 7%,var(--ug-slc-panel))}
.gal-slc .slc-frys h3{margin:0 0 6px;font-size:1rem;color:var(--ug-slc-ok)}
.gal-slc .slc-frys-q{font-size:0.95rem;font-weight:700;margin:0 0 8px}
.gal-slc table{width:100%;border-collapse:collapse;font-size:0.85rem;margin:8px 0}
.gal-slc th,.gal-slc td{text-align:left;padding:9px 11px;border-bottom:1px solid var(--ug-slc-line);vertical-align:top}
/* Narrow screens: the 4-column Frys-table keeps a readable width and scrolls
   horizontally inside its .gal-tabel-rul wrapper instead of overflowing the
   viewport; the table itself stays a table. */
@media (max-width:560px){
  .gal-slc .slc-frys table{min-width:520px;table-layout:fixed}
}
.gal-slc thead th{font-size:0.7rem;text-transform:uppercase;letter-spacing:0.04em;color:var(--ug-slc-muted)}
.gal-slc tbody tr:last-child td{border-bottom:none}
.gal-slc .slc-badge{font-size:0.63rem;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;padding:2px 7px;border-radius:5px;white-space:nowrap}
.gal-slc .slc-badge.slc-b-data{background:color-mix(in oklab,var(--ug-slc-data) 18%,transparent);color:var(--ug-slc-data)}
.gal-slc .slc-badge.slc-b-view{background:color-mix(in oklab,var(--ug-slc-view) 20%,transparent);color:var(--ug-slc-view)}

.gal-slc code{font-family:var(--ug-slc-mono)}

/* ════════════════════════════════════════════════════════════════════════
   Sammenlign elementer (sammenlign.js) — valg-toggle + sticky kurv + panel.
   Chrome-farver på --ug-* / --wa-color-* så panelet arver galleriets lys +
   .wa-dark-temaer; preview-fladen er bevidst hardkodet hvid (som kortet, der
   ikke tema-inverterer). Preview-klonen spejler kort-strukturen: container-type
   på .gal-cmp-prev-inst (= .gal-viewport-body) og den hvide flade på den
   omsluttende .gal-cmp-prev (= .gal-viewport). Panelets rækker deler ét
   grid-spor-sæt (labelw + N×colw) så previews og token-matrix flugter
   kolonne-for-kolonne.
   ════════════════════════════════════════════════════════════════════════ */

/* ── ⊕-toggle i kort-summary (ligger før badges, så margin-left:auto ikke rammer den) ── */
.gal-cmp-toggle {
  appearance: none; cursor: pointer; margin: 0; padding: 0; flex: none;
  inline-size: 1.45rem; block-size: 1.45rem;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
  border: 1.5px solid var(--ug-border-quiet, var(--wa-color-neutral-70));
  border-radius: 50%; background: var(--ug-surface, #fff);
  color: var(--ug-text-quiet, var(--wa-color-neutral-50));
  font-size: 0.95rem; font-weight: 700;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.gal-cmp-toggle:hover { border-color: var(--ug-brand, #00483e); color: var(--ug-brand, #00483e); }
.gal-cmp-toggle--on { background: var(--ug-brand, #00483e); border-color: var(--ug-brand, #00483e); color: #fff; }
.gal-cmp-toggle:focus-visible { outline: 2px solid var(--ug-brand, #00483e); outline-offset: 2px; }

/* ── Sticky kurv-bar ── */
.gal-cmp-tray {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 80;
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.6rem;
  padding: 0.6rem 1rem;
  background: var(--ug-surface, #fff);
  border-top: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-85));
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.12);
}
.gal-cmp-tray[hidden] { display: none; } /* author display:flex would otherwise beat [hidden] */
.gal-cmp-tray-titel { font-size: 0.9rem; }
.gal-cmp-tray-spacer { flex: 1 1 auto; }
.gal-cmp-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.gal-cmp-chip {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.15rem 0.2rem 0.15rem 0.55rem;
  border: var(--wa-border-width-s, 1px) solid var(--ug-brand-line, var(--ug-brand, #00483e));
  border-radius: var(--ug-radius-pill, 999px);
  font-family: var(--ug-mono, monospace); font-size: 0.78rem;
  background: var(--ug-surface, #fff);
}
.gal-cmp-chip code { font-weight: 700; }
.gal-cmp-chip button {
  appearance: none; border: 0; background: none; cursor: pointer; line-height: 1;
  padding: 0.1rem 0.3rem; border-radius: 50%; color: var(--ug-text-quiet, var(--wa-color-neutral-50));
  font-size: 0.85rem;
}
.gal-cmp-chip button:hover { background: var(--ug-surface-sunk, var(--wa-color-neutral-90)); color: var(--ug-text, inherit); }
.gal-cmp-hint { font-size: 0.78rem; color: var(--wa-color-danger-40); font-weight: 600; }
.gal-cmp-hint[hidden] { display: none; }

/* ── Panel (wa-dialog) ── */
.gal-cmp-dialog { --width: 96vw; }
.gal-cmp-controls {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.9rem;
  padding-bottom: 0.7rem; margin-bottom: 0.5rem;
  border-bottom: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-85));
}
.gal-cmp-bredde { display: inline-flex; align-items: center; gap: 0.3rem; }
.gal-cmp-bredde-pil {
  appearance: none; cursor: pointer;
  border: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-85));
  background: var(--ug-surface, #fff); color: var(--ug-text, inherit);
  padding: 0.25rem 0.6rem; font-size: 0.78rem; border-radius: var(--ug-radius-s, 0.3rem);
}
.gal-cmp-bredde-pil.aktiv { background: var(--ug-brand, #00483e); color: #fff; border-color: var(--ug-brand, #00483e); }

/* ── Aligned column grid: én grid-skabelon delt af alle rækker ── */
.gal-cmp-scroll { overflow-x: auto; overflow-y: visible; }
.gal-cmp-rows { width: max-content; min-width: 100%; }
.gal-cmp-row {
  display: grid;
  grid-template-columns: var(--cmp-labelw, 168px) repeat(var(--cmp-n, 2), var(--cmp-w, 390px));
  border-bottom: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90));
}
.gal-cmp-lbl {
  position: sticky; left: 0; z-index: 2;
  background: var(--ug-surface, #fff);
  padding: 0.6rem 0.75rem; font-size: 0.74rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em; color: var(--ug-text-quiet, var(--wa-color-neutral-50));
  border-right: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-85));
}
.gal-cmp-tk { text-transform: none; letter-spacing: 0; }
.gal-cmp-tk code { font-family: var(--ug-mono, monospace); font-weight: 700; font-size: 0.76rem; color: var(--ug-text, inherit); }
.gal-cmp-colhead { padding: 0.6rem 0.75rem; border-left: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90)); }
.gal-cmp-colhead code { font-weight: 700; font-size: 0.82rem; }
.gal-cmp-colbadges { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-top: 0.35rem; }
.gal-cmp-row--head, .gal-cmp-row--matrixhead { background: var(--ug-surface-sunk, var(--wa-color-neutral-95)); }
.gal-cmp-row--head .gal-cmp-lbl, .gal-cmp-row--matrixhead .gal-cmp-lbl { background: var(--ug-surface-sunk, var(--wa-color-neutral-95)); }

/* Preview-celler: klonet element ved valgt container-bredde på hvid flade (= kortet) */
.gal-cmp-prev { border-left: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90)); background: #fff; overflow: hidden; }
.gal-cmp-prev-inst { container-type: inline-size; padding: 1.25rem 1rem; box-sizing: border-box; }

/* Token-matrix-celler */
.gal-cmp-tv {
  padding: 0.5rem 0.75rem; border-left: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90));
  font-family: var(--ug-mono, monospace); font-size: 0.76rem; color: var(--ug-text, inherit);
  word-break: break-all; align-self: center;
}
.gal-cmp-none { color: var(--wa-color-neutral-50); font-style: italic; }
.gal-cmp-uloest { color: var(--wa-color-danger-40); font-weight: 700; }
.gal-cmp-diff { background: color-mix(in srgb, var(--wa-color-danger-50) 12%, transparent); }
.gal-cmp-trow:hover { background: color-mix(in srgb, var(--ug-brand, #00483e) 5%, transparent); }

/* "Kun forskelle": skjul rækker der er ens på tværs af alle kolonner */
.gal-cmp-body--kunforskelle .gal-cmp-trow[data-ens="true"] { display: none; }

/* Note når "kun forskelle" skjuler ALLE rækker (elementerne er ens på tokens) */
.gal-cmp-emptynote { position: sticky; left: 0; padding: 0.9rem 0.75rem; font-size: 0.85rem; color: var(--ug-text-quiet, var(--wa-color-neutral-50)); font-style: italic; }
.gal-cmp-emptynote[hidden] { display: none; }

/* Kilde-foldud (skjult indtil "Vis kilde") */
.gal-cmp-row--kilde { display: none; }
.gal-cmp-body--kilde .gal-cmp-row--kilde { display: grid; }
.gal-cmp-kilde-col { border-left: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90)); padding: 0.5rem 0.75rem; min-width: 0; }
.gal-cmp-kilde-col h4 { margin: 0.4rem 0 0.25rem; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.03em; color: var(--ug-text-quiet, var(--wa-color-neutral-50)); }
.gal-cmp-kilde-col .gal-code { margin: 0; max-height: 320px; overflow: auto; font-size: 0.72rem; }

/* ── invitations-oversigtens række (ug3-trxlr) · flank-flex på de REELLE
   flex-børn ──────────────────────────────────────────────────────────────
   Rækkens indholds-split stod som et block-barn på sin egen linje
   (status-flisen stod OVER teksten, Johannes' design-feedback 2026-07-11
   pkt. 1). Giv splittet flank-content-flexen direkte, scoped via composerens
   data-ug-id-identitet (aldrig klasser). Status-flisen er flex:none i sit
   atom, så flisen står på linje, vertikalt centreret (flankens
   align-items: center). */
[data-ug-id="grp-invitation-oversigt-raekke"] > [data-ug-id="grp-invitation-indhold"] {
  flex: 1;
  min-inline-size: 0;
}
/* ── RTE-editor chrome (ug3-qff6r.1.2.6) ─────────────────────────────────────
   Styles the Tiptap richtext editor that rte.js builds IN PLACE of a
   data-ug-rte="ja" <wa-textarea>: a framed surface with a toolbar (Afsnitsformat
   dropdown + B/I/U/S/</> + lists + Link + Ryd) and a live character count. The
   DOM is runtime-built by the DRIVER (cmd/gallery/static/rte.js), not by the
   ug-langtekst-input element, so this driver-chrome lives in look.css — NOT in
   element-CSS — and the C7/C8 element-CSS constraints (tag/::part-only,
   token-only) do not gate it. Token-only regardless; dark mode falls out of the
   --ug-* tokens (each is redefined in the dark :root). */
.ug-rte-wrap {
  border: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90));
  border-radius: var(--ug-radius, 0.5rem);
  background: var(--ug-surface, #ffffff);
  overflow: hidden;
}
/* Focus-frame: the editable surface's own outline is removed (below), so the
   WRAP shows focus for the whole control. */
.ug-rte-wrap:focus-within {
  border-color: var(--ug-border-strong, var(--wa-color-neutral-70));
}
.ug-rte-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ug-space-3xs, 0.125rem);
  padding: var(--ug-space-2xs, 0.4375rem) var(--ug-space-xs, 0.5625rem);
  border-bottom: var(--wa-border-width-s, 1px) solid var(--ug-border-quiet, var(--wa-color-neutral-90));
}
.ug-rte-sep {
  align-self: stretch;
  inline-size: var(--wa-border-width-s, 1px);
  min-block-size: 1.25rem;
  margin-inline: var(--ug-space-3xs, 0.125rem);
  background: var(--ug-border-quiet, var(--wa-color-neutral-90));
}
/* Active mark/node: brand-tint the button so the toolbar reads the caret's live
   formatting state, not just the available actions. wa-button styles its interior
   via ::part(base); no WA utility covers a per-button active tint, so ::part is
   the correct tool here (repo Don't: ::part is acceptable when no utility fits). */
.ug-rte-btn[data-active]::part(base) {
  background: var(--ug-brand-quiet, var(--wa-color-lys-brand-95));
  color: var(--ug-brand, #00483e);
}
.ug-rte-surface {
  padding: var(--ug-space-s, 0.75rem) var(--ug-space-m, 1rem);
}
/* .ProseMirror is Tiptap's contenteditable child of the mount surface. Drop its
   default focus outline (the wrap shows focus) and give it a clickable min height
   even when empty. */
.ug-rte-surface .ProseMirror {
  outline: none;
  min-block-size: 6rem;
}
.ug-rte-count {
  display: flex;
  justify-content: flex-end;
  padding: var(--ug-space-3xs, 0.125rem) var(--ug-space-m, 1rem) var(--ug-space-2xs, 0.4375rem);
  font-size: var(--ug-text-xs, 0.6875rem);
  color: var(--ug-text-quiet, var(--wa-color-neutral-50));
  font-variant-numeric: tabular-nums;
}
/* Over the max-length: the driver toggles [data-over] on the count. */
.ug-rte-count[data-over] {
  color: var(--ug-danger, #b6000e);
}

/* ── Form svar-beholder (ADR-0044/M6, ug3-mqbwn) ──────────────────────────────
   The composer closes a [handling] svar="under" <form> with an empty
   .ug-form-svar container and points hx-target at it, so the endpoint's fragment
   reply lands inline UNDER the submit button instead of navigating.

   While empty it must cost nothing: a form-relation arranges its members in a
   wa-stack (display:flex + gap), where an ordinary empty div is still a flex item
   and would add one full gap below the button. display:contents generates no box
   at all, so the layout is byte-for-byte the pre-swap layout. The rule stops
   matching the moment htmx swaps the reply in, leaving an ordinary block — which
   is also what makes the aria-live region announce (a display:contents element is
   an unreliable live region). */
.ug-form-svar:empty {
  display: contents;
}
/* The confirmation line itself: the <p class="ug-kontakt-tak"> success fragment.
   Quiet confirmation, not a callout — it sits directly under the control that
   caused it.

   DELIBERATELY UNSCOPED (Johannes, 2026-07-31). Four handlers emit this class —
   kontaktSubmit's «Tak — din besked er sendt.» in the svar-container, plus
   kontakt-modtager-gemt (handlers.go) and the two intro confirmations (intro.go)
   on their own targets. They are the same kind of message, so they get the same
   look; the rule was briefly scoped to .ug-form-svar only to keep the styling
   decision out of a bug-fix, and Johannes has since made it explicitly. A future
   fragment that should NOT look like a quiet confirmation needs its own class,
   not a narrower selector here. */
.ug-kontakt-tak {
  margin: 0;
  color: var(--ug-text-quiet);
  font-size: var(--ug-text-s);
}

/* ── Liste-inaktiv placeholder (ug3-t0lj1) ────────────────────────────────────
   The gallery LIST pages (/kompositionsrelationer + /kompositionsgrupper)
   compose every registered relation/group with no host, so a DATA-bound
   handling.rute can never resolve there. In liste-mode the composer emits the
   arrangement as a neutral, non-submittable wrapper (or an hx-less dispatch
   element) carrying data-ug-liste-inaktiv instead of a knækket marker. Dim it
   so "inactive by construction" is visible, and cut pointer events so the dead
   controls do not read as clickable (belt-and-braces with the native `inert`
   attribute the composer emits alongside, which also removes the controls from
   the tab order + accessibility tree). The attribute IS the scope: cockpits can
   never emit it (the composer's liste-mode is structurally unreachable from the
   live entry points), so the rule is dead outside the two list pages. */
[data-ug-liste-inaktiv] {
  opacity: 0.55;
  pointer-events: none;
}
/* The visible WHY — dimming alone cannot tell «inactive by construction» apart
   from «someone forgot a binding», and the composer's title-attribute sits on
   an `inert` element (hit-test lands on <body>, AT-tree pruned), so it can
   never surface as a tooltip. The caption therefore lives OUTSIDE the inert
   subtree, generated on the gallery preview container. Generated content is
   exposed in the accessibility tree, so AT users get the explanation too. */
.gal-viewport-body:has([data-ug-liste-inaktiv])::after {
  content: "Inaktiv på listesiden: DATA-bundet handling har ingen vært her — ruten bindes i et live cockpit.";
  display: block;
  margin-top: var(--ug-space-s, 8px);
  font-size: var(--ug-text-s, 12px);
  color: var(--ug-text-quiet, #6b7280);
}
