/* =============================================================================
   BR-BygAI — designsystem, version 1.1
   =============================================================================
   Følger BRANDGUIDE.md 1.1. Ændringerne fra 1.0 er besluttet af Benjamin
   6. august 2026 og skrevet ind i guiden med dato og årsag:

     * Radius hævet fra 4 px til en skala (6 / 8 / 12 px). 4 px på alle flader
       gav et fladt, dateret udtryk uden at tilføje autoritet.
     * Diskret elevation tillades på FLYDENDE lag — komposer-bjælken og
       popovers. Rammer er stadig standard på alt, der ligger i fladen.
     * Pill-form er fortsat forbudt. Det er ikke en æstetisk detalje: den
       rektangulære form er det, der får fladen til at læse som et dokument
       frem for en beskedapp, og vi gengiver lovtekst.

   Uændret fra 1.0, og må ikke ændres uden at guiden ændres:
     * Paletten. Fordeling ca. 70 % Papir/Kalk, 20 % Blæk, 8 % Paragrafgrøn,
       2 % Signalgul.
     * Signalgul ALDRIG som tekstfarve på lys baggrund.
     * Lovtekst har paragrafgrøn venstrekant på Tavle; vejledning har
       signalgul. Systemets vigtigste visuelle regel.
     * Lovtekst højst 72 tegn bred.
     * 8 px grundenhed.
   ========================================================================== */

:root {
  /* ---- Kernefarver ---- */
  --paragrafgroen: #1f5c4a;
  --groen-dyb: #153f33;
  --signalgul: #eba53c;
  --blaek: #14181c;
  --papir: #f4f2ee;

  /* ---- Understøttende ---- */
  --kalk: #ffffff;
  --tavle: #fbfaf8;
  --kant: #e2ded6;
  --beton: #8a8478;

  /* Tonede flader, afledt af paletten. Bruges til aktive og valgte
     tilstande, hvor en ren farveflade ville blive for dominerende i
     70/20/8/2-fordelingen. */
  --groen-tone: #eaf1ee;
  --groen-tone-kant: #c5d8d1;
  --gul-tone: #fdf4e6;
  /* Tonet flade til det destruktive. Gul er reserveret til vejledning. */
  --obs-tone: #fdeeea;

  /* ---------------------------------------------------------------------
     Beton til TEKST.

     Brandguiden udpeger Beton (#8A8478) til sekundær tekst. Målt kontrast:
        Beton / Papir 3,32:1 · Kalk 3,72:1 · Tavle 3,56:1
     Alle under WCAG AA's 4,5:1. Guiden nævner ikke Beton i kontrast-afsnittet,
     så konflikten er ikke bevidst. CLAUDE.md afsnit 6.3 sætter AA som mål, og
     kontrast er det krav, der ikke kan omgås.

     #716c62 er den lyseste nedskalering af samme kulør, der består alle tre:
        Papir 4,67:1 · Kalk 5,22:1 · Tavle 5,00:1
     #8A8478 er bevaret til IKKE-tekst: streger, prikker, ikoner.
     --------------------------------------------------------------------- */
  --beton-tekst: #716c62;

  /* ---------------------------------------------------------------------
     Kant på INTERAKTIVE kontroller.

     WCAG 1.4.11 kræver 3:1 for det, der identificerer en kontrol. Målt:
        --kant #E2DED6 på Kalk   1,34:1
        --kant #E2DED6 på Papir  1,20:1
     En chip eller en opfølgningsknap identificeres udelukkende af sin 1 px
     kant på en flade, der selv kun er 1,12:1 mod siden — altså visuelt ikke
     til at skelne fra et afsnit brødtekst.

     Beton (#8A8478) giver 3,72:1 på Kalk og består dermed. Brandguiden
     udpeger netop Beton til IKKE-tekst — streger, ikoner, rammer — så dette
     er den brug, guiden allerede foreskriver. --kant bevares til dekorative
     skillelinjer, hvor 1.4.11 ikke gælder.
     --------------------------------------------------------------------- */
  --kant-kontrol: #8a8478;

  /* ---- Status ---- */
  --obs: #c2481f;
  /* Obs/Papir er 4,43:1 — lige under AA. Denne giver 5,65:1 på Papir. */
  --obs-tekst: #a83c15;
  --info: #2c6be0;

  /* ---- Rum, 8 px grundenhed ---- */
  --rum-h: 4px;
  --rum-1: 8px;
  --rum-2: 12px;
  --rum-3: 16px;
  --rum-4: 24px;
  --rum-5: 32px;
  --rum-6: 48px;
  --rum-7: 56px;
  --rum-8: 80px;

  /* ---- Radius, version 1.1 ---- */
  --radius-1: 6px; /* små kontroller: chips, felter */
  --radius-2: 8px; /* kort, knapper, beskeder */
  --radius-3: 12px; /* store paneler, komposer */
  --radius-ikon: 5px; /* fastlåst af logoet */

  /* ---- Elevation, kun flydende lag ---- */
  --skygge-1: 0 1px 2px rgba(20, 24, 28, 0.04), 0 -1px 12px rgba(20, 24, 28, 0.04);
  --skygge-2: 0 8px 24px rgba(20, 24, 28, 0.1), 0 2px 6px rgba(20, 24, 28, 0.06);

  --skrift: Archivo, 'Helvetica Neue', Arial, sans-serif;

  /* Maks. linjebredde på lovtekst. `ch` er bredden af "0", ikke et
     gennemsnitstegn — i Archivo er 72ch ca. 80 tegn. 60ch rammer guidens
     72-tegns-grænse. */
  --lov-bredde: 60ch;

  /* Læsebredde på brødtekst og svar. */
  --laese-bredde: 68ch;

  --appbar-hoejde: 60px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Topbjælken er sticky. Uden dette scroller ankre og fokusringe ind under. */
  scroll-padding-top: calc(var(--appbar-hoejde) + var(--rum-2));
}

body {
  margin: 0;
  background: var(--papir);
  color: var(--blaek);
  font-family: var(--skrift);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------- Typografi ---------- */

h1,
h2,
h3,
h4 {
  margin: 0;
  color: var(--blaek);
  text-wrap: balance;
}

h1 {
  font-size: clamp(32px, 4.6vw, 46px);
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
}

h2 {
  font-size: clamp(22px, 2.6vw, 28px);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.25;
}

h3 {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.005em;
}

h4 {
  font-size: 16px;
  font-weight: 600;
}

p {
  margin: 0 0 var(--rum-3);
  max-width: var(--laese-bredde);
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--paragrafgroen);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--groen-dyb);
}

:focus-visible {
  outline: 2px solid var(--paragrafgroen);
  outline-offset: 2px;
  border-radius: 2px;
}

.label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--beton-tekst);
}

.note {
  font-size: 14.5px;
  color: var(--beton-tekst);
  max-width: var(--laese-bredde);
}

.manchet {
  font-size: clamp(18px, 2vw, 20px);
  line-height: 1.55;
  color: var(--blaek);
  max-width: 60ch;
}

.visuallyhidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skiplink {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--paragrafgroen);
  color: var(--papir);
  padding: var(--rum-2) var(--rum-3);
  border-radius: var(--radius-2);
  text-decoration: none;
}

.skiplink:focus {
  left: var(--rum-2);
  top: var(--rum-2);
}

/* ---------- Layout ---------- */

.wrap {
  width: 100%;
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 var(--rum-4);
}

.wrap--smal {
  max-width: 820px;
}

.sektion {
  padding: var(--rum-8) 0;
}

.sektion--tavle {
  background: var(--tavle);
  border-top: 1px solid var(--kant);
  border-bottom: 1px solid var(--kant);
}

.sektion__hoved {
  max-width: 60ch;
  margin-bottom: var(--rum-5);
}

.sektion__hoved p {
  margin-top: var(--rum-2);
  margin-bottom: 0;
}

/* ---------- Logo ---------- */

.logo {
  display: inline-flex;
  align-items: center;
  gap: var(--rum-1);
  text-decoration: none;
  color: var(--blaek);
}

.logo:hover {
  color: var(--blaek);
}

/* Dobbeltparagraf: første § paragrafgrøn, andet signalgul. Signalgul er her
   et mærke, ikke brødtekst — tilladt brug. */
.logo__maerke {
  font-weight: 700;
  font-size: 28px;
  line-height: 1;
  letter-spacing: -0.06em;
}

.logo__maerke span:first-child {
  color: var(--paragrafgroen);
}

.logo__maerke span:last-child {
  color: var(--signalgul);
}

.logo__ord {
  font-weight: 800;
  font-size: 21px;
  letter-spacing: -0.035em;
}

.logo__undertekst {
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--beton-tekst);
  margin-top: 1px;
}

/* ---------- Topbjælke ---------- */

.top {
  background: rgba(244, 242, 238, 0.92);
  -webkit-backdrop-filter: blur(8px); /* Safari, inkl. iOS */
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--kant);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* Understøtter browseren ikke blur, skal bjælken være helt uigennemsigtig —
   ellers læses tekst gennem den, når indhold ruller forbi. */
@supports not ((backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))) {
  .top {
    background: var(--papir);
  }
}

.top__indhold {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--rum-3);
  min-height: var(--appbar-hoejde);
}

.top__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--rum-3);
  font-size: 15px;
}

.top__nav a:not(.knap) {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--blaek);
  text-decoration: none;
}

.top__nav a:not(.knap):hover {
  color: var(--paragrafgroen);
  text-decoration: underline;
}

/* ---------- Knapper ---------- */

.knap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--rum-1);
  min-height: 48px;
  padding: var(--rum-2) var(--rum-4);
  border: 1px solid var(--paragrafgroen);
  border-radius: var(--radius-2);
  background: var(--paragrafgroen);
  color: var(--papir);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.knap:hover:not(:disabled) {
  background: var(--groen-dyb);
  border-color: var(--groen-dyb);
  color: var(--papir);
}

/* [hidden] SKAL kunne skjule en knap.
 *
 * En author-deklaration slaar UA-arkets [hidden] { display: none } uanset
 * specificitet. .knap saetter display: inline-flex, saa #historik-knap, #ud-knap
 * og #login-link blev ALDRIG skjult: en bruger uden login saa baade "Log ind" og
 * "Log ud" og en tom Samtaler-knap, og en logget ind bruger saa dem begge.
 *
 * Reglen staar allerede eksplicit for hvert andet element med en
 * display-override — .kildepanel, .kald, .vedhaeft, .historik, .kvittering.
 * .knap og .ikonknap var glemt. */
.knap[hidden],
.ikonknap[hidden] {
  display: none;
}

.knap:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.knap--sekundaer {
  background: var(--kalk);
  color: var(--paragrafgroen);
}

.knap--sekundaer:hover:not(:disabled) {
  background: var(--groen-tone);
  color: var(--groen-dyb);
}

.knap--stille {
  background: transparent;
  border-color: var(--kant-kontrol);
  color: var(--blaek);
}

.knap--stille:hover:not(:disabled) {
  background: var(--tavle);
  border-color: var(--beton-tekst);
  color: var(--blaek);
}

.knap--lille {
  min-height: 44px;
  padding: var(--rum-1) var(--rum-2);
  font-size: 14px;
}

.knapraekke {
  display: flex;
  gap: var(--rum-2);
  flex-wrap: wrap;
  margin-top: var(--rum-4);
}

/* Ikon-knap: kvadratisk, til send og vedhæft. Aldrig rund — se guiden. */
.ikonknap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex: none;
  padding: 0;
  border: 1px solid var(--paragrafgroen);
  border-radius: var(--radius-2);
  background: var(--paragrafgroen);
  color: var(--papir);
  cursor: pointer;
}

.ikonknap:hover:not(:disabled) {
  background: var(--groen-dyb);
  border-color: var(--groen-dyb);
}

.ikonknap:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.ikonknap svg {
  width: 20px;
  height: 20px;
  display: block;
}

/* ---------- Kort og gitter ---------- */

.kort {
  background: var(--kalk);
  border: 1px solid var(--kant);
  border-radius: var(--radius-2);
  padding: var(--rum-4);
}

.kort h3 {
  margin-bottom: var(--rum-1);
}

.kort--fremhaevet {
  border-left: 3px solid var(--paragrafgroen);
}

.gitter {
  display: grid;
  gap: var(--rum-3);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

/* ---------- Lovtekst ---------- */

/* Paragrafgrøn venstrekant på Tavle. Systemets vigtigste visuelle regel:
   brugeren skal altid kunne se, hvad der er reglementets egne ord. */
.lovtekst {
  background: var(--tavle);
  border: 1px solid var(--kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 0 var(--radius-1) var(--radius-1) 0;
  padding: var(--rum-3) var(--rum-4);
  margin: var(--rum-3) 0;
  max-width: var(--lov-bredde);
  font-size: 16px;
  line-height: 1.7;
}

/* Vejledning er ikke bindende og får derfor en anden kant end kravet. */
.lovtekst--vejledning {
  border-left-color: var(--signalgul);
  background: var(--gul-tone);
}

.lovtekst__kilde {
  display: block;
  margin-bottom: var(--rum-1);
}

/* =============================================================================
   Kravkort — teknisk tegning
   =============================================================================
   Det visuelle sprog er byggetegningens: tynde streger, målsætningslinjer med
   kotepile, skravering. Tre stregvægte med hver sin rolle, og det er dem, der
   gør forskellen mellem en tegning og en illustration.

   Farverne sættes med KLASSER, ikke med style-attributter: CSP'en har
   style-src-attr 'none', og en inline style i SVG ville blive blokeret.

   vector-effect: non-scaling-stroke er nødvendig. Uden den skalerer stregvægten
   med viewBox'en, og en tegning af et 1,0 m værn ville få tykkere streger end
   en af et 2,1 m loft — altså en vilkårlig visuel forskel på to lige vigtige
   krav.
   ========================================================================== */

.kravkort {
  margin: var(--rum-3) 0 0;
  padding: var(--rum-2) var(--rum-3);
  background: var(--tavle);
  border: 1px solid var(--kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 0 var(--radius-1) var(--radius-1) 0;
  max-width: var(--lov-bredde);
}

/* Vejledning er ikke bindende og får derfor samme signalgule kant som
   .lovtekst--vejledning. Krav og vejledning må ikke se ens ud — heller ikke
   som tegning. */
.kravkort--vejledning {
  border-left-color: var(--signalgul);
  background: var(--gul-tone);
}

.kravkort__tegning {
  display: block;
  width: 100%;
  max-width: 320px;
  height: auto;
}

/* ---- De tre stregvægte ---- */

/* Snitflade: bygningsdelen selv. Tykkest, fordi den er motivet. */
.kravkort__tegning .tg-snit {
  stroke: var(--paragrafgroen);
  stroke-width: 2;
  stroke-linecap: square;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.kravkort__tegning .tg-snit-ramme {
  stroke: var(--paragrafgroen);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
  fill: none;
}

/* Målsætningslinjen. Tynd, men i fuld farve — den skal læses. */
.kravkort__tegning .tg-maal {
  stroke: var(--blaek);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
}

/* Hjælpelinjer: fører fra bygningsdelen ud til målsætningen. Svagest. */
.kravkort__tegning .tg-hjaelp {
  stroke: var(--beton);
  stroke-width: 0.75;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.kravkort__tegning .tg-pil {
  fill: var(--blaek);
  stroke: none;
}

.kravkort__tegning .tg-flade {
  fill: var(--kalk);
  stroke: none;
}

/* Materiale i snit.
   En rigtig diagonal skravering kræver et <pattern> i defs pr. tegning. Det
   kommer, når der er flere materialer at skelne mellem — indtil da bæres
   signalet af snitstregen, og fladen er blot en tone. En skravering, der ikke
   betyder noget bestemt, er dekoration, og dekoration i en lovtegning er en
   påstand, vi ikke kan dokumentere. */
.kravkort__tegning .tg-skravering {
  fill: var(--groen-tone);
  stroke: none;
}

.kravkort__tegning .tg-tal {
  fill: var(--blaek);
  stroke: var(--tavle);
  stroke-width: 4;
  font-family: var(--skrift);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

.kravkort--vejledning .kravkort__tegning .tg-tal {
  stroke: var(--gul-tone);
}

.kravkort__note {
  margin-top: var(--rum-1);
  font-size: 13px;
  color: var(--beton-tekst);
}

.kravkort__kilde {
  font-weight: 600;
  color: var(--blaek);
}

/* ---------- Kildehenvisning som chip ---------- */

.kilder {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rum-1);
  margin-top: var(--rum-2);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--rum-1);
  min-height: 44px;
  padding: var(--rum-1) var(--rum-2);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--kalk);
  color: var(--blaek);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.chip:hover,
.chip[aria-expanded='true'] {
  border-color: var(--paragrafgroen);
  background: var(--groen-tone);
}

.chip__prik {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--paragrafgroen);
  flex: none;
}

.chip--vejledning .chip__prik {
  background: var(--signalgul);
}

/* Farve alene er ikke nok (WCAG 1.4.1) — chippen får også tekst i JS. */
.chip--uverificeret {
  border-color: var(--obs);
}

.chip--uverificeret .chip__prik {
  background: var(--obs);
}

.kildepanel {
  border: 1px solid var(--kant);
  border-radius: var(--radius-2);
  background: var(--tavle);
  padding: var(--rum-3);
  margin-top: var(--rum-2);
}

.kildepanel[hidden] {
  display: none;
}

.kildepanel .lovtekst {
  margin-top: 0;
}

/* =============================================================================
   Chat-appen
   =============================================================================
   Fladen er en app, ikke et dokument: fast topbjælke, rullende tråd i midten,
   komposer fastgjort i bunden. Den gamle opbygning havde spørgefeltet ØVERST
   og svarene under, så feltet forsvandt op ud af skærmen så snart samtalen
   blev længere end et skærmbillede. Det er den vigtigste ændring her.
   ========================================================================== */

body.app {
  /* 100vh først som fallback: på iOS under 15.4 findes dvh ikke, og uden
     fallback ville højden være auto — så ville komposeren ikke sidde fast.
     dvh er nødvendig OVEN i den, fordi 100vh på iOS regner med skjult
     browser-chrome og gør fladen for høj, så bunden skæres af. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--papir);
}

/* Rullefladen. minmax(0, 1fr) ovenfor er nødvendig — uden den nægter
   grid-rækken at blive mindre end sit indhold, og hele siden ruller i
   stedet for tråden. */
.traad {
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-behavior: smooth;
  padding: var(--rum-4) 0 var(--rum-5);
}

.traad__indhold {
  width: 100%;
  max-width: 820px;
  margin: 0 auto;
  padding: 0 var(--rum-4);
  display: flex;
  flex-direction: column;
  gap: var(--rum-4);
}

/* ---- Tom tilstand ---- */

.velkomst {
  padding: var(--rum-5) 0 var(--rum-2);
}

.velkomst h1 {
  font-size: clamp(26px, 3.4vw, 34px);
}

.velkomst .manchet {
  margin-top: var(--rum-2);
}

/* ---- En tur i samtalen ---- */

.tur {
  display: flex;
  flex-direction: column;
  gap: var(--rum-1);
}

.tur__rolle {
  margin: 0;
}

/* Brugerens spørgsmål: Tavle-flade, tydeligt adskilt fra svaret uden at
   efterligne en beskedboble. */
.tur--bruger {
  align-items: flex-end;
}

.tur--bruger .tur__tekst {
  background: var(--tavle);
  border: 1px solid var(--kant);
  border-radius: var(--radius-2);
  padding: var(--rum-2) var(--rum-3);
  max-width: 90%;
}

.tur--svar .tur__tekst {
  max-width: var(--laese-bredde);
}

.tur__tekst {
  overflow-wrap: anywhere;
}

/* pre-wrap KUN på brugerens spørgsmål. Det er rå tekst, hvor linjeskift er
   brugerens egne og skal bevares.
   Svaret bygges af rigtige <p> og <ul> af svartekst() i app.js, og pre-wrap
   ovenpå det ville give dobbelt luft mellem afsnittene. */
.tur--bruger .tur__tekst {
  white-space: pre-wrap;
}

/* Luften mellem afsnit er det, der gør et svar til et opslag frem for en mur.
   Den er større end normal afsnitsluft med vilje: hvert afsnit er ét krav, og
   man skal kunne finde det rigtige uden at læse hele svaret. */
.tur--svar .tur__tekst p + p,
.tur--svar .tur__tekst p + .svarliste,
.tur--svar .tur__tekst .svarliste + p {
  margin-top: var(--rum-3);
}

/* Den levende tekst, mens svaret skrives.
   pre-wrap, fordi teksten endnu ikke er delt i afsnit og lister — det kan foerst
   goeres, naar hele svaret er der, og en halv liste ville hoppe paa skaermen.
   Markoeren er en blinkende streg, saa det er tydeligt at der kommer mere. */
.tur__tekst--levende {
  white-space: pre-wrap;
}

.tur__tekst--levende::after {
  content: ;
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--paragrafgroen);
  animation: markoer 1s step-end infinite;
}

@keyframes markoer {
  50% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .tur__tekst--levende::after {
    animation: none;
  }
}

/* ---- Svaret skrives frem ----
   Afsnittene tændes ét ad gangen af skrivLevende() i app.js. Teksten ER i DOM'en
   hele tiden — det er kun synligheden, der venter. Derfor kan en skærmlæser læse
   hele svaret med det samme, og en søgemaskine ser det fuldt.

   visibility og ikke display: pladsen skal være taget fra starten, ellers ville
   svarkortet vokse ryk for ryk, og siden ville hoppe under læsningen. */
.tur__tekst[data-levende] > [data-venter] {
  visibility: hidden;
}

.tur__tekst[data-levende] > :not([data-venter]) {
  animation: afsnit-ind 0.22s cubic-bezier(0.2, 0.7, 0.3, 1);
}

@keyframes afsnit-ind {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Listen er reglementets egen form: én linje pr. krav. Punkttegnet er en kort
   paragrafgrøn streg og ikke en prik — det er tegningens streg, ikke et
   generisk bullet. */
.svarliste {
  margin: 0;
  padding: 0;
  list-style: none;
}

.svarliste li {
  position: relative;
  padding-left: var(--rum-4);
}

.svarliste li + li {
  margin-top: var(--rum-2);
}

.svarliste li::before {
  content: '';
  position: absolute;
  left: 0;
  /* 0,7em rammer midt i den første linje ved en linjehøjde omkring 1,55 —
     regnet, ikke skønnet, så stregen ikke sidder over eller under teksten. */
  top: 0.7em;
  width: 10px;
  height: 2px;
  background: var(--paragrafgroen);
}

/* Svaret er en flade på Kalk med paragrafgrøn kant i venstre side, så et
   svar visuelt hører til reglementet — men lysere end .lovtekst, fordi det
   er VORES ord, ikke reglementets. */
.svarkort {
  background: var(--kalk);
  border: 1px solid var(--kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 0 var(--radius-2) var(--radius-2) 0;
  padding: var(--rum-3) var(--rum-4);
}

.svarkort--afvist {
  border-left-color: var(--obs);
}

/* En netværksfejl er ikke en principiel afvisning. De to må ikke se ens ud. */
.svarkort--fejl {
  border-left-color: var(--beton-tekst);
}

.svarkort__afsnit {
  margin-top: var(--rum-3);
  padding-top: var(--rum-3);
  border-top: 1px solid var(--kant);
}

/* ---- Status under arbejde ---- */

.status {
  display: flex;
  align-items: center;
  gap: var(--rum-1);
  color: var(--beton-tekst);
  font-size: 15px;
}

.status__prik {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--paragrafgroen);
  flex: none;
  animation: puls 1.4s ease-in-out infinite;
}

@keyframes puls {
  0%,
  100% {
    opacity: 0.3;
  }
  50% {
    opacity: 1;
  }
}

/* ---- Afvisning og advarsel ----
   De VIGTIGSTE beskeder var tidligere de mindste: advarslen om en
   ukontrolleret kildehenvisning stod som 14 px fodnote, og "svarede ikke" som
   12 px versalmærkat. Den ene siger "stol ikke på dette", den anden er en
   kvalitet og ikke en fejl. De skal se ud som det, de er. */

.afvisning {
  margin: 0 0 var(--rum-2);
  font-size: 16px;
  font-weight: 600;
  color: var(--obs-tekst);
  max-width: var(--lov-bredde);
}

.advarsel {
  margin: var(--rum-3) 0 0;
  padding: var(--rum-2) var(--rum-3);
  border: 1px solid var(--obs);
  border-left-width: 3px;
  border-radius: 0 var(--radius-1) var(--radius-1) 0;
  background: var(--kalk);
  font-size: 15.5px;
  color: var(--blaek);
  max-width: var(--lov-bredde);
}

/* ---- Foreslåede opfølgninger ---- */

.opfoelg {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rum-1);
  margin-top: var(--rum-2);
}

.opfoelg__knap {
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--kalk);
  color: var(--blaek);
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 500;
  text-align: left;
  padding: var(--rum-1) var(--rum-2);
  min-height: 44px;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.opfoelg__knap:hover {
  border-color: var(--paragrafgroen);
  background: var(--groen-tone);
}

/* ---- Feedback og målinger ---- */

.feedback {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--rum-1);
  margin-top: var(--rum-3);
}

.maalinger {
  font-size: 13px;
  color: var(--beton-tekst);
  display: flex;
  flex-wrap: wrap;
  gap: var(--rum-2);
  margin-top: var(--rum-2);
}

/* ---------- Komposer ---------- */

.komposer {
  background: var(--papir);
  border-top: 1px solid var(--kant);
  box-shadow: var(--skygge-1);
  padding: var(--rum-2) 0 var(--rum-3);
  /* Plads til hjemmeindikatoren på iOS. */
  padding-bottom: max(var(--rum-3), env(safe-area-inset-bottom));
}

.komposer__indhold {
  width: 100%;
  max-width: 820px;
  margin: 0 auto;
  padding: 0 var(--rum-4);
}

.komposer__felt {
  display: flex;
  align-items: flex-end;
  gap: var(--rum-1);
  background: var(--kalk);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-3);
  padding: var(--rum-1);
  transition: border-color 0.12s ease;
}

.komposer__felt:focus-within {
  border-color: var(--paragrafgroen);
}

/* Autogrow uden inline styles.
   ---------------------------------------------------------------------------
   Feltet skal vokse med indholdet. Den sædvanlige løsning sætter
   element.style.height fra JavaScript, men CSP'en her har
   style-src-attr 'none', og vi vil ikke bygge på en antagelse om, hvorvidt
   CSSOM rammes af den.

   I stedet ligger tekstfeltet og en skjult kopi af teksten oven på hinanden i
   samme grid-celle. Kopien er almindeligt indhold og bestemmer højden; JS
   sætter kun et data-attribut, aldrig en style. Loftet er på wrapperen, så
   lange spørgsmål ruller i stedet for at skubbe komposeren op over skærmen. */
.komposer__vokse {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
  max-height: 200px;
  overflow-y: auto;
}

.komposer__vokse::after,
.komposer__felt textarea {
  grid-area: 1 / 1 / 2 / 2;
  border: 0;
  background: transparent;
  color: var(--blaek);
  font-family: inherit;
  font-size: 17px;
  font-weight: 400;
  line-height: 1.5;
  padding: var(--rum-2);
  min-height: 48px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Kopien af teksten. Mellemrummet efter attr() sikrer, at en afsluttende
   linjeskift også giver plads til den nye linje. */
.komposer__vokse::after {
  content: attr(data-tekst) ' ';
  visibility: hidden;
  pointer-events: none;
}

.komposer__felt textarea {
  outline: 0;
  resize: none;
  overflow: hidden;
}

.komposer__fod {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--rum-2);
  flex-wrap: wrap;
  margin-top: var(--rum-1);
  font-size: 13px;
  color: var(--beton-tekst);
}

.komposer__fod p {
  margin: 0;
  font-size: 13px;
  max-width: none;
}

/* =============================================================================
   Hussnit — reglementet sat ind i bygningen
   =============================================================================
   Samme stregvægte som kravkortet, så de to tegninger hører til samme sprog.
   Fremhævningen sker med ÉT data-attribut på beholderen; CSS'en gør resten, så
   der ikke findes en klasse, der kan komme ud af trit med aria-pressed.
   ========================================================================== */

/* ---- Heroen ----
   Alt det vigtige i første skærmbillede: overskrift, hvad værktøjet gør, den
   klikbare tegning og nøgletallene. Vil man mere, ruller man.

   svh og ikke vh: på mobil ændrer vh sig, når browserens adresselinje glider
   væk, og heroen ville hoppe under rulningen. svh er den lille højde og står
   stille. min-height og ikke height, så indholdet aldrig bliver klippet, hvis
   nogen zoomer eller bruger stor systemskrift. */
.hero {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: calc(100svh - var(--appbar-hoejde));
  padding: var(--rum-5) 0 0;
  background: var(--papir);
  border-bottom: 1px solid var(--kant);
}

/* ---- Tegneark ----
   Heroen skal læses som et TEGNEARK, og huset som en tegning på det. Det er
   vores udgave af et baggrundsgitter: ikke et dekorativt prikmønster, men
   millimeterpapir — fladen en projekterende faktisk tegner på.

   To lag som i rigtigt millimeterpapir: en fin 8 px-deling og en kraftigere
   linje for hver 40 px. 8 px er ikke tilfældigt; det er designsystemets
   grundenhed, så gitteret og layoutet står i samme takt.

   Masken er det, der holder brandguidens 70 % Papir: gitteret er stærkest
   OMKRING TEGNINGEN og forsvinder helt mod kanterne, så det aldrig bliver en
   fladefarve på et stort område. Centret ligger ved 74 % 46 % — altså over
   huset, ikke over teksten. Sad det ved teksten, blev gitteret tættest, hvor der
   skal læses, og huset kom til at svæve på en tom flade.

   Ren CSS. Ingen billeder, intet JavaScript, ingen bevægelse. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(31, 92, 74, 0.16) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(31, 92, 74, 0.16) 1px, transparent 1px),
    linear-gradient(to right, rgba(31, 92, 74, 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(31, 92, 74, 0.07) 1px, transparent 1px);
  background-size:
    40px 40px,
    40px 40px,
    8px 8px,
    8px 8px;
  /* Halvgennemsigtig maske, så gitteret toner ud mod kanterne frem for at blive
     klippet med en hård kant. */
  mask-image: radial-gradient(90% 80% at 74% 46%, #000 0%, rgba(0, 0, 0, 0.5) 55%, transparent 82%);
  -webkit-mask-image: radial-gradient(90% 80% at 74% 46%, #000 0%, rgba(0, 0, 0, 0.5) 55%, transparent 82%);
}

/* Understøtter browseren ikke masker, ville gitteret dække hele fladen med hård
   kant. Så er det bedre helt væk: tegningen bærer sig selv. */
@supports not ((mask-image: radial-gradient(#000, transparent)) or
  (-webkit-mask-image: radial-gradient(#000, transparent))) {
  .hero::before {
    display: none;
  }
}

/* Heroen får en bredere ramme end resten af siden. Det er ikke inkonsekvens:
   tegningen er sidens billede, og på 1120 px blev huset en illustration ved
   siden af teksten frem for det, siden handler om. Sektionerne nedenfor holder
   1120, så læsebredden på brødtekst er uændret.

   Kolonnerne 0,72/1,28 giver tegningen omkring 740 px mod tekstens 420 — huset
   er den brede halvdel. */
.hero__indhold {
  display: grid;
  gap: var(--rum-5);
  grid-template-columns: 0.72fr 1.28fr;
  align-items: center;
  flex: 1 1 auto;
  max-width: 1240px;
  padding-top: var(--rum-4);
  padding-bottom: var(--rum-4);
}

.hero__tekst h1 {
  font-size: clamp(32px, 4.1vw, 46px);
}

@media (max-width: 1000px) {
  .hero {
    min-height: 0;
    padding-bottom: var(--rum-4);
  }

  .hero__indhold {
    grid-template-columns: 1fr;
    gap: var(--rum-4);
  }
}

.hus {
  min-width: 0;
}

/* Rammen er KUN en positioneringsflade: den er præcis lige så stor som SVG'en,
   så punkternes procent-koordinater rammer det samme som viewBox'ens. Havde den
   polstring eller en anden højde, ville hvert punkt sidde forskudt.

   INGEN hvid kasse. Huset er tegnet på arket, ikke lagt i et kort ovenpå det —
   det var netop det, der fik heroen til at falde fra hinanden: et kort med
   skygge, der svævede over millimeterpapiret, så gitteret blev en baggrund
   bagved frem for den flade, tegningen står på. */
.hus__ramme {
  position: relative;
  /* Samme forhold som viewBox 460 × 340. Uden det ville rammen have SVG'ens
     højde først efter indlæsning, og punkterne ville hoppe på plads. */
  aspect-ratio: 460 / 340;
}

.snit {
  display: block;
  width: 100%;
  height: 100%;
  background: transparent;
  border: 0;
  overflow: visible;
}

/* Stregvægtene. Se forklaringen ved .kravkort__tegning — non-scaling-stroke er
   nødvendig, ellers ændrer vægten sig med visningsstørrelsen. */
.snit .tg-snit {
  stroke: var(--paragrafgroen);
  stroke-width: 2;
  stroke-linecap: square;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.snit .tg-snit-ramme {
  stroke: var(--paragrafgroen);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.snit .tg-hjaelp {
  stroke: var(--beton);
  stroke-width: 0.75;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.snit .tg-maal {
  stroke: var(--blaek);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.snit .tg-flade {
  fill: var(--kalk);
  stroke: none;
}

.snit .tg-skravering {
  fill: var(--groen-tone);
  stroke: none;
}

/* Fremhævning. Uden et valg står hele snittet i fuld styrke — det er også
   tilstanden uden JavaScript.

   fill-box og ikke view-box: transform-origin skal være den enkelte bygningsdels
   egen midte, ikke hele tegningens. Ellers ville taget skalere om et punkt nede
   ved fundamentet og glide sidelæns i stedet for at træde frem. */
.hus[data-aktiv] .snit > g {
  opacity: 0.18;
  transition: opacity 0.2s ease;
  transform-box: fill-box;
  transform-origin: center;
}

/* Bygningsdelene bæres af data-del, ikke af id. Det er ikke kosmetik: med
   attributter kan reglen for bevægelse frabedt nedenfor have samme specificitet
   og vinde, fordi den står senere. Med et id i selektoren kunne den ikke slås
   uden !important — og et !important, der kun står der for at slå ens eget
   id-valg, er en fejl, man arver. */
.hus[data-aktiv='del-tag'] .snit > [data-del='del-tag'],
.hus[data-aktiv='del-ydervaeg'] .snit > [data-del='del-ydervaeg'],
.hus[data-aktiv='del-etage'] .snit > [data-del='del-etage'],
.hus[data-aktiv='del-vindue'] .snit > [data-del='del-vindue'],
.hus[data-aktiv='del-doer'] .snit > [data-del='del-doer'],
.hus[data-aktiv='del-trappe'] .snit > [data-del='del-trappe'],
.hus[data-aktiv='del-vaadrum'] .snit > [data-del='del-vaadrum'],
.hus[data-aktiv='del-koekken'] .snit > [data-del='del-koekken'],
.hus[data-aktiv='del-ventilation'] .snit > [data-del='del-ventilation'],
.hus[data-aktiv='del-varme'] .snit > [data-del='del-varme'],
.hus[data-aktiv='del-afloeb'] .snit > [data-del='del-afloeb'],
.hus[data-aktiv='del-fundament'] .snit > [data-del='del-fundament'] {
  opacity: 1;
  animation: fremhaev 0.42s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* Den valgte del træder frem: et lille overskud forbi 1 og tilbage igen. Fordi
   stregerne har non-scaling-stroke, bliver de ikke tykkere undervejs — det er
   delen, der flytter sig, ikke tegningens stregvægt, der ændrer sig. */
@keyframes fremhaev {
  0% {
    opacity: 0.25;
    transform: scale(0.982);
  }
  55% {
    opacity: 1;
    transform: scale(1.012);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Terrænet bliver svagt synligt, så huset ikke svæver, når man vælger en del
   inde i det. Terrænet har med vilje ikke data-del: det er ikke en bygningsdel,
   reglementet stiller krav til, og skal derfor ikke kunne vælges. */
.hus[data-aktiv] #del-terraen {
  opacity: 0.45;
}

/* Tegningen skal kunne trykkes på, ikke kun prikkerne. Det virker dér, hvor
   delen har en flade (tg-flade); rene streger som tagfladen rammes kun på selve
   stregen — derfor er prikken den bærende indgang, og tegningen den ekstra. */
.snit > g[data-del] {
  cursor: pointer;
}

/* ---- Gratis-maerket i heroen ----
   Stort og foerst, efter Benjamins oenske. Betoningen baeres af stoerrelsen og
   den signalgule UNDERSTREGNING — guiden tillader gul som markering, aldrig som
   tekstfarve paa lys bund, og det er praecis den brug. */
.hero__gratis {
  font-size: clamp(20px, 2.6vw, 30px);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--blaek);
}

.hero__gratis-tal {
  position: relative;
  color: var(--paragrafgroen);
  font-variant-numeric: tabular-nums;
}

.hero__gratis-tal::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 6px;
  background: var(--signalgul);
  z-index: -1;
}

/* ---- Chat-previewet i heroen ----
   Ikke en knap, der lover en chat — selve spørgefeltet. Kortet låner appens
   komposer-sprog, så det, man ser her, er det, man får derinde.

   Spøgelsesteksten er en <button> henover feltet: et tryk lægger spørgsmålet i
   feltet. Den er aria-hidden — skærmlæseren har feltets egen label, og en tekst,
   der skifter hvert sjette sekund, ville kun larme. */
.hero-chat {
  max-width: 460px;
}

.hero-chat__felt {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--rum-1);
  padding: var(--rum-1);
  background: var(--kalk);
  border: 1px solid var(--kant-kontrol);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: var(--radius-3);
}

.hero-chat__felt:focus-within {
  border-color: var(--paragrafgroen);
}

.hero-chat__felt input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 48px;
  padding: var(--rum-1) var(--rum-2);
  border: 0;
  background: transparent;
  color: var(--blaek);
  font-family: inherit;
  /* 16 px eller mere, ellers zoomer iOS ind ved fokus. */
  font-size: 16px;
}

.hero-chat__felt input:focus {
  outline: 0;
}

/* Spøgelset ligger over feltet, men slipper klik igennem til teksten selv:
   hele fladen ER klikbar, fordi den er en knap. */
.hero-chat__ghost {
  position: absolute;
  left: calc(var(--rum-1) + var(--rum-2));
  right: 64px;
  top: 0;
  bottom: 0;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--beton-tekst);
  font-family: inherit;
  font-size: 16px;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  cursor: text;
}

.hero-chat__ghost[hidden] {
  display: none;
}

/* Skrivemarkøren. En 2 px streg, der blinker — samme sprog som et rigtigt
   felt, så øjet læser "her kan der skrives". */
.hero-chat__ghost::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 1.1em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--paragrafgroen);
  animation: hero-markoer 1.1s steps(2) infinite;
}

@keyframes hero-markoer {
  to {
    opacity: 0;
  }
}

.hero-chat__send {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--paragrafgroen);
  border-radius: var(--radius-2);
  background: var(--paragrafgroen);
  color: var(--papir);
  cursor: pointer;
  transition: background-color 0.14s ease;
}

.hero-chat__send:hover {
  background: var(--groen-dyb);
}

.hero-chat__send svg {
  width: 20px;
  height: 20px;
  display: block;
}

.hero-chat__fod {
  display: flex;
  align-items: center;
  gap: var(--rum-2);
  margin-top: var(--rum-1);
  font-size: 12.5px;
  color: var(--beton-tekst);
}

@media (prefers-reduced-motion: reduce) {
  .hero-chat__ghost::after {
    animation: none;
    opacity: 0.6;
  }
}

/* ---- Glyffer i tegningens stregsprog ----
   Delt af flow-trinnene, kortene og tillidspunkterne. Samme tre stregvægte som
   snittet — det er stadig en byggetegning, ikke et ikonbibliotek. */
.flow__tegning .tg-flade,
.kort__glyf .tg-flade {
  fill: var(--groen-tone);
  stroke: none;
}

.flow__tegning .tg-flade--vejl,
.kort__glyf .tg-flade--vejl {
  fill: var(--gul-tone);
  stroke: none;
}

.flow__tegning .tg-snit-ramme,
.kort__glyf .tg-snit-ramme,
.tillid__glyf .tg-snit-ramme {
  stroke: var(--paragrafgroen);
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.kort__glyf .tg-ramme--vejl {
  stroke: var(--signalgul);
  stroke-width: 1.4;
  stroke-dasharray: 3 2;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.flow__tegning .tg-snit,
.tillid__glyf .tg-snit {
  stroke: var(--paragrafgroen);
  stroke-width: 2;
  stroke-linecap: square;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.flow__tegning .tg-hjaelp,
.kort__glyf .tg-hjaelp {
  stroke: var(--beton);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.flow__tegning .tg-groenkant,
.kort__glyf .tg-groenkant {
  stroke: var(--paragrafgroen);
  stroke-width: 6;
  vector-effect: non-scaling-stroke;
}

.flow__tegning .tg-flueben,
.kort__glyf .tg-flueben,
.tillid__glyf .tg-flueben {
  stroke: var(--paragrafgroen);
  stroke-width: 2.4;
  stroke-linecap: square;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.flow__tegning .tg-maal,
.flow__pil .tg-maal {
  stroke: var(--blaek);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.flow__pil .tg-pilhoved {
  fill: var(--blaek);
  stroke: none;
}

.flow__tegning .tg-paragraf {
  fill: var(--paragrafgroen);
  font-family: inherit;
  font-size: 16px;
  font-weight: 800;
}

.kort__glyf .tg-paragraf--stor {
  font-size: 22px;
}

/* ---- Flow: fra spørgsmål til paragraf ---- */
.flow {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  gap: var(--rum-3);
  align-items: start;
  margin: 0;
  padding: 0;
  list-style: none;
}

.flow__trin h3 {
  margin-top: var(--rum-2);
  font-size: 17px;
}

.flow__tegning {
  display: block;
  width: 120px;
  height: 90px;
}

.flow__pil {
  align-self: center;
  padding-top: var(--rum-4);
}

.flow__pil svg {
  display: block;
  width: 48px;
  height: 24px;
}

@media (max-width: 860px) {
  .flow {
    grid-template-columns: 1fr;
  }

  /* Pilene drejer ikke med — de fjernes. En lodret pil mellem tre kort siger
     ikke andet, end rækkefølgen allerede gør. */
  .flow__pil {
    display: none;
  }
}

/* ---- Nøgletalsbåndet ---- */
.baand {
  background: var(--groen-dyb);
  color: var(--papir);
}

.baand__raekke {
  display: grid;
  grid-template-columns: repeat(4, auto);
  justify-content: space-between;
  gap: var(--rum-3) var(--rum-4);
  padding-top: var(--rum-4);
  padding-bottom: var(--rum-4);
}

.baand__tal strong {
  display: block;
  font-size: clamp(26px, 3vw, 36px);
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.baand__tal span {
  display: block;
  max-width: 26ch;
  margin-top: 2px;
  font-size: 13px;
  color: rgba(244, 242, 238, 0.75);
}

@media (max-width: 760px) {
  .baand__raekke {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* ---- Kortenes glyffer ---- */
.kort__glyf {
  display: block;
  width: 44px;
  height: 44px;
  margin-bottom: var(--rum-2);
}

/* ---- Eksemplet i en vinduesramme ---- */
.vindue {
  background: var(--kalk);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-3);
  overflow: hidden;
}

.vindue__bjaelke {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: var(--rum-1) var(--rum-2);
  background: var(--tavle);
  border-bottom: 1px solid var(--kant);
}

.vindue__prik {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid var(--kant-kontrol);
  background: var(--kalk);
}

.vindue__titel {
  margin-left: var(--rum-1);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--beton-tekst);
}

.vindue__indhold {
  display: flex;
  flex-direction: column;
  gap: var(--rum-3);
  padding: var(--rum-4);
}

/* ---- Tillidspunkternes glyffer ---- */
.tillid__glyf {
  display: block;
  width: 36px;
  height: 36px;
  margin-bottom: var(--rum-2);
}

/* ---- Guidelisten ----
   En liste, ikke kort. Hver linje er en indgang til en artikel med paragraffen
   synlig — det er paragraffen, der gør linket vaerd at følge. */
.guide-liste {
  margin: 0;
  padding: 0;
  list-style: none;
}

.guide-liste li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--rum-3);
  padding: var(--rum-2) 0;
  border-top: 1px solid var(--kant);
}

.guide-liste li:first-child {
  border-top: 0;
}

.guide-liste a {
  font-weight: 600;
}

.guide-liste .note {
  flex: 0 0 auto;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
  .guide-liste li {
    flex-direction: column;
    gap: 2px;
  }

  .guide-liste .note {
    text-align: left;
  }
}

/* ---- Forbrugspanelet ----
   <progress> og ikke en div-maaler: elementet baerer value/max selv, saa
   CSP'ens style-src-attr 'none' ikke er i vejen, og skaermlaeseren faar
   procenten gratis. Udseendet kraever de leverandoer-praefiksede selektorer —
   det er prisen for det rigtige element, og den er lav. */
.forbrug__linje {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--rum-2);
  font-size: 14.5px;
  margin-bottom: var(--rum-1);
}

.forbrug__linje strong {
  font-variant-numeric: tabular-nums;
}

.forbrug progress {
  display: block;
  width: 100%;
  height: 8px;
  border: 1px solid var(--kant-kontrol);
  border-radius: 4px;
  background: var(--tavle);
  -webkit-appearance: none;
  appearance: none;
  overflow: hidden;
}

.forbrug progress::-webkit-progress-bar {
  background: var(--tavle);
}

.forbrug progress::-webkit-progress-value {
  background: var(--paragrafgroen);
}

.forbrug progress::-moz-progress-bar {
  background: var(--paragrafgroen);
}

.forbrug__blok .note {
  margin-top: var(--rum-h);
}

/* ---- Arbejdssporet ----
   Vises UNDER den levende tekst, mens faserne efter sidste saetning koerer.

   Hvorfor det er saa tydeligt: MAALT paa et rigtigt svar stod skaermen stille
   i 8,3 sekunder mellem sidste saetning og det faerdige svar, mens modellen
   skrev citations-arrayet og verifikationen koerte. Foerste udgave brugte den
   samme 8 px pulserende prik som faserne foer teksten — og den blev ikke set.
   Efter otte sekunders stilstand skal feedbacken vaere et element, ikke en
   detalje.

   Tegningens sprog, jf. brandguiden: 1 px kant frem for skygge, radius 4 px,
   paragrafgroen som den arbejdende farve. Ingen pill-form. */
.arbejder {
  margin-top: var(--rum-3);
  padding: var(--rum-2) var(--rum-3);
  border: 1px solid var(--kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 4px;
  background: var(--kalk);
}

.arbejder__hoved {
  display: flex;
  align-items: center;
  gap: var(--rum-2);
}

.arbejder__titel {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--paragrafgroen);
}

/* Tre prikker i FORSKUDT rytme. Mønsteret laeses som arbejde; én prik, der
   blinker, laeses som en prik, der blinker. */
.arbejder__prikker {
  display: inline-flex;
  gap: 5px;
  flex: none;
}

.arbejder__prik {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--paragrafgroen);
  animation: arbejder-puls 1.2s ease-in-out infinite;
}

.arbejder__prik:nth-child(2) {
  animation-delay: 0.2s;
}

.arbejder__prik:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes arbejder-puls {
  0%,
  100% {
    opacity: 0.25;
    transform: scale(0.85);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

.arbejder__fase {
  margin: var(--rum-1) 0 0;
  font-size: 14.5px;
  color: var(--blaek);
}

/* Maalestregen: en groen streg, der loeber i sporet som en kotepil, der maaler
   op. Bevidst uden procent-fremdrift — vi VED ikke hvor langt der er igen, og
   en bjaelke, der lover 70 %, ville lyve. Bevaegelse uden loefte. */
.arbejder__spor {
  position: relative;
  height: 2px;
  margin-top: var(--rum-2);
  background: var(--kant);
  overflow: hidden;
}

.arbejder__loeber {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 35%;
  background: var(--paragrafgroen);
  animation: arbejder-loeb 1.6s ease-in-out infinite;
}

@keyframes arbejder-loeb {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(386%);
  }
}

/* Respekterer systemvalget: ingen bevaegelse, men stadig synlig besked.
   Et stillestaaende spor er bedre end ingen besked — teksten baerer den. */
@media (prefers-reduced-motion: reduce) {
  .arbejder__prik,
  .arbejder__loeber {
    animation: none;
  }
  .arbejder__loeber {
    width: 100%;
    opacity: 0.45;
  }
}

/* ---- Artikler ---- */
.brod {
  font-size: 13px;
  color: var(--beton-tekst);
  margin-bottom: var(--rum-3);
}

.artikel__meta {
  margin-top: var(--rum-2);
  font-size: 13px;
  color: var(--beton-tekst);
}

.artikel h2 {
  font-size: 24px;
}

.artikel h3 {
  margin-top: var(--rum-3);
  font-size: 17px;
}

.artikel ul {
  padding-left: 1.2em;
}

.artikel li + li {
  margin-top: var(--rum-1);
}

.artikel-cta {
  padding: var(--rum-4);
  background: var(--groen-tone);
  border: 1px solid var(--groen-tone-kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 0 var(--radius-2) var(--radius-2) 0;
}

/* ---- Fodens navigation ---- */
.fod__nav {
  display: flex;
  gap: var(--rum-3);
  margin: var(--rum-3) 0;
  flex-wrap: wrap;
}

.fod__nav a {
  color: rgba(244, 242, 238, 0.85);
}

.fod__nav a:hover {
  color: var(--papir);
}

/* ---- Punkterne på huset ----
   Prikkerne er det, der siger "tryk her", og de er tegningens ANNOTATIONSLAG.
   Derfor er de signalgule: brandguiden giver gul til markering og understregning,
   aldrig til tekst på lys bund — og en henvisningsprik er præcis en markering.
   Konstruktionen er grøn, annotationen er gul. Det er ikke pynt, det er den
   samme opdeling en byggetegning selv bruger.

   Ringen om kernen er blæk. Den er der, fordi gul på Papir kun er 1,9:1 og
   dermed ikke i sig selv kan identificere en kontrol, jf. WCAG 1.4.11. Blæk på
   Papir er 14:1, så det er ringen der bærer synligheden, og gulen der bærer
   betydningen.

   Punkterne er RIGTIGE <a>-elementer oven på SVG'en, ikke klikbare paths.
   Grunden er ikke smag: et <a> giver fokusring, tastatur, aria-expanded og
   skærmlæser gratis, og — vigtigere her — det kan lyse og pulse, hvilket et
   SVG-element ikke kan lige så let. */
.punkter {
  position: absolute;
  inset: 0;
  /* Eget stakkelag, så et åbent kald kan lægge sig over de andre punkter uden at
     skulle konkurrere med noget uden for tegningen. */
  isolation: isolate;
}

/* Gruppen er NULSTOR og sidder på koordinatet. Alt — prik, streg og kald —
   hænger ud fra dette ene punkt, så de tre altid følger hinanden. En nulstor
   gruppe opsnapper ingen klik; det gør kun børnene. */
.punkt-gruppe {
  position: absolute;
  width: 0;
  height: 0;

  /* Retningen kaldet går ud i. Vinklen og forskydningen hører sammen: kaldets
     nære hjørne ligger 58 px ud og 46 px op, og stregen mellem dem er derfor
     74 px lang med 38,4 graders fald. Ændres det ene, skal det andet med. */
  --streg-vinkel: -38.4deg;
  --kald-ud: 58px;
  --kald-op: 46px;
}

.punkt-gruppe[data-kald='op-venstre'] {
  --streg-vinkel: -141.6deg;
}

.punkt-gruppe[data-kald='ned-hoejre'] {
  --streg-vinkel: 38.4deg;
}

.punkt-gruppe[data-kald='ned-venstre'] {
  --streg-vinkel: 141.6deg;
}

/* Det åbne kald skal ligge over de andre prikker, ellers stikker en nabo-prik
   op gennem kortet. */
.punkt-gruppe:has(.punkt[aria-expanded='true']) {
  z-index: 3;
}

/* Koordinaterne står HER og ikke i style-attributter: CSP'en har
   style-src-attr 'none', så en position sat fra JavaScript ville blive blokeret.

   De er procenter af SVG'ens viewBox, og de er OPTIMEREDE, ikke skønnede: hvert
   punkt er søgt inden for sin egen bygningsdels geometri — en kasse eller et
   linjestykke fra snittet — så den mindste afstand mellem to prikker bliver
   størst mulig.

   Grunden er telefonen. Ved 320 px er tegningen 304 px bred, og de oprindelige
   koordinater gav 36 px mellem tag og ventilation — under klikfladen, så
   varmeanlægget stjal en del af dørens flade. Optimeringen giver 40,0 px, og det
   er det GEOMETRISKE MAKSIMUM for tolv punkter på denne tegning i den bredde.
   46 px er altså umuligt på en 320 px skærm; derfor følger klikfladen pladsen,
   se @media nedenfor. */
.punkt-gruppe[data-punkt='del-ventilation'] { left: 62.61%; top: 23.82%; }
.punkt-gruppe[data-punkt='del-koekken'] { left: 34.11%; top: 39.41%; }
.punkt-gruppe[data-punkt='del-tag'] { left: 16.09%; top: 42.9%; }
.punkt-gruppe[data-punkt='del-ydervaeg'] { left: 81.74%; top: 45.29%; }
.punkt-gruppe[data-punkt='del-etage'] { left: 53.91%; top: 61.76%; }
.punkt-gruppe[data-punkt='del-trappe'] { left: 40.43%; top: 67.06%; }
.punkt-gruppe[data-punkt='del-doer'] { left: 16.96%; top: 68.24%; }
.punkt-gruppe[data-punkt='del-vindue'] { left: 81.74%; top: 69.41%; }
.punkt-gruppe[data-punkt='del-vaadrum'] { left: 65.43%; top: 70.59%; }
.punkt-gruppe[data-punkt='del-varme'] { left: 28.84%; top: 75.88%; }
.punkt-gruppe[data-punkt='del-fundament'] { left: 16.96%; top: 87.48%; }
.punkt-gruppe[data-punkt='del-afloeb'] { left: 67.24%; top: 92.94%; }

/* Prikken. 46 px klikflade om en 14 px synlig kerne: stor nok til en handske,
   lille nok til ikke at dække tegningen. */
.punkt {
  position: absolute;
  left: -23px;
  top: -23px;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.punkt::after {
  content: '';
  position: absolute;
  inset: 16px;
  border-radius: 50%;
  background: var(--signalgul);
  border: 1.5px solid var(--blaek);
  transition: inset 0.16s ease, background-color 0.16s ease, border-width 0.16s ease;
}

/* Lyset. En ring, der breder sig udad og forsvinder — tegningens måde at banke
   på. Forskudt pr. prik, så de tolv ikke pulser i takt: samtidig puls læses som
   en fejl, forskudt puls læses som liv. */
.punkt::before {
  content: '';
  position: absolute;
  inset: 13px;
  border-radius: 50%;
  border: 2px solid var(--signalgul);
  opacity: 0;
  animation: punktpuls 3.4s ease-out infinite;
}

@keyframes punktpuls {
  0% {
    transform: scale(0.62);
    opacity: 0;
  }
  16% {
    opacity: 0.85;
  }
  70% {
    transform: scale(2.4);
    opacity: 0;
  }
  100% {
    transform: scale(2.4);
    opacity: 0;
  }
}

.punkt-gruppe:nth-child(2) .punkt::before { animation-delay: 0.28s; }
.punkt-gruppe:nth-child(3) .punkt::before { animation-delay: 0.56s; }
.punkt-gruppe:nth-child(4) .punkt::before { animation-delay: 0.84s; }
.punkt-gruppe:nth-child(5) .punkt::before { animation-delay: 1.12s; }
.punkt-gruppe:nth-child(6) .punkt::before { animation-delay: 1.4s; }
.punkt-gruppe:nth-child(7) .punkt::before { animation-delay: 1.68s; }
.punkt-gruppe:nth-child(8) .punkt::before { animation-delay: 1.96s; }
.punkt-gruppe:nth-child(9) .punkt::before { animation-delay: 2.24s; }
.punkt-gruppe:nth-child(10) .punkt::before { animation-delay: 2.52s; }
.punkt-gruppe:nth-child(11) .punkt::before { animation-delay: 2.8s; }
.punkt-gruppe:nth-child(12) .punkt::before { animation-delay: 3.08s; }

.punkt:hover::after,
.punkt:focus-visible::after {
  inset: 13px;
  border-width: 2px;
}

/* Den åbne prik er vendt om: blæk kerne i en gul ring. Samme to farver, byttet
   rundt — så det er tydeligt hvilken der er valgt, uden at indføre en tredje
   farve i annotationslaget. Pulsen holder op, for en invitation, man har taget
   imod, skal ikke blive ved med at banke. */
.punkt[aria-expanded='true']::after {
  inset: 12px;
  background: var(--blaek);
  border-color: var(--signalgul);
  border-width: 3px;
}

.punkt[aria-expanded='true']::before {
  animation: none;
  opacity: 0.5;
  transform: scale(2.1);
}

/* ---- Henvisningsstregen ----
   Byggetegningens leader: en tynd, skrå streg fra detaljen ud til kaldet.
   Tegnes fra prikken og udad, så bevægelsen læses som at nogen sætter en
   henvisning på snittet — ikke som at et kort dukker op.

   Blæk og ikke gul: 1 px gul på Papir er 1,9:1 og ville forsvinde. Gulen sidder
   i prikken og i kaldets overkant, hvor den har flade nok til at bære. */
.punkt__streg {
  position: absolute;
  left: 0;
  top: 0;
  width: 74px;
  height: 1px;
  background: var(--blaek);
  transform-origin: left center;
  transform: rotate(var(--streg-vinkel)) scaleX(0);
  opacity: 0;
  pointer-events: none;
}

@keyframes streg-ud {
  from {
    opacity: 0;
    transform: rotate(var(--streg-vinkel)) scaleX(0);
  }
  to {
    opacity: 1;
    transform: rotate(var(--streg-vinkel)) scaleX(1);
  }
}

.punkt[aria-expanded='true'] ~ .punkt__streg {
  animation: streg-ud 0.26s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}

/* ---- Kaldet ----
   Den lille popup ved detaljen: hvad man har trykket på, og hvad man kan spørge
   om. Spørgsmålene står HER og ikke i en boks nede på siden — det var netop
   problemet før: man trykkede, og svaret lå uden for skærmen.

   Gul overkant, fordi kaldet hører til annotationslaget sammen med prikken.
   3 px flade, ikke tekst — det er den brug guiden tillader.

   Skygge er tillladt her: guiden giver netop den ene undtagelse fra "rammer frem
   for skygger" til flydende paneler, og et kald svæver over tegningen. */
.kald {
  position: absolute;
  width: 268px;
  padding: var(--rum-3);
  background: var(--kalk);
  border: 1px solid var(--kant);
  border-top: 3px solid var(--signalgul);
  border-radius: var(--radius-2);
  box-shadow: var(--skygge-2);
  animation: kald-ind 0.24s cubic-bezier(0.2, 0.7, 0.3, 1) 0.14s backwards;
}

.kald[hidden] {
  display: none;
}

/* Kaldet lander i det hjørne, stregen peger mod. De fire varianter er ikke
   valgfrie: prikker øverst i snittet SKAL have kaldet nedad, ellers stikker det
   op over heroens overkant, og prikker i højre halvdel skal have det til
   venstre, ellers ud over sidens bredde. */
.punkt-gruppe[data-kald='op-hoejre'] .kald {
  left: var(--kald-ud);
  bottom: var(--kald-op);
}

.punkt-gruppe[data-kald='op-venstre'] .kald {
  right: var(--kald-ud);
  bottom: var(--kald-op);
}

.punkt-gruppe[data-kald='ned-hoejre'] .kald {
  left: var(--kald-ud);
  top: var(--kald-op);
}

.punkt-gruppe[data-kald='ned-venstre'] .kald {
  right: var(--kald-ud);
  top: var(--kald-op);
}

@keyframes kald-ind {
  from {
    opacity: 0;
    transform: scale(0.94);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.kald__navn {
  margin: 0 0 var(--rum-2);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--beton-tekst);
}

.kald__spoergsmaal {
  display: flex;
  flex-direction: column;
  gap: var(--rum-1);
}

/* Spørgsmålene glider ind ét ad gangen. Forsinkelsen er lille — det skal læses
   som at listen bliver skrevet, ikke som at siden er langsom. */
.kald__spoergsmaal button {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: var(--rum-1) var(--rum-2);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--kalk);
  color: var(--blaek);
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
  animation: kald-linje 0.26s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
  transition: border-color 0.14s ease, background-color 0.14s ease, transform 0.14s ease;
}

@keyframes kald-linje {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.kald__spoergsmaal button:nth-child(1) { animation-delay: 0.24s; }
.kald__spoergsmaal button:nth-child(2) { animation-delay: 0.31s; }
.kald__spoergsmaal button:nth-child(3) { animation-delay: 0.38s; }

.kald__spoergsmaal button:hover {
  border-color: var(--paragrafgroen);
  background: var(--groen-tone);
  transform: translateX(2px);
}

/* Fritekst: "Spørg BR-BygAI om køkkenet …". Formen er en rigtig <form>, så Enter
   virker uden en tastaturlytter. */
.kald__form {
  display: flex;
  gap: var(--rum-1);
  margin-top: var(--rum-2);
  padding-top: var(--rum-2);
  border-top: 1px solid var(--kant);
  animation: kald-linje 0.26s cubic-bezier(0.2, 0.7, 0.3, 1) 0.45s backwards;
}

.kald__felt {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: var(--rum-1);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--kalk);
  color: var(--blaek);
  font-family: inherit;
  /* 16 px eller mere, ellers zoomer iOS ind ved fokus — og et zoom, der sker af
     sig selv, føles som en fejl. */
  font-size: 16px;
}

.kald__felt:focus {
  border-color: var(--paragrafgroen);
  outline: 0;
}

.kald__send {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  min-height: 44px;
  border: 1px solid var(--paragrafgroen);
  border-radius: var(--radius-1);
  background: var(--paragrafgroen);
  color: var(--papir);
  cursor: pointer;
  transition: background-color 0.14s ease;
}

.kald__send:hover {
  background: var(--groen-dyb);
}

.kald__send svg {
  width: 18px;
  height: 18px;
  display: block;
}

/* ---- Vinket ved overskriften ----
   Samme gule prik som på tegningen, samme puls. Vinket og det, det peger på,
   skal være samme sprog. */
.hero__hint {
  display: inline-flex;
  align-items: center;
  gap: var(--rum-2);
  font-size: 14px;
  color: var(--beton-tekst);
}

.hero__hint-prik {
  position: relative;
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--signalgul);
  border: 1.5px solid var(--blaek);
}

.hero__hint-prik::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid var(--signalgul);
  animation: punktpuls 3.4s ease-out infinite;
}

/* ---- Små skærme ----
   Kaldet kan ikke sidde ved prikken på en telefon: 268 px ved en prik i højre
   side ville ryge ud over skærmkanten. Det bliver i stedet et fast panel i
   bunden, hvor det altid er synligt uden at rulle — netop det, der var galt før.

   position: fixed virker her, fordi ingen forælder har en transform. Havde
   .punkter eller .punkt-gruppe haft en, ville fixed blive relativ til DEN og
   panelet lande et tilfældigt sted. */
/* Klikfladen skrumpede til 40 px under 900 px, og det var praecis omvendt af,
   hvad der skulle ske: tegningen bliver meget mindre paa en telefon, saa
   prikkerne rykker taettere sammen.

   MAALT ved 320 px: seks par prikker laa taettere end klikfladen, og ved 390 px
   stjal varmeanlaegget 6,4 px af doerens flade — det vinder, fordi det staar
   senere i DOM'en. En toemrer med handsker trykkede paa doeren og fik varmen.

   46 px holdes derfor paa alle bredder. Kun KERNEN bliver mindre, saa tegningen
   ikke drukner i prikker. */
@media (max-width: 900px) {
  /* Huset bryder ud af wrap-polstringen. Hver px taeller: prikkernes indbyrdes
     afstand skalerer med tegningens bredde, og ved 320 px er forskellen mellem
     288 og 304 px netop forskellen paa 38 og 40 px mellem to prikker. */
  .hus {
    margin-left: calc(var(--rum-4) * -1 + var(--rum-1));
    margin-right: calc(var(--rum-4) * -1 + var(--rum-1));
  }

  .punkt::after {
    inset: 17px;
  }

  .punkt::before {
    inset: 14px;
  }

  .punkt__streg {
    display: none;
  }

  .kald {
    position: fixed;
    left: var(--rum-3);
    right: var(--rum-3);
    /* Hjemmeindikatoren paa iOS er 34 px. Med 16 px laa panelets nederste 18 px i
       den zone, hvor systemet opsnapper opstrygninger, og send-knappen laa paa
       kanten. Komposeren gjorde det allerede rigtigt; kaldet gjorde ikke. */
    bottom: max(var(--rum-3), env(safe-area-inset-bottom));
    top: auto;
    width: auto;
    z-index: 40;
    /* Uden denne fortsaetter rulningen ud i siden bagved. */
    overscroll-behavior: contain;
    max-height: 60vh;
    overflow-y: auto;
  }

  /* Nulstiller de fire retninger. bottom SKAL bruge samme max() som ovenfor,
     ellers ophaever denne regel den og laegger panelet tilbage i
     hjemmeindikatorens zone. */
  .punkt-gruppe[data-kald='op-hoejre'] .kald,
  .punkt-gruppe[data-kald='op-venstre'] .kald,
  .punkt-gruppe[data-kald='ned-hoejre'] .kald,
  .punkt-gruppe[data-kald='ned-venstre'] .kald {
    left: var(--rum-3);
    right: var(--rum-3);
    bottom: max(var(--rum-3), env(safe-area-inset-bottom));
    top: auto;
  }
}

/* Under 380 px kan tolv 46 px klikflader ikke ligge paa tegningen uden at
   overlappe. Det er regnet, ikke skoennet: 40,0 px er maksimum ved 320 px, og
   46 px kraever en tegning paa mindst 350 px, altsaa en skaerm paa ca. 370 px.

   Fladen foelger derfor pladsen. 40 px er stadig over det, prikkerne havde foer
   (36 px med overlap), og de overlapper ikke laengere. Alternativet — at beholde
   46 px og lade dem daekke hinanden — er en flade, der ikke kan rammes. */
@media (max-width: 379px) {
  .punkt {
    left: -20px;
    top: -20px;
    width: 40px;
    height: 40px;
  }

  .punkt::after {
    inset: 14px;
  }

  .punkt::before {
    inset: 11px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hus[data-aktiv] .snit > g,
  .hus[data-aktiv] .snit > g[data-del] {
    transition: none;
    animation: none;
  }

  /* Pulsen væk, men ringen bliver: det er ringen om kernen, ikke bevægelsen, der
     gør prikken synlig. */
  .punkt::before,
  .hero__hint-prik::after {
    animation: none;
    opacity: 0.4;
  }

  .punkt::after,
  .kald,
  .kald__spoergsmaal button,
  .kald__form,
  .kald__send {
    transition: none;
    animation: none;
  }

  .punkt[aria-expanded='true'] ~ .punkt__streg {
    animation: none;
    opacity: 1;
    transform: rotate(var(--streg-vinkel)) scaleX(1);
  }
}

/* =============================================================================
   Kapitelfacade og paragrafkaede
   =============================================================================
   To oversigtstegninger, der viser HVOR svaret bor. Kravkortet viser ét krav;
   disse viser sammenhaengen.

   Samme stregsprog som kravkortet: tynde paragrafgroenne streger, ingen
   fladefarver paa store omraader, tal i blaek med halo saa de kan laeses over en
   streg. non-scaling-stroke er noedvendig — uden den aendrer stregvaegten sig med
   visningsstoerrelsen, og en byggetegnings stregvaegt betyder noget.
   ========================================================================== */

.oversigt {
  display: block;
  width: 100%;
  height: auto;
  margin-top: var(--rum-2);
  background: var(--kalk);
  border: 1px solid var(--kant);
  border-radius: var(--radius-1);
}

.oversigt .tg-snit {
  stroke: var(--paragrafgroen);
  stroke-width: 2;
  stroke-linecap: square;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.oversigt .tg-snit-ramme {
  stroke: var(--paragrafgroen);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.oversigt .tg-hjaelp {
  stroke: var(--beton);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.oversigt .tg-flade {
  fill: var(--groen-tone);
  stroke: none;
}

/* Vejledning er ikke bindende og maa ALDRIG se ud som et krav.
   Signalgul er guidens markering til netop det. */
.oversigt .tg-flade--vejledning {
  fill: var(--gul-tone);
  stroke: none;
}

.oversigt .tg-ramme--vejledning {
  stroke: var(--signalgul);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  fill: none;
}

/* En henvisning til en DS/EN-standard er en ENDESTATION. Kaeden stopper der,
   fordi indholdet ikke maa gengives — og det skal kunne SES paa tegningen. */
.oversigt .tg-flade--licens {
  fill: var(--gul-tone);
  stroke: none;
}

.oversigt .tg-ramme--licens {
  stroke: var(--signalgul);
  stroke-width: 1.5;
  stroke-dasharray: 3 2;
  vector-effect: non-scaling-stroke;
  fill: none;
}

.oversigt .tg-pil {
  fill: var(--paragrafgroen);
  stroke: none;
}

.oversigt .tg-pil--licens {
  fill: var(--signalgul);
  stroke: none;
}

/* Tallene skal kunne laeses OVER en streg. Haloen er en hvid stroke bag
   glyfferne.

   paint-order HOERER TIL HER, ikke i markup.
   SVG tegner som standard stroke OVEN PAA fill, saa en 2,5 px hvid kontur om en
   10 px skrift sluger glyfferne helt — teksten bliver usynlig. Reglen laa
   tidligere som et attribut paa hvert enkelt kald, og ét kaldsted glemte den:
   maalnoderne i paragrafkaeden stod som tomme kasser. Haloen og dens
   tegnerkkefoelge er én egenskab og skal defineres ét sted. */
.oversigt .tg-tal {
  fill: var(--blaek);
  stroke: var(--kalk);
  stroke-width: 2.5;
  paint-order: stroke;
  font-family: inherit;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.oversigt .tg-label {
  fill: var(--beton-tekst);
  font-family: inherit;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.oversigt .tg-note {
  fill: var(--beton-tekst);
  font-family: inherit;
  font-size: 8.5px;
}

/* =============================================================================
   Vedhaeftning
   =============================================================================
   Den valgte fil staar OVER feltet, ikke ved siden af knappen. Grunden er
   mobilen: ved siden af knappen ville filnavnet klemme spoergefeltet sammen paa
   en telefon, og et navn, man ikke kan laese, er det samme som ingen bekraeftelse.
   ========================================================================== */

.vedhaeft {
  display: flex;
  align-items: center;
  gap: var(--rum-1);
  margin-bottom: var(--rum-1);
  padding: var(--rum-1) var(--rum-2);
  /* INGEN gul venstrekant. Signalgul betyder VEJLEDNING, IKKE BINDENDE i dette
     system, og det er dets vigtigste visuelle regel. Genbruges koden til "her er
     din valgte fil", holder den op med at betyde noget. */
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--tavle);
  font-size: 13.5px;
}

.vedhaeft[hidden] {
  display: none;
}

.vedhaeft__ikon {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  color: var(--beton-tekst);
}

.vedhaeft__ikon svg {
  width: 16px;
  height: 16px;
  display: block;
}

.vedhaeft__navn {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--blaek);
}

/* 44 px og ikke 32. Vaerktoejet bruges med handsker, og knappen fjerner det
   foto, brugeren lige har taget. */
.vedhaeft__fjern {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -8px -10px -8px 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--beton-tekst);
  cursor: pointer;
}

.vedhaeft__fjern:hover {
  background: var(--kant);
  color: var(--blaek);
}

.vedhaeft__fjern svg {
  width: 14px;
  height: 14px;
  display: block;
}

/* Mærkatet i svaret: hvad der blev sendt med, og OM det blev laest.
   Blev filen ikke laest, skal det staa i svaret. Et svar, der ser ud som om
   billedet blev laest, naar det ikke blev, er vaerre end en fejlbesked. */
.vedhaeft-maerkat {
  display: inline-flex;
  align-items: center;
  gap: var(--rum-h);
  margin-bottom: var(--rum-2);
  padding: 2px var(--rum-1);
  border: 1px solid var(--groen-tone-kant);
  border-radius: var(--radius-1);
  background: var(--groen-tone);
  font-size: 12px;
  color: var(--beton-tekst);
}

.vedhaeft-maerkat--ulaest {
  border-color: var(--obs-tekst);
  background: var(--gul-tone);
  color: var(--obs-tekst);
}

/* =============================================================================
   Historik — skuffen med samtalerne
   =============================================================================
   En skuffe og ikke en fast kolonne. Grunden er mobilen: vaerktoejet bruges paa
   en byggeplads, og en permanent sidebar ville tage en tredjedel af skaermen fra
   selve svaret. Samme adfaerd paa alle bredder, saa der kun er én tilstand at
   fejlsoege.

   Skygge er tilladt her: brandguiden giver netop den ene undtagelse fra "rammer
   frem for skygger" til flydende paneler.
   ========================================================================== */

/* top: 0 og ikke --appbar-hoejde.
   Tokenet er 60 px, men .top__indhold har flex-wrap og min-height — altsaa en
   MINDSTEhoejde. Regnet: for en logget ind bruger ombryder bjaelken til to
   raekker paa hver telefonbredde, og saa laa skyggen hen over nav-raekken med
   selve Samtaler-knappen. Vejen ud var skjult bag det, der skulle lukkes.

   Skuffen daekker nu bjaelken og har sin egen lukkeknap. Én sandhed i stedet for
   tre hardkodede referencer til et tal, der ikke passer. */
.historik {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: var(--rum-3);
  width: min(340px, 88vw);
  padding: var(--rum-3);
  background: var(--kalk);
  border-right: 1px solid var(--kant);
  box-shadow: var(--skygge-2);
  overflow-y: auto;
  overscroll-behavior: contain;
  animation: skuffe-ind 0.2s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.historik[hidden],
.historik__skygge[hidden] {
  display: none;
}

@keyframes skuffe-ind {
  from {
    transform: translateX(-14px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

/* Skyggen daekker HELE skaermen, og skuffen har sin egen lukkeknap.
   Foerste udgave daekkede kun under topbjaelken for at holde Samtaler-knappen
   synlig — men bjaelken ombryder til to raekker paa telefon, saa skyggen laa hen
   over netop den knap. En lukkeknap i skuffen er den enkle og rigtige loesning. */
.historik__skygge {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 39;
  border: 0;
  padding: 0;
  background: rgba(20, 24, 28, 0.28);
  cursor: pointer;
}

.historik__hoved {
  display: flex;
  align-items: center;
  gap: var(--rum-2);
  padding-bottom: var(--rum-2);
  border-bottom: 1px solid var(--kant);
}

.historik__hoved .label {
  flex: 1 1 auto;
  margin: 0;
}

.historik__luk {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -8px -8px -8px 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--beton-tekst);
  cursor: pointer;
}

.historik__luk:hover {
  background: var(--tavle);
  color: var(--blaek);
}

.historik__luk svg {
  width: 18px;
  height: 18px;
  display: block;
}

.historik__hoved .label {
  margin: 0;
}

.historik__liste {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--rum-h);
  flex: 1 1 auto;
}

/* Hver raekke er to knapper: aabn samtalen, og slet den. De ligger i samme
   raekke, men er hver sin knap — en slette-handling maa aldrig kunne rammes ved
   et uheld, naar man ville aabne. */
/* 8 px og ikke 4 mellem "aabn" og "slet". Sletningen kan ikke fortrydes. */
.historik__raekke {
  display: flex;
  align-items: stretch;
  gap: var(--rum-1);
  border-radius: var(--radius-1);
}

.historik__aabn {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: var(--rum-1) var(--rum-2);
  border: 1px solid transparent;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--blaek);
  font-family: inherit;
  font-size: 14.5px;
  text-align: left;
  cursor: pointer;
  transition: background-color 0.12s ease, border-color 0.12s ease;
}

.historik__aabn:hover {
  background: var(--tavle);
  border-color: var(--kant);
}

/* Den åbne samtale. aria-current er den eneste kilde — ikke en klasse.
   MÅLT: den tonede flade var 1,15:1 mod Kalk og kanten 1,49:1. WCAG 1.4.11
   kræver 3:1 for det, der identificerer en kontrols tilstand — i sollys på en
   telefon kunne man ikke se hvilken samtale der var åben, og man trykkede den
   samme række to gange.

   En paragrafgrøn venstrekant på 3 px giver 7,81:1 og er samtidig systemets eget
   sprog: kanten er reglementets markering, en tonet flade er ikke. */
.historik__aabn[aria-current='true'] {
  background: var(--groen-tone);
  border-color: var(--groen-tone-kant);
  border-left: 3px solid var(--paragrafgroen);
  padding-left: calc(var(--rum-2) - 2px);
  font-weight: 600;
}

.historik__titel {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Dage tilbage, pr. samtale. Loeftet om 30 dage skal staa dér, hvor det gaelder,
   ikke kun i en politik. */
.historik__dage {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--beton-tekst);
}

/* Under fem dage er dette den vigtigste oplysning i skuffen for nogen med en
   byggesag, der har koert i tre uger. */
.historik__dage[data-snart] {
  color: var(--obs-tekst);
  font-weight: 600;
}

/* 44 px. Sletningen er en hard delete med cascade og har ingen fortrydelse —
   det er det daarligste sted at have et lille maal. */
.historik__slet {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px;
  min-height: 44px;
  border: 1px solid transparent;
  border-radius: var(--radius-1);
  background: transparent;
  color: var(--beton-tekst);
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease;
}

/* Obs-familien og ikke gul, af samme grund som ovenfor: gul er vejledning. */
.historik__slet:hover {
  background: var(--obs-tone);
  color: var(--obs-tekst);
}

.historik__slet svg {
  width: 16px;
  height: 16px;
  display: block;
}

.historik__fod {
  flex: 0 0 auto;
  padding-top: var(--rum-2);
  border-top: 1px solid var(--kant);
}

/* Bekraeftelse paa sletning staar i raekken selv, ikke i en dialog. En dialog
   for at slette én samtale er for meget ceremoni; en raekke, der spoerger
   "Slet? Ja / Nej", er lige saa tydelig og kan afbrydes ved at gaa videre. */
/* Omdoebning i raekken. Feltet skal have 16 px, ellers zoomer iOS. */
.historik__omdoebform {
  display: flex;
  gap: var(--rum-1);
  align-items: center;
  width: 100%;
  padding: var(--rum-h) 0;
}

.historik__navnefelt {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 40px;
  padding: var(--rum-1);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--kalk);
  color: var(--blaek);
  font-family: inherit;
  font-size: 16px;
}

.historik__navnefelt:focus {
  border-color: var(--paragrafgroen);
  outline: 0;
}

.historik__bekraeft {
  display: flex;
  align-items: center;
  gap: var(--rum-1);
  width: 100%;
  padding: var(--rum-1) var(--rum-2);
  border: 1px solid var(--obs-tekst);
  border-radius: var(--radius-1);
  background: var(--obs-tone);
  font-size: 13.5px;
  /* Ved 320 px faar teksten under 110 px og ombryder til fem linjer uden dette. */
  flex-wrap: wrap;
}

.historik__bekraeft span {
  flex: 1 1 auto;
}

@media (prefers-reduced-motion: reduce) {
  .historik {
    animation: none;
  }
}

/* =============================================================================
   Tilbud om konto — dialogen ved det gratis loft
   =============================================================================
   Et flydende lag, så skygge er tilladt her. Brandguiden 1.1 giver netop den ene
   undtagelse fra "rammer frem for skygger": flydende paneler.
   ========================================================================== */

.tilbud {
  max-width: 520px;
  width: calc(100% - var(--rum-4));
  padding: var(--rum-4);
  border: 1px solid var(--kant);
  border-radius: var(--radius-3);
  background: var(--kalk);
  color: var(--blaek);
  box-shadow: var(--skygge-2);

  /* Dialogen bærer nu oprettelsesformularen og kan derfor blive højere end
     skærmen — især på en telefon i landskab, som er byggepladsens format.
     Uden dette blev knappen "Opret konto" klippet af uden nogen måde at nå den.
     dvh frem for vh: vh regner med adressefeltet skjult, og det er det ikke. */
  max-height: 90dvh;
  overflow-y: auto;
}

/* Fallback for browsere uden dvh. Det er @supports-betingelsen — ikke
   rækkefølgen — der holder den ude, hvor dvh findes. */
@supports not (height: 1dvh) {
  .tilbud {
    max-height: 90vh;
  }
}

.tilbud::backdrop {
  background: rgba(20, 24, 28, 0.45);
}

.tilbud__luk {
  float: right;
  margin: calc(var(--rum-2) * -1) calc(var(--rum-2) * -1) 0 0;
}

/* Lukkeknappen må ikke se ud som handlingen. Den er en udvej, ikke et valg.
   --stille aendrer FARVE, ikke stoerrelse. Den satte 40x40 og overskrev
   .ikonknap's 48x48, fordi den staar senere — saa vedhaeft-knappen blev mindre
   end send-knappen lige ved siden af. */
.ikonknap--stille {
  background: transparent;
  border-color: transparent;
  color: var(--beton-tekst);
}

.ikonknap--stille:hover:not(:disabled) {
  background: var(--tavle);
  border-color: var(--kant);
  color: var(--blaek);
}

.tilbud__punkter {
  margin: var(--rum-3) 0 0;
  padding: 0;
  list-style: none;
}

/* Border-top med :first-child-undtagelse giver skillelinjer MELLEM punkter uden
   en linje i toppen og bunden. Ingen ikoner, ingen flueben — strukturen bærer. */
.tilbud__punkter li {
  padding: var(--rum-2) 0;
  border-top: 1px solid var(--kant);
  font-size: 15px;
}

.tilbud__punkter li:first-child {
  border-top: 0;
}

/* Frivillige felter, sammenfoldet.
   Ingen pilrotation og ingen animation: brandguiden vil rammer frem for effekter,
   og en <details> siger sin tilstand selv. Kun markøren og en kant, der viser at
   det kan klikkes. */
.tilbud__frivilligt {
  margin-top: var(--rum-3);
  border-top: 1px solid var(--kant);
  border-bottom: 1px solid var(--kant);
}

.tilbud__frivilligt > summary {
  padding: var(--rum-2) 0;
  cursor: pointer;
  font-size: 15px;
  color: var(--beton-tekst);
}

/* Fokusringen skal være synlig — en <summary> er tastaturens vej ind her. */
.tilbud__frivilligt > summary:focus-visible {
  outline: 2px solid var(--paragrafgroen);
  outline-offset: 2px;
}

.tilbud__frivilligt[open] > summary {
  color: var(--blaek);
  border-bottom: 1px solid var(--kant);
  margin-bottom: var(--rum-2);
}

.tilbud__frivilligt > *:last-child {
  margin-bottom: var(--rum-2);
}

@media (max-width: 700px) {
  .tilbud {
    padding: var(--rum-3);
  }
}

/* =============================================================================
   Faner og formularfelter — login-siden
   ============================================================================= */

/* Tilstanden bor i aria-selected, og CSS'en læser attributten. Ingen
   .active-klasse, der kan komme ud af trit med tilgængeligheden. */
.faner {
  display: flex;
  gap: var(--rum-1);
  border-bottom: 1px solid var(--kant);
}

.fane {
  min-height: 48px;
  padding: var(--rum-2) var(--rum-3);
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--radius-2) var(--radius-2) 0 0;
  background: transparent;
  color: var(--beton-tekst);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  /* Trækker den valgte fane ned over sektionslinjen, så den hænger sammen med
     panelet under. */
  margin-bottom: -1px;
}

.fane[aria-selected='true'] {
  background: var(--kalk);
  border-color: var(--kant);
  border-bottom-color: var(--kalk);
  color: var(--blaek);
}

.fane:hover:not([aria-selected='true']) {
  color: var(--blaek);
}

.felt {
  display: grid;
  gap: var(--rum-h);
  margin-bottom: var(--rum-3);
}

.felt label {
  font-size: 15px;
  font-weight: 600;
  color: var(--blaek);
}

.felt input,
.felt select {
  min-height: 48px;
  padding: var(--rum-2) var(--rum-2);
  border: 1px solid var(--kant-kontrol);
  border-radius: var(--radius-1);
  background: var(--kalk);
  color: var(--blaek);
  font-family: inherit;
  /* 16 px eller mere. Under det zoomer iOS ind på feltet ved fokus, og så
     sidder halvdelen af formularen uden for skærmen. */
  font-size: 16px;
  width: 100%;
}

.felt input:focus,
.felt select:focus {
  border-color: var(--paragrafgroen);
}

.felt__hjaelp {
  margin: 0;
  font-size: 13.5px;
  color: var(--beton-tekst);
  max-width: var(--laese-bredde);
}

.felt__frivillig {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--beton-tekst);
  padding-left: var(--rum-h);
}

/* align-items: flex-start, så afkrydsningen flugter med FØRSTE tekstlinje og
   ikke med blokkens midte. Samtykketekster er tre linjer lange. */
.samtykke {
  display: flex;
  align-items: flex-start;
  gap: var(--rum-2);
  margin-bottom: var(--rum-3);
  padding: var(--rum-2);
  background: var(--tavle);
  border: 1px solid var(--kant);
  border-radius: var(--radius-1);
}

.samtykke input[type='checkbox'] {
  width: 22px;
  height: 22px;
  margin-top: 2px;
  flex: none;
  accent-color: var(--paragrafgroen);
}

.samtykke label {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--blaek);
}

/* Kvittering. Paragrafgrøn kant, fordi den bekræfter noget — modsat .advarsel,
   der har Obs-kant. De to må ikke se ens ud. */
.kvittering {
  margin: 0;
  padding: var(--rum-2) var(--rum-3);
  border: 1px solid var(--kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 0 var(--radius-1) var(--radius-1) 0;
  background: var(--groen-tone);
  font-size: 15.5px;
  color: var(--blaek);
  max-width: var(--laese-bredde);
}

.kvittering[hidden],
.advarsel[hidden] {
  display: none;
}

/* ---------- AI-mærkat ---------- */

.ai-maerkat {
  display: inline-flex;
  align-items: center;
  gap: var(--rum-h);
  padding: 3px var(--rum-1);
  border: 1px solid var(--kant);
  border-radius: var(--radius-1);
  background: var(--tavle);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--beton-tekst);
  white-space: nowrap;
}

/* ---------- Ansvarsbjælke ---------- */

/* Permanent forbehold i chat-appen. Den, der bogmærker /app, så ellers
   aldrig forbeholdet — det stod kun på landingssiden. */
.ansvarsbjaelke {
  border: 1px solid var(--kant);
  border-left: 3px solid var(--paragrafgroen);
  border-radius: 0 var(--radius-1) var(--radius-1) 0;
  background: var(--tavle);
  padding: var(--rum-2) var(--rum-3);
  font-size: 14.5px;
  color: var(--blaek);
  max-width: none;
}

/* ---------- Tillidsmodul ---------- */

.tillid {
  display: grid;
  gap: var(--rum-3);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.tillid__punkt {
  border: 1px solid var(--kant);
  border-top: 2px solid var(--paragrafgroen);
  border-radius: 0 0 var(--radius-2) var(--radius-2);
  background: var(--kalk);
  padding: var(--rum-3);
}

.tillid__punkt h3 {
  margin-bottom: var(--rum-h);
  font-size: 16px;
}

.tillid__punkt p {
  margin: 0;
  font-size: 15px;
  color: var(--beton-tekst);
}

/* ---------- Fod ---------- */

.fod {
  background: var(--blaek);
  color: var(--papir);
  padding: var(--rum-6) 0;
}

.fod a {
  color: var(--papir);
}

.fod a:hover {
  color: var(--signalgul);
}

.fod .logo,
.fod .logo__ord {
  color: var(--papir);
}

/* Første § i det mørke logo skal være papirfarvet for at have kontrast. */
.logo--paa-moerk .logo__maerke span:first-child {
  color: var(--papir);
}

.logo--paa-moerk .logo__undertekst {
  color: var(--kant);
}

.fod__note {
  font-size: 14px;
  color: var(--kant); /* på Blæk: 12,3:1 — inden for paletten */
  max-width: var(--laese-bredde);
  margin-top: var(--rum-3);
}

/* ---------- Hjælpeklasser ----------
   Findes fordi CSP'en forbyder inline styles (style-src-attr 'none'). Brugte
   siderne style="..."-attributter, ville de blive blokeret i produktion — og
   den nemme "løsning" ville være at tillade unsafe-inline, hvorefter
   beskyttelsen mod injiceret CSS er væk. Derfor: klasser her. */

.mt-1 { margin-top: var(--rum-1); }
.mt-2 { margin-top: var(--rum-2); }
.mt-3 { margin-top: var(--rum-3); }
.mt-4 { margin-top: var(--rum-4); }
.mt-5 { margin-top: var(--rum-5); }
.mb-1 { margin-bottom: var(--rum-1); }
.mb-2 { margin-bottom: var(--rum-2); }
.mb-3 { margin-bottom: var(--rum-3); }
.mb-4 { margin-bottom: var(--rum-4); }

.tekst-obs { color: var(--obs-tekst); }
.tekst-beton { color: var(--beton-tekst); }

/* Landingssidens eksempel genbruger .traad__indhold inde i .wrap.
   Uden padding-nulstillingen lagde begge vandret luft på, så eksemplet blev
   smallere end resten. Og uden margin-left: 0 centrerede blokken sig selv inde
   i .wrap — målt i runde 1 var eksemplet forskudt 78 px ved 1024 og 126 px ved
   1440 fra sin EGEN sektionsoverskrift. */
.wrap > .traad__indhold {
  padding-left: 0;
  padding-right: 0;
  margin-left: 0;
}

/* Fremdrift til skærmlæseren. Vises også visuelt, fordi en linje der siger
   hvad der sker, er bedre end en prik der pulserer. */
.komposer__status {
  margin: var(--rum-1) 0 0;
  min-height: 1.4em;
  font-size: 13px;
  color: var(--beton-tekst);
  max-width: none;
}

/* pre-wrap på .tur__tekst er NØDVENDIG for modeltekst, som kan indeholde
   linjeskift. Men den rammer også håndskrevet HTML: målt i runde 1 gav
   landingssidens eksempel en blank førstelinje, ~90 px indrykning og tre hårde
   linjeskift, fordi indrykningen i kilden blev bevaret. Statisk tekst får
   derfor almindelig ombrydning. */
.tur__tekst--statisk {
  white-space: normal;
}

/* Chippen i landingssidens eksempel er en visning, ikke en kontrol. Målt i
   runde 1: den var en <span> med cursor: pointer, tabIndex -1 og intet
   aria-expanded — den så klikbar ud, kunne ikke få fokus og gjorde ingenting.
   En falsk affordance på det element, hele produktet handler om, er værre end
   ingen chip. */
.chip--statisk {
  cursor: default;
}

/* =============================================================================
   Tilpasning til skærmstørrelse
   =============================================================================
   Reglerne ovenfor er alle enkolonne eller auto-fit-gitre, så de virker i sig
   selv på lille skærm. Herunder justeres luft, skriftstørrelser og
   kolonnetællinger — plus de ting, der KUN gælder berøring.
   ========================================================================== */

/* ---- iPad og andre tablets: 700–1100 px ----
   Auto-fit-gitrene ville her presse tre og fire kolonner ind på en bredde,
   der kun har plads til to. Sat eksplicit i stedet for at lade minmax gætte. */
@media (min-width: 701px) and (max-width: 1100px) {
  .sektion {
    padding: var(--rum-7) 0;
  }

  .gitter,
  .tillid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* iPad i portræt er 768 px bred. Tråden er 820 px, så den ville ellers ligge
   klemt helt ud til begge kanter. */
@media (min-width: 701px) and (max-width: 860px) {
  .traad__indhold,
  .komposer__indhold {
    max-width: 100%;
  }
}

/* ---- Telefon: under 700 px ---- */
@media (max-width: 700px) {
  body {
    font-size: 16px;
  }

  .wrap,
  .traad__indhold,
  .komposer__indhold {
    padding-left: var(--rum-3);
    padding-right: var(--rum-3);
  }

  .wrap > .traad__indhold {
    padding-left: 0;
    padding-right: 0;
  }

  .sektion {
    padding: var(--rum-6) 0;
  }

  .top__nav {
    gap: var(--rum-2);
    font-size: 14px;
  }

  .logo__maerke {
    font-size: 24px;
  }

  .logo__ord {
    font-size: 19px;
  }

  .svarkort {
    padding: var(--rum-3);
  }

  .lovtekst {
    padding: var(--rum-2) var(--rum-3);
  }

  .tur--bruger .tur__tekst {
    max-width: 100%;
  }

  /* Et forslag pr. linje. Fire knapper med lang tekst side om side blev
     ulæselige stumper på 360 px. */
  .opfoelg {
    flex-direction: column;
    align-items: stretch;
  }

}

/* ---- Topbjælken må aldrig ombryde til to rækker ----
   Målt i runde 1 med headless Chrome: bjælken var 109 px høj ved 430 px og
   112 px ved 768 px, mod tokenet --appbar-hoejde på 60 px. Ved 768 px fyldte
   logo 340 px + nav 395 px + 16 px gap = 751 px mod 720 px til rådighed.
   De to bredder er iPhone Pro Max og iPad i portræt.

   Konsekvensen var værst på app-fladen, hvor bjælken er en grid-række: den tog
   13,6 % af skærmen, før brugeren havde skrevet noget.

   Undertitlen er den længste del af logoet, så den ryger først. Er der stadig
   for lidt plads, ryger de sekundære links, og kun logo og knap står tilbage. */
@media (max-width: 780px) {
  .logo__undertekst {
    display: none;
  }
}

@media (max-width: 560px) {
  .top__nav a:not(.knap) {
    display: none;
  }
}

/* ---- Berøring ----
   På en touch-skærm findes der ingen markør, der kan forlade et element, så
   :hover bliver hængende efter et tryk: knappen bliver ved med at se
   "aktiveret" ud, længe efter fingeren er væk. Basisudseendet gendannes her.
   :focus-visible og aria-expanded bærer stadig tilstanden. */
@media (hover: none) {
  .knap:hover:not(:disabled) {
    background: var(--paragrafgroen);
    border-color: var(--paragrafgroen);
  }

  .knap--sekundaer:hover:not(:disabled) {
    background: var(--kalk);
    color: var(--paragrafgroen);
  }

  .knap--stille:hover:not(:disabled) {
    background: transparent;
    border-color: var(--kant);
  }

  .ikonknap:hover:not(:disabled) {
    background: var(--paragrafgroen);
    border-color: var(--paragrafgroen);
  }

  .chip:hover:not([aria-expanded='true']) {
    border-color: var(--kant-kontrol);
    background: var(--kalk);
  }

  .opfoelg__knap:hover {
    border-color: var(--kant-kontrol);
    background: var(--kalk);
  }

  .top__nav a:not(.knap):hover {
    color: var(--blaek);
    text-decoration: none;
  }
}

/* Brugere, der zoomer, eller som har sat en stor systemskrift, skal stadig
   kunne nå komposeren. Er der under 420 px lodret plads, må tråden hellere
   blive lille end at komposeren skubbes ud af skærmen. */
@media (max-height: 420px) {
  .traad {
    padding-top: var(--rum-2);
  }

  .velkomst {
    padding-top: var(--rum-2);
  }
}

/* ---- Ejendomskort: lokalplanen for en adresse ----
   Registerdata fra Plandata, IKKE reglementstekst.

   Derfor blaek-ramme og ikke paragrafgroen: i dette system betyder groen
   bindende reglementstekst (.lovtekst), og signalgul betyder vejledning. En
   lokalplan er kommunens egen forskrift, der gaelder ved siden af BR18 — den
   maa ikke se ud som en BR18-bestemmelse, og den maa ikke se ud som
   vejledning. Den er en tredje ting, og den skal se ud som en tredje ting. */
.ejendom {
  margin-top: var(--rum-3);
  padding: var(--rum-3);
  border: 1px solid var(--blaek);
  border-radius: 4px;
  background: var(--papir);
}

.ejendom__hoved {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--rum-2);
}

.ejendom__adresse {
  font-weight: 600;
  color: var(--blaek);
}

.ejendom__besked {
  margin: var(--rum-2) 0 0;
  font-size: 14.5px;
  color: var(--beton-tekst);
}

.ejendom__plan {
  margin-top: var(--rum-2);
  padding-top: var(--rum-2);
  border-top: 1px solid var(--kant);
}

.ejendom__plannavn {
  margin: 0;
  font-weight: 600;
}

.ejendom__tal {
  margin: var(--rum-1) 0 0;
  padding-left: var(--rum-3);
  font-size: 14.5px;
}

.ejendom__dok {
  display: inline-block;
  margin-top: var(--rum-2);
  font-size: 14.5px;
}

.ejendom__note {
  margin: var(--rum-2) 0 0;
  padding-top: var(--rum-2);
  border-top: 1px solid var(--kant);
  font-size: 13px;
  color: var(--beton-tekst);
}

/* Antagelsen om adressen. Skal LAESES, ikke opdages — svarer vi om en anden
   grund end den, brugeren tror, skal han kunne se det med det samme. */
.ejendom__antagelse {
  margin: var(--rum-2) 0 0;
  padding-left: var(--rum-2);
  border-left: 3px solid var(--signalgul);
  font-size: 14.5px;
}

/* ---- Relaterede guider ----
   Den interne linkstruktur, maalt frem: 10 af 18 artikler havde ingen
   indgaaende links fra andre artikler og var kun naaelige fra hubben. Baade en
   soegemaskine og en laeser, der er landet midt i emnet, har brug for vejen
   videre. Diskret ramme — det er en henvisning, ikke en handling. */
.relateret {
  padding: var(--rum-3);
  border: 1px solid var(--kant);
  border-radius: 4px;
  background: var(--kalk);
}

/* ---- Tabel ----
   Bruges paa vilkaarssiden til at vise formaal og retsgrundlag pr. oplysning.
   En tabel er det rigtige her: fire faste kolonner om syv datatyper laeses
   hurtigere end syv afsnit, og GDPR art. 13's oplysningspligt kan efterproeves
   raekke for raekke.

   Rammen ruller VANDRET paa lille skaerm frem for at braekke siden. Reglen fra
   16.4-arbejdet gaelder ogsaa i CSS: indholdet maa ikke tvinge body til at
   rulle sidevaerts. */
.tabelramme {
  overflow-x: auto;
  border: 1px solid var(--kant);
  border-radius: 4px;
}

.tabel {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
  min-width: 520px;
}

.tabel th,
.tabel td {
  padding: var(--rum-2);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--kant);
}

.tabel thead th {
  background: var(--kalk);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--beton-tekst);
}

.tabel tbody tr:last-child th,
.tabel tbody tr:last-child td {
  border-bottom: 0;
}

/* ---- Tilbagemeldings-knappen ----
   Flyder i nederste hoejre hjoerne, saa den er naaelig fra alle sider uden at
   staa i vejen for indholdet. Diskret som standard; det er en vej ud, ikke en
   opfordring.

   Radius 4 px og 1 px kant, jf. brandguiden — ingen pill-form, ingen skygge
   ud over den, et flydende panel maa have. */
.tilbagemeld-knap {
  position: fixed;
  right: var(--rum-3);
  bottom: var(--rum-3);
  z-index: 40;
  padding: 10px 14px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--blaek);
  background: var(--papir);
  border: 1px solid var(--kant);
  border-radius: 4px;
  box-shadow: 0 2px 8px rgb(20 24 28 / 12%);
  cursor: pointer;
}

.tilbagemeld-knap:hover {
  border-color: var(--paragrafgroen);
  color: var(--paragrafgroen);
}

/* I chat-appen ligger komposeren i bunden. Knappen loeftes, saa den ikke
   daekker sendeknappen paa telefon. */
.app .tilbagemeld-knap {
  bottom: auto;
  top: calc(var(--rum-3) + 52px);
}

@media (max-width: 640px) {
  .tilbagemeld-knap {
    right: var(--rum-2);
    bottom: var(--rum-2);
    padding: 8px 12px;
    font-size: 12.5px;
  }
  .app .tilbagemeld-knap {
    top: auto;
    bottom: calc(var(--rum-2) + 64px);
  }
}

.tilbagemeld {
  max-width: 34rem;
}

.tilbagemeld__slags {
  margin: var(--rum-3) 0 0;
  padding: 0;
  border: 0;
}

.tilbagemeld__valg {
  display: flex;
  align-items: center;
  gap: var(--rum-1);
  margin-top: var(--rum-1);
  font-size: 15px;
  cursor: pointer;
}

.tilbagemeld__form textarea {
  width: 100%;
  font: inherit;
  padding: 10px 12px;
  color: var(--blaek);
  background: var(--papir);
  border: 1px solid var(--kant);
  border-radius: 4px;
  resize: vertical;
}

.tilbagemeld__form textarea:focus-visible {
  outline: 2px solid var(--paragrafgroen);
  outline-offset: 1px;
}
