/* Grundviden designtokens + delte komponenter (start på det fælles designsystem,
   jf. docs/SOEG-PLAN.md 9b). Første forbruger: /soeg. Paletten er sitets eksisterende
   (Index/Kort); nye sider bruger tokens herfra i stedet for at redeklarere.
   Komponent-præfiks: .gv- (delt), .gvc- (card-dele). */

/* hidden-attributten SKAL vinde over komponenters display (fx .gv-chip's inline-flex) -
   ellers "forsvinder" elementer ikke når JS sætter hidden (områdechippen 24.07). */
[hidden] { display:none !important; }

:root { color-scheme: light dark;
    /* White ground + sharpened green since 11.08.2026 (the boligsiden-inspired redesign round,
       approved on the /design/forside.html mock). The warm paper #fbfbf9 lives on as --panel for
       quiet fills (ad cards, footers) instead of tinting every page. */
    --bg:#fff; --fg:#1a1a17; --muted:#6f6f60; --line:#e7e5e0;
    --panel:#f7f6f3;
    --card:#fff; --accent:#166534; --accentbg:#e7f3ea;
    /* Text ON an --accent fill. It cannot be a fixed white: --accent is a DARK green in this theme
       and a PALE one in the dark theme, so white gives 7,76:1 here and 1,65:1 there, against a 4,5:1
       minimum - which is how the ejendomsrapport button became unreadable in dark mode (Jonas,
       02.08.2026). Pairing the two colours in the theme block is what stops them drifting apart. */
    --paa-accent:#fff;
    --pos:#2f7d22; --posbg:#e4efdd; --neg:#c05621; --negbg:#f7e8dc;
    --warn:#8a6d1a; --warnbg:#f7efd8;
    --radius:12px; --radius-s:8px; --skygge:0 8px 28px rgba(0,0,0,.16);
    /* Elevation for resting cards (07.08.2026). Hairline-border-on-everything is the
       generated-dashboard look; a card that matters gets a whisper of shadow instead. */
    --skygge-let:0 1px 2px rgba(26,26,23,.05), 0 5px 16px rgba(26,26,23,.06);
}
@media (prefers-color-scheme: dark) { :root {
    --bg:#14140f; --fg:#ededdf; --muted:#9a9a86; --line:#33332a;
    --panel:#1e1e17;
    --card:#1c1c16; --accent:#a9d68f; --accentbg:#1f2c17;
    --paa-accent:#14140f;   /* 11,17:1 on the pale accent - see the light theme for why this pairs */
    --pos:#8fc573; --posbg:#20301a; --neg:#e0955c; --negbg:#332216;
    --warn:#d9b95c; --warnbg:#2c2510;
    --skygge:0 8px 28px rgba(0,0,0,.5);
    --skygge-let:0 1px 2px rgba(0,0,0,.3), 0 5px 16px rgba(0,0,0,.25);
} }

/* ---------------------------------------------------------------------------
   BASE LAYER (27.07.2026). The handful of rules every page carried its own copy of, because
   a new page is made by copying an old one. 85 copies across 33 pages removed.

   WHAT IS DELIBERATELY NOT HERE is the more useful half of this comment. Hoisting
   `body`, `h1`, `h2`, `.wrap`, `table`, `th`, `td` was tried first and BROKE 6 of 29 pages:
   the report page gained padding and heading spacing it never had, three table pages
   shifted. `th.num`/`td.num` was tried next and still moved two statistik pages - they use
   `class="num"` cells they never styled, so a rule here would have RIGHT-ALIGNED numbers
   that were left-aligned before. Arguably an improvement, but not a silent one.

   Two things make a rule unsafe to put here, and neither is visible in the CSS text:
   1. It reaches pages that never declared it. Whether that matters depends on whether the
      page contains the element at all, which no static check can see.
   2. gv.css loads FIRST, so a page normally wins - but only at equal specificity. A more
      specific selector here (`td.num`) beats a page's `.num` regardless of order.
   So the rule for this block is narrow: our own classes, or a single inherited property,
   never anything that sizes or spaces a box. Verified by pixels, not by reasoning -
   tools/visual.sh over the reachable pages is what says this changed nothing.

   THE VALUES BELOW ARE THE ADDRESS PAGE'S (27.07.2026, Jonas' call, and the direction is
   the whole point). The first version took the values MOST content pages happened to use -
   design by majority vote among the pages he likes least, which bakes mediocrity in as the
   baseline and means improving the address page propagates nowhere. Now the best page IS
   the baseline: make the address page nicer and school, kommune, lejlighed and admin follow.
   Not the FRONT page's values, though - it is deliberately a landing page (hero h1 at
   2.1rem, narrower .wrap, more top padding) and keeps its own overrides. Hoisting those
   would have made every page look like a landing page, which is not the same as consistent.
   Solgt.cshtml and Prisudvikling.cshtml likewise keep their own body/html rules, because a
   full-screen map needs height:100% - layout mechanics, not styling.

   THIS COMMENT ONCE CLOSED TEN LINES EARLY BY ACCIDENT, and that cost more than any rule in
   the block (27.07.2026). The remaining prose became CSS tokens: the parser read it as one
   long invalid selector, ran on until the next opening brace, and DROPPED THE RULE IT FOUND
   THERE - the box-sizing:border-box line just below. Every page linking this file rendered
   content-box for 61 minutes in production (415f527 18:37 to 5a8dcaf 19:38), including the
   address page, which had just had its own copy removed as redundant. Nothing saw it. The build is not involved, gv-doctor read the file as text,
   and tools/visual.sh was told via EXPECT that the address page was allowed to change - the
   gate was off for precisely the page that broke. gv-doctor now rejects a comment-close token
   that closes nothing, and any selector running over five lines - see tjek_css_kommentarer,
   which covers this file and all 39 inline style blocks. Proven by breaking it: reinstating
   the early close reports this exact line.
   Do not write that token inside a comment when describing this - the first draft of this
   paragraph quoted it literally and reopened the very hole it documents.
   --------------------------------------------------------------------------- */
* { box-sizing:border-box; }
body { margin:0; padding:1.5rem 1.25rem 4rem; background:var(--bg); color:var(--fg);
    font:16px/1.6 "Source Sans 3",system-ui,-apple-system,Segoe UI,Roboto,sans-serif; }
/* The brand punkt: the green square dot after the wordmark ("grundviden."). An inline-block so it
   baseline-aligns like punctuation wherever the wordmark is written. */
.pkt { display:inline-block; width:.3em; height:.3em; background:var(--accent);
    border-radius:22%; margin-left:.12em; }

/* House-ad card, shared by the front page rail and the address page (Pages/Shared/_Annonce.cshtml
   owns the markup and the reasoning). Never in print - an ad on a printed ejendomsrapport reads
   as endorsement. */
.annonce { background:var(--panel); border:1px solid var(--line); border-radius:12px;
    padding:1.1rem 1.2rem; position:relative; }
.ann-maerke { position:absolute; top:.65rem; right:.9rem; font-size:.66rem; font-weight:700;
    text-transform:uppercase; letter-spacing:.06em; color:var(--muted); opacity:.8; }
.ann-ill { width:42px; height:42px; color:var(--accent); }
.ann-rubrik { font-family:"Source Serif 4", Georgia, serif; font-weight:700; font-size:1.16rem;
    margin:.4rem 0 .35rem; line-height:1.25; color:var(--fg); }
.ann-tekst { margin:0 0 .9rem; font-size:.89rem; color:var(--muted); }
.ann-cta { display:inline-block; background:var(--accent); color:var(--paa-accent); font-weight:700;
    font-size:.9rem; padding:.55rem 1.05rem; border-radius:10px; text-decoration:none; }
.ann-hvem { display:block; margin-top:.75rem; font-size:.8rem; font-weight:700; color:var(--fg); }
@media print { .annonce { display:none !important; } }
a { color:var(--accent); }
.wrap { max-width:54rem; margin:0 auto; }
/* THE HEADING FACE (07.08.2026, Jonas' call after "looks like an AI project" feedback). Source
   Serif 4 for headings and the wordmark ONLY - body text stays system-ui for speed and density.
   Self-hosted (approved download, 122 KB latin woff2, covers æøå), path-versioned like every
   other font. A serif display face is the single cheapest way OFF the generated-dashboard look,
   which is precisely a site set entirely in the browser's default sans.
   The fallback chain is serif on purpose: if the file fails, headings degrade to Georgia rather
   than silently becoming the body font again - a visible failure is a fixable one. */
@font-face {
    font-family: "Source Serif 4";
    src: url("/fonts/source-serif-4-v14/latin-600-700.woff2") format("woff2");
    font-weight: 600 700; font-style: normal; font-display: swap;
}
/* THE BODY FACE (11.08.2026, same redesign round). Source Sans 3 - drawn by the same designer as
   the serif above, so the pairing is by construction rather than by taste. Variable weight axis in
   one 28 KB latin file, real tabular figures. The system-ui stack stays as fallback: a failed font
   load degrades to exactly what the site looked like before, which is the safe direction. */
@font-face {
    font-family: "Source Sans 3";
    src: url("/fonts/source-sans-3-v19/latin-200-900.woff2") format("woff2");
    font-weight: 200 900; font-style: normal; font-display: swap;
}
h1 { font-size:1.7rem; letter-spacing:-.01em; margin:0 0 .25rem;
    font-family:"Source Serif 4", Georgia, serif; font-weight:600; }
h2 { font-size:1.15rem; margin:2rem 0 .8rem; padding-top:1rem; border-top:1px solid var(--line);
    font-family:"Source Serif 4", Georgia, serif; font-weight:600; }
.sub { color:var(--muted); margin:0 0 1.2rem; }
.crumb { font-size:.85rem; margin:0 0 1rem; }
.crumb a { color:var(--accent); }
.kilde { color:var(--muted); font-size:.78rem; }
footer { margin-top:3rem; padding-top:1.2rem; border-top:1px solid var(--line);
    color:var(--muted); font-size:.82rem; }
footer a { color:var(--accent); }
table { width:100%; border-collapse:collapse; font-size:.95rem; }
th, td { padding:.45rem .6rem; border-bottom:1px solid var(--line); text-align:left; vertical-align:top; }
/* Numbers line up under each other and never wrap. Note this RIGHT-ALIGNS `class="num"`
   cells on pages that never styled them - a deliberate consistency change, not a no-op. */
th.num, td.num { text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; }

/* Shared page components (27.07.2026). These are not base elements but small blocks that
   several pages had each built their own copy of, in 2-5 variants. Since Jonas' reference
   surfaces are the front page, the address page and the map popup - none of which use these -
   the variants were collapsed onto the most common one rather than preserved. The point is
   that a key figure looks like a key figure everywhere, not that no page moved. */

/* Key figures ("1.248.941 m2" over a caption), 5 pages. */
.noegle { display:flex; gap:1.6rem; flex-wrap:wrap; margin:.5rem 0 0; }
.noegle b { display:block; font-size:1.9rem; color:var(--accent); letter-spacing:-.01em;
    /* The serif face and TABULAR figures: a KPI number is the page's typography doing the
       talking, and proportional system-ui digits jitter in width between tiles. */
    font-family:"Source Serif 4", Georgia, serif; font-weight:600; font-variant-numeric:tabular-nums; }
.noegle span { font-size:.8rem; color:var(--muted); }

/* Horizontal bar with a label and a value, 4 pages. */
.vbar { display:grid; grid-template-columns:5.5rem 1fr 6.5rem; gap:.5rem; align-items:center;
    font-size:.85rem; margin:.15rem 0; }
.vbar .track { background:var(--accentbg); border-radius:4px; height:.9rem; }
.vbar .fill { display:block; background:var(--accent); opacity:.7; height:100%; border-radius:4px; }
/* The label and value columns lived in the kommune page's own sheet until 14.08.2026, so the
   town page's first bar chart rendered with an unstyled label and a left-aligned figure. Three
   parts of one component in two files is how the fourth consumer gets a broken one. */
.vbar .lab { color:var(--muted); }
.vbar .b { text-align:right; font-variant-numeric:tabular-nums; }

/* Up/down. Deliberately NOT --pos/--neg: these mark direction of change, not good/bad.
   The weight is here on purpose. Collapsing the four variants onto the most common one
   dropped the bold from the "Loefteevne" column on the school pages, which is the column
   the whole table is sorted by - so the EXPRESSIVE variant won, not the commonest. */
.op, .ned { font-weight:600; }
.op { color:#3a9d3a; }
.ned { color:#c33b32; }

.muted { color:var(--muted); font-size:.9rem; }
.lead { color:var(--muted); margin:0 0 1.2rem; }

/* The compact "trivia" table: first column is a muted label, the rest are right-aligned
   numbers. Unanimous across the 3 pages that had it - nothing had to be chosen. */
table.triv { width:100%; border-collapse:collapse; font-size:.9rem; margin-top:.4rem; }
table.triv th, table.triv td { padding:.4rem .5rem; border-bottom:1px solid var(--line);
    text-align:right; white-space:nowrap; }
table.triv th:first-child, table.triv td:first-child { text-align:left; color:var(--muted); font-weight:400; }
thead th, table.triv thead th { font-weight:600; font-size:.78rem; color:var(--muted); }

/* Segmenteret kontrol (marked-vælgeren) */
.gv-seg { display:inline-flex; border:1px solid var(--line); border-radius:999px; padding:.15rem; gap:.15rem; background:var(--card); }
/* button AND a: a segment whose options are destinations rather than modes needs real links, so
   Liste/Kort can be middle-clicked and shared. Added 27.07.2026 with the list/map view switch;
   nothing else in the codebase puts an <a> in a .gv-seg, so this only widens what is styled. */
.gv-seg button, .gv-seg a { font:inherit; font-size:.82rem; border:0; background:transparent; color:var(--muted);
    padding:.28rem .8rem; border-radius:999px; cursor:pointer; text-decoration:none; display:inline-block; }
.gv-seg button.aktiv, .gv-seg a.aktiv { background:var(--accentbg); color:var(--accent); font-weight:600; }
.gv-seg a:hover { color:var(--fg); }

/* Small count on a button ("Avanceret 3"): says how much is hidden behind it. */
.gv-taeller { display:inline-flex; align-items:center; justify-content:center; min-width:1.15rem;
    height:1.15rem; margin-left:.4rem; padding:0 .28rem; border-radius:999px; font-size:.7rem;
    font-weight:700; background:var(--accent); color:var(--bg); }

/* Filterbar: knapper der åbner paneler (details/summary for native åbn/luk) */
.gv-fbar { display:flex; flex-wrap:wrap; gap:.45rem; align-items:center; }
.gv-fknap { position:relative; }
.gv-fknap > summary { list-style:none; display:inline-flex; align-items:center; gap:.35rem; cursor:pointer;
    font-size:.86rem; padding:.42rem .8rem; border:1px solid var(--line); border-radius:999px;
    background:var(--card); color:var(--fg); user-select:none; white-space:nowrap; }
.gv-fknap > summary::-webkit-details-marker { display:none; }
.gv-fknap > summary::after { content:''; width:.42rem; height:.42rem; border-right:1.6px solid var(--muted);
    border-bottom:1.6px solid var(--muted); transform:rotate(45deg) translateY(-.1rem); }
.gv-fknap[open] > summary { border-color:var(--accent); }
.gv-fknap.harvalg > summary { border-color:var(--accent); background:var(--accentbg); color:var(--accent); font-weight:600; }
.gv-panel { position:absolute; top:calc(100% + .4rem); left:0; z-index:20; min-width:16rem;
    background:var(--card); border:1px solid var(--line); border-radius:var(--radius);
    box-shadow:var(--skygge); padding:.85rem .95rem; }
.gv-panel.hoejre { left:auto; right:0; }  /* desktop: højrestil panelet under barens sidste knap */
/* ONE FIXED WIDTH FOR THE BAR'S DROPDOWNS ON DESKTOP (Jonas, 17.08.2026: "they should be fixed
   width and on desktop they could be a bit wider ... so the bars are easier to use"). Measured at
   1280px before the change: Bolig 358 px, Pris 256, Størrelse 256 - and Bolig's was CONTENT-driven,
   so the panel visibly resized as facet counts landed and as a slider's own min/max labels grew.
   A dropdown that changes width while you read it is the fault; the sliders being cramped is the
   cost. 23rem = 368 px is above the widest of the three, so nothing reflows to a narrower box, and
   the two slider panels gain 44% of track.
   NOT applied on the map: kort.css's `.panel .gv-panel { width:auto }` has the same specificity and
   is linked after this file, so the side panel keeps sizing itself to its own 16.5rem column. Under
   641px the bottom-sheet rule below overrides `width` via left/right anyway. */
/* ...and a ceiling, because one of them is now 49 buttons tall. "Mæglerens ord" came out of
   Avanceret on 17.08.2026 with the whole sales-text vocabulary in it, and a dropdown taller than
   the window has no scrollbar of its own - it simply runs off the bottom of the screen with its
   last group unreachable. The mobile bottom-sheet rule below has had exactly this pair since it
   was written; desktop never needed it until a panel got big. */
@media (min-width:641px) { .gv-fbar .gv-panel { width:23rem; max-height:min(70vh, 34rem); overflow:auto; } }
/* Mobil: bottom-sheet. NB top:auto er obligatorisk - desktop-reglens top:calc(100%+.4rem)
   betyder m. position:fixed "100% af viewporten" = panelet lander USYNLIGT under skaermen
   (24.07: "filtrene gør ingenting" på mobil). */
@media (max-width:640px) {
    /* z-index over bundnavigationen (.omrnav er 90) - et aabent sheet er modal-agtigt */
    .gv-panel, .gv-panel.hoejre { position:fixed; left:0; right:0; top:auto; bottom:0; min-width:0; z-index:95;
        border-radius:var(--radius) var(--radius) 0 0; border-bottom:0;
        max-height:72vh; overflow:auto; padding-bottom:max(1rem, env(safe-area-inset-bottom)); }
    /* A TABLE TOO WIDE FOR THE PHONE SCROLLS INSIDE ITSELF, never sideways with the whole page
       (08.08.2026). Five pages could be panned horizontally at 390 px - /om/kilder by 201 px,
       /skole by 144, /statistik by 68, both address pages by ~30 - and the gate that exists to
       catch exactly that was comparing scrollWidth against innerWidth, which GROWS to the
       overflow under emulation and so could never fail. tools/fejlfejning.mjs owns that record.
       `display:block` turns the table into its own scroll container; `width:100%` from the base
       rule keeps the box the width of the column it sits in, so a table that already fits is
       unchanged - measured on /kommune and the address page, where all ten tables stayed 350 px.
       Deliberately NOT a wrapper div: that would be markup in 25 pages for a rule that is the
       same in all of them, and gv.css is where a rule the whole site obeys belongs. */
    table { display:block; overflow-x:auto; }
}
.gv-panel label { display:block; font-size:.78rem; color:var(--muted); margin:.5rem 0 .15rem; }
.gv-panel label:first-child { margin-top:0; }

/* Felter og knapper */
.gv-tal, .gv-select, .gv-tekst { font:inherit; font-size:.86rem; padding:.4rem .55rem; color:inherit;
    border:1px solid var(--line); border-radius:var(--radius-s); background:var(--bg); width:100%; }
.gv-tal:focus, .gv-select:focus, .gv-tekst:focus { outline:none; border-color:var(--accent); }
/* 16px is not a taste decision, it is the iOS threshold: Safari ZOOMS the whole page when you focus
   an input smaller than that, and then lets you pan around the zoomed page. What you see is a dialog
   whose heading has scrolled off the top and whose text runs past the right edge - which reads as a
   layout bug and is not one. It cannot be reproduced in an emulator either: measured at 390px wide,
   nothing overflowed at all, while .gv-tal computed to 13,76px (Jonas' screenshot, 28.07.2026).
   The mobile filter sheet already set 1rem for legibility, which is why only the builder showed it. */
@media (max-width:720px) {
    .gv-tal, .gv-select, .gv-tekst { font-size:16px; }
}
.gv-minmax { display:flex; gap:.4rem; align-items:center; }
.gv-minmax span { color:var(--muted); }
/* Antagelse: two boxes that are NOT a range, so they get a gap wide enough to read as separate
   controls and each carries its own unit. No separator between them - a hyphen or an en space is
   what makes two boxes read as one interval. */
/* The renovation sum on a result card. `svag` is the case where the gain is inside our own price
   uncertainty - muted rather than hidden, because a hidden caveat is not a caveat. */
.gvc-reno { font-size:.9rem; margin:.25rem 0 0; color:var(--tekst); }
.gvc-reno.svag { color:var(--muted); }
.gvc-reno .gvc-usik { color:var(--muted); }
/* The two halves of a renovation case, under the total. Their own line because they are an
   explanation of the number above, not two more facts at the same level - and because printing
   only the sum is exactly what hid a house whose renovation lost money (07.08.2026). */
.gvc-renodel { display:block; font-size:.76rem; color:var(--muted); margin-top:.15rem; }
.kritantag { display:flex; gap:.9rem; align-items:center; flex-wrap:wrap; }
.kritantaglab { display:flex; gap:.3rem; align-items:center; }
.kritantaglab .kritenhed { color:var(--muted); font-size:.9rem; white-space:nowrap; }
.gv-knap { font:inherit; font-size:.85rem; font-weight:600; padding:.45rem .95rem; cursor:pointer;
    border:1px solid var(--line); border-radius:999px; background:var(--card); color:var(--fg); }
.gv-knap.primaer { background:var(--accent); border-color:var(--accent); color:var(--bg); }
.gv-lenke { font-size:.82rem; color:var(--accent); background:none; border:none; padding:0; cursor:pointer; text-decoration:underline; font-family:inherit; }

/* iOS Safari keeps double-tap-to-zoom alive on every control, and a second tap on a button is a
   natural thing to do while a live count is still settling - so the page zooms toward the button
   instead of pressing it again. Jonas hit it on the map's "Vis N boliger" button, 01.08.2026.
   `manipulation` switches off double-tap zoom FOR THESE ELEMENTS ONLY; pinch-to-zoom still works
   everywhere on the page, so it costs no accessibility - which is also why the answer is not
   `user-scalable=no` on the viewport. It removes the ~300 ms tap delay that comes with waiting to
   see whether a second tap is coming, so every control on the site also gets slightly quicker.
   Deliberately NOT on the map canvas or any container: MapLibre reads its own touch gestures. */
button, input, select, textarea, label, summary,
.gv-knap, .gv-chip, .gv-lenke, .gv-seg a { touch-action:manipulation; }

/* Chips: både filter-toggles (button) og info-chips på cards (span) */
.gv-chip { display:inline-flex; align-items:center; gap:.3rem; font:inherit; font-size:.78rem;
    padding:.26rem .7rem; border:1px solid var(--line); border-radius:999px; background:var(--card);
    color:var(--fg); cursor:pointer; white-space:nowrap; }
.gv-chip.aktiv { background:var(--accentbg); border-color:var(--accent); color:var(--accent); font-weight:600; }
.gvc-chip { display:inline-block; font-size:.68rem; padding:.08rem .45rem; border-radius:5px;
    background:var(--accentbg); color:var(--accent); white-space:nowrap; }
.gvc-chip.advarsel { background:var(--negbg); color:var(--neg); }
/* Åbent hus: den eneste chip med en udløbsdato, så den skal skille sig ud fra de faste fakta ved
   siden af. Positiv farve, ikke advarsel - det er en invitation, ikke et forbehold. */
.gvc-chip.gvc-aaben { background:var(--posbg); color:var(--pos); font-weight:600; }
/* Temaer: mæglerens egne ord, ikke et register. Derfor dæmpet og med kursiv frem for accentfarven -
   chippen ved siden af ("Altan", "Elevator") er et felt nogen har udfyldt, den her er noget nogen
   har SKREVET for at sælge et hus. Forskellen skal kunne ses uden at man læser hjælpeteksten. */
.gvc-chip.gvc-tema { background:var(--line); color:var(--muted); font-style:italic; }
/* Standordene: samme "det er mæglerens ord"-dæmpning som temaerne, men i tekstfarve frem for grå,
   fordi stand er det dyreste at overse. Ikke accentfarven - den er reserveret til registerfakta. */
.gvc-chip.gvc-stand { background:var(--line); color:var(--fg); font-style:italic; }
/* Det ord DU søgte på. Ringen tegnes i chippens egen tekstfarve frem for i accentfarven, så den
   bliver ved med at læse som mæglerens ord - accenten betyder registerfakta og skal blive ved med
   at gøre det. Kortet flytter samtidig træfferen forrest (soegkort.js), for på fem chips er en
   stilforskel stadig en scanning. */
.gvc-chip.gvc-traef { box-shadow:inset 0 0 0 1px currentColor; font-weight:700; font-style:normal; }
/* Lejeøkonomi: samme vægt som .gvc-meta, men egen linje - beløbene skal kunne læses sammen. */
.gvc-leje { font-size:.78rem; color:var(--muted); margin-top:.15rem; }

/* Verdict-badge: afvigelse fra modelpris. Farve + fortegn i teksten (farveblind-sikkert). */
.gv-verdict { display:inline-block; font-size:.74rem; font-weight:700; padding:.12rem .5rem;
    border-radius:6px; white-space:nowrap; }
.gv-verdict.under { background:var(--posbg); color:var(--pos); }
.gv-verdict.over { background:var(--negbg); color:var(--neg); }
.gv-verdict.neutral { background:var(--accentbg); color:var(--muted); }

/* Warning box, shared by /firma (going concern) and /adresse (hjemfaldspligt): both had it inline
   with a fixed pale background and no text colour, so dark mode put the near-white --fg on #fdf3f2
   (Jonas, 22.08). Heading NOT --neg - measured 3,82:1 against the 4,83:1 the hardcoded box had. */
.gv-advarsel { margin:1.3rem 0 .5rem; padding:.6rem .85rem; border:1px solid var(--neg);
    border-left-width:5px; border-radius:10px; background:var(--negbg); font-size:.95rem; }
.gv-advarsel > strong { color:#b8342a; }
@media (prefers-color-scheme: dark) { .gv-advarsel > strong { color:#e69086; } }

/* Energimærke-pille (officielle klassefarver, hvid tekst) */
.gv-energi { display:inline-block; font-size:.68rem; font-weight:700; color:#fff; padding:.08rem .38rem;
    border-radius:4px; line-height:1.3; }
.gv-energi.eA { background:#2f7d22; } .gv-energi.eB { background:#7fb356; } .gv-energi.eC { background:#c9b524; }
.gv-energi.eD { background:#e0a020; } .gv-energi.eE { background:#e08a3c; } .gv-energi.eF { background:#d0563c; }
.gv-energi.eG { background:#b8342a; }

/* Bolig-card (listevisningen) */
/* min-width:0: som grid-item er default min-width:auto, og adressens nowrap-ellipsis goer saa
   kortets min-content BREDERE end skaermen -> vandret overflow paa mobil (435px-layout, 24.07). */
.gv-card { position:relative; display:flex; gap:.9rem; min-width:0; background:var(--card); border:1px solid var(--line);
    border-radius:var(--radius); padding:.75rem; transition:border-color .12s, transform .12s; }
.gvc-foto { flex:none; width:7.6rem; height:6rem; object-fit:cover; border-radius:var(--radius-s); background:var(--accentbg); }
.gvc-foto.tom { display:grid; place-items:center; color:var(--muted); font-size:1.4rem; }
.gvc-krop { flex:1; min-width:0; display:flex; flex-direction:column; gap:.14rem; }
.gvc-prislinje { display:flex; align-items:baseline; gap:.55rem; flex-wrap:wrap; }
.gvc-pris { font-size:1.06rem; font-weight:700; letter-spacing:-.01em; }
/* Up to TWO lines, then ellipsis - not one line and ellipsis. On a 390 px phone the card's photo
   takes 7,6rem, and what got cut was always the tail: "Børup Tværvej 15, 8310 …" hid the postal
   town, which is the half that tells you WHERE in the municipality the home is. The card is already
   variable height (the meta line wraps freely), so a second line costs nothing structural, and the
   clamp keeps a pathological address from growing the card without limit. Found 01.08.2026 by
   looking at a phone-width capture. */
.gvc-adr { font-weight:600; font-size:.92rem; overflow:hidden;
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.gvc-adr a { color:inherit; text-decoration:none; }
.gvc-adr a::after { content:''; position:absolute; inset:0; } /* stretched link: hele kortet klikker til adressesiden */
.gvc-meta, .gvc-bund { font-size:.78rem; color:var(--muted); display:flex; flex-wrap:wrap; gap:.2rem .6rem; align-items:center; }
.gvc-bund { margin-top:auto; }
.gvc-maegler { position:relative; z-index:2; color:var(--accent); text-decoration:none; margin-left:auto; white-space:nowrap; }

/* Hover kun paa enheder MED hover (mus): paa touch "haenger" hover-stilen fast efter tap,
   saa fx en fravalgt chip bliver ved at ligne noget andet end naboerne (24.07).
   REGLEN NAAEDE IKKE NY CSS. 28.07.2026 blev den samme fejl skrevet ind igen i _Bygger.cshtml,
   _Filterbar.cshtml og Index.cshtml - fire dage efter denne kommentar, i filer der ligger ved siden
   af. Jonas fandt den paa en telefon: et fravalgt trin beholdt sin accent-kant og foeltes
   "half clicked". En kommentar i EN fil beskytter kun den fil, saa reglen er nu maalt i stedet:
   tools/soeg-mobil-tjek.mjs afsnit 4b koerer en rigtig mus hen paa knappen med touch-emulering og
   tjekker at den ser fravalgt ud. NB headless kan ALDRIG svare `hover: hover`, heller ikke med
   CDP setEmulatedMedia - saa den positive side maales paa hvor reglen STAAR, ikke paa farven. */
@media (hover:hover) {
    .uch a:hover { text-decoration:underline; }

    .gv-fknap > summary:hover { border-color:var(--accent); }
    .gv-knap:hover { border-color:var(--accent); color:var(--accent); }
    .gv-chip:hover { border-color:var(--accent); }
    .gv-card:hover { border-color:var(--accent); transform:translateY(-1px); }
    .gvc-maegler:hover { text-decoration:underline; }
}
@media (max-width:560px) {
    .gvc-foto { width:5.6rem; height:5rem; }
    .gvc-pris { font-size:.98rem; }
}

/* Tom tilstand + status */
.gv-tom { text-align:center; color:var(--muted); padding:2.2rem 1rem; border:1px dashed var(--line);
    border-radius:var(--radius); font-size:.92rem; }

/* "Gem søgning" popover. Anchored to the filter bar rather than centred, because it belongs to the
   button that opened it - and deliberately NOT position:fixed: on /kort it renders inside .panel,
   which has backdrop-filter and would capture a fixed element and put it off screen. That is the
   bug tools/kort-dialog-tjek.mjs was built for on 01.08.2026; the same trap, avoided by design. */
.gemsoegboks { position:absolute; z-index:30; margin-top:.35rem; padding:.7rem .8rem;
    background:var(--bg); border:1px solid var(--line); border-radius:12px;
    box-shadow:var(--skygge); width:min(20rem,calc(100vw - 2rem)); }
.gemsoegboks label { display:block; font-size:.78rem; color:var(--muted); margin-bottom:.25rem; }
.gemsoegboks input { width:100%; box-sizing:border-box; font-size:16px; padding:.4rem .55rem;
    border:1px solid var(--line); border-radius:8px; background:var(--card); color:inherit; }
.gemsoegrk { display:flex; align-items:center; gap:.6rem; margin-top:.55rem; }

/* THE BRANCHE PANEL (VIRK6 T1). Same shell as .gemsoegboks above - absolute, not fixed, for the
   reason that block's own comment gives - but wider and with a scrolling result list, because it
   is a search over 61 everyday trades plus 1.691 official titles rather than a single field.
   Height is capped in vh so the phone keyboard cannot push the list off screen. */
.brboks { position:absolute; z-index:30; margin-top:.35rem; padding:.7rem .8rem;
    background:var(--bg); border:1px solid var(--line); border-radius:12px;
    box-shadow:var(--skygge); width:min(26rem,calc(100vw - 2rem)); }
.brboks label { display:block; font-size:.78rem; color:var(--muted); margin-bottom:.25rem; }
.brboks input { width:100%; box-sizing:border-box; font-size:16px; padding:.4rem .55rem;
    border:1px solid var(--line); border-radius:8px; background:var(--card); color:inherit; }
.brliste { margin-top:.5rem; max-height:min(22rem,45vh); overflow-y:auto; }
/* One row per suggestion: the everyday word on the left, how many live companies it covers on the
   right. The count is what makes the list rankable by eye - "VVS 3.743" against a code with four. */
.brrk { display:flex; align-items:center; justify-content:space-between; gap:.6rem; width:100%;
    text-align:left; font:inherit; font-size:.85rem; padding:.4rem .5rem; border:0; border-radius:8px;
    background:none; color:inherit; cursor:pointer; }
.brrk:hover { background:var(--accentbg); }
.brrk.valgt { background:var(--accentbg); color:var(--accent); font-weight:600; }
.brrk .brtal { color:var(--muted); font-size:.78rem; font-variant-numeric:tabular-nums; flex:none; }
.brrk.valgt .brtal { color:var(--accent); }
/* An official DB07 title, under the everyday words. Smaller and muted, because it is the precise
   answer for somebody who already knows their own code - not the one most readers want. */
.brrk.brkode .brnavn { color:var(--muted); font-size:.8rem; }
/* The free-text fallback row (VIRK6 T4). Set apart by a rule above it, because it is a different
   ACTION from the rows over it - it searches the companies' own prose rather than picking a
   trade - and a row that looks identical to the others would be read as one more branche. */
.brrk.brfritekst { border-top:1px solid var(--line); border-radius:0; margin-top:.35rem;
    padding-top:.55rem; }
.brrk.brfritekst .brnavn { color:var(--accent); font-weight:600; }

/* The person's trade mix (VIRK6 T2): "VVS 80% · Ejendomme 20% · af 5 aktuelle selskaber".
   Wraps rather than scrolls - a long mix on a 390 px phone is several trades, and pushing it
   sideways would hide the basis, which is the part that makes the percentages mean anything. */
.mixlinje { display:flex; flex-wrap:wrap; align-items:baseline; gap:.2rem .5rem;
    margin:.15rem 0 .35rem; font-size:.9rem; }
.mixlinje > a { font-weight:600; }
.mixlinje > a:not(:last-of-type)::after, .mixlinje .mixandet::after { content:"·"; color:var(--muted);
    font-weight:400; margin-left:.5rem; }
.mixlinje .mixandet { color:var(--muted); }
.mixlinje .dis { font-size:.82rem; }

/* "Heading, with a link pushed to the right edge" - the section-heading row. It lived in
   strib.css, whose own comment already said it is not the photo strip's style but a component
   the front page reuses for headings with no strip under them. That was true and one page short:
   /virksomheder does NOT link strib.css (it has no photo strips), so its "Siden sidst" heading
   got no rule at all and the "Dit gemte →" link sat unstyled against the text instead of at the
   right edge - Jonas, 17.08.2026, "looks bad ... should just be changed to the design from
   boliger". Moved 17.08.2026 for the same reason .srad moved here on 12.08: a component more than
   one page draws belongs in the shared sheet. Nothing else declares .uch, so the earlier position
   in the cascade cannot change what the two pages that already had it render. */
.uch { display:flex; align-items:baseline; gap:.9rem; font-size:1.35rem; letter-spacing:-.012em;
    margin:2.4rem 0 .8rem; border:0; padding:0; }
.uch a { margin-left:auto; font-weight:600; font-size:.9rem; white-space:nowrap; text-decoration:none; }

/* Personal news rows ("Siden sidst") - shared by the front page box and /konto (Gemt).
   The renderer is js/gv-siden.js; a page that draws these rows loads that file first.
   Moved here from forside.css 12.08.2026 when /konto became the second consumer. */
.srad { display:flex; align-items:center; gap:.7rem; padding:.55rem 1rem;
    border-top:1px solid var(--line); color:var(--fg); text-decoration:none; font-size:.95rem; }
/* Direct-child b only: the search rows' one-line name, which IS a flex item and can clip.
   The event rows' b sits inside .stekst, where an inline can never clip - nowrap there just
   pushed long addresses past the right screen edge (seen on a phone 15.08.2026, the rows with
   thumbnails; the short-address rows only LOOKED right). Those sentences wrap instead. */
.srad > b { font-weight:600; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.srad:hover b { text-decoration:underline; }
.spil { margin-left:auto; flex-shrink:0; font-size:.8rem; font-weight:700;
    border-radius:999px; padding:.16rem .6rem; white-space:nowrap; }
.spil.ny { background:var(--accentbg); color:var(--accent); }
.spil.stille { background:var(--panel); color:var(--muted); font-weight:600; }
.sbad { flex-shrink:0; font-size:.68rem; font-weight:700; border-radius:6px; padding:.16rem .45rem;
    text-transform:uppercase; letter-spacing:.03em; }
.sbad.solgt { background:var(--fg); color:var(--bg); }
.sbad.tilsalg { background:var(--accentbg); color:var(--accent); }
.sbad.fald { background:var(--negbg); color:var(--neg); }
.sbad.aabent { background:var(--accent); color:var(--bg); }
.sbad.plan { background:var(--panel); color:var(--fg); border:1px solid var(--line); }
.sbad.model { background:var(--fg); color:var(--bg); }
.sthumb { width:56px; height:40px; object-fit:cover; border-radius:6px; flex-shrink:0;
    border:1px solid var(--line); }
.stekst { min-width:0; font-size:.92rem; }
.stekst b { font-weight:600; }
.stekst small { display:block; color:var(--muted); font-size:.79rem; }
