/* Demo-grade, one file, no build step (FRONTEND.md 2). Plain CSS: the largest
   single piece of new complexity here would be a toolchain, and it would buy
   nothing at this scale.

   EVERY COLOUR IS A VARIABLE, because there are two themes and a hard-coded hex
   is how one of them ends up with black text on a dark grey card. The dark values
   are a separate block at the bottom, not a filter: `invert()` would flip the
   comparison's semantic colours (green agreement, red missing) into nonsense.

   THE COMPARISON NEVER RELIES ON COLOUR ALONE. Each state also carries a symbol
   (= − +) and a Danish word, so it survives a mono printout and colour-blindness;
   ~8% of men cannot separate the red from the green. */
:root {
  color-scheme: light dark;

  --ink: #16191d;
  --ink-soft: #3d444c;
  --mut: #5b6570;
  --line: #dfe3e8;
  --line-strong: #c6ccd4;
  --bg: #f6f7f9;
  --card: #ffffff;
  --card-2: #eef1f4;
  --link: #1a5fb4;

  /* verdicts */
  --klar: #0f7b3e;
  --klar-bg: #e6f4ec;
  --gennemsyn: #8a5a00;
  --gennemsyn-bg: #fdf3e0;
  --afvist: #8a2020;
  --afvist-bg: #fbeaea;

  /* the comparison's three states: agreement / missing / spurious */
  --enig: #0f7b3e;
  --enig-bg: #e3f3ea;
  --mangler: #9b1c1c;
  --mangler-bg: #fbe9e9;
  --overskydende: #8a5a00;
  --overskydende-bg: #fdf1de;

  /* the drop zone: a tint of --link, and the scrim behind the drag overlay */
  --accent-soft: #eaf2fd;
  --overlay: #10141ae0;

  /* THE primary action, and nothing else on the page. A step deeper than --link
     so the one button that submits owns a shade no link or secondary control uses
     -- the front page previously had two identically blue buttons and neither won.
     --handling-tekst is a token rather than a literal #fff because the dark theme
     needs INK on the bright fill: white on #79b0f5 lands at ~2.6:1. */
  --handling: #154c91;
  --handling-kant: #0d3567;
  --handling-tekst: #ffffff;

  /* ONE RADIUS SCALE. Not themed -- a corner is not a colour -- so these are
     defined once here and never repeated in the dark blocks.

     There were seven values in this file (4, 6, 8, 10, 14, 18, 999px) and no rule
     behind any of them: buttons alone carried three, depending on which commit
     last touched them. Sheet metal is sheared and folded, so a control is tight
     and only the drop targets are soft.

       --r-kontrol  anything you click or type into
       --r-kort     containers: cards, notices, tables, lists
       --r-zone     the two drop targets, deliberately softer than a card
       --r-pille    status tokens: badge, chip, flag. NEVER a control -- a pill
                    shape is what says "this is a label, not a button". */
  --r-kontrol: 4px;
  --r-kort: 8px;
  --r-zone: 14px;
  --r-pille: 999px;
}

:root[data-theme="dark"], :root[data-theme="dark"] * { color-scheme: dark; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #e7eaee;
    --ink-soft: #c3c9d1;
    --mut: #98a2ad;
    --line: #2c333c;
    --line-strong: #3d4652;
    --bg: #14171b;
    --card: #1b1f25;
    --card-2: #232830;
    --link: #79b0f5;

    --klar: #58d68d;
    --klar-bg: #14301f;
    --gennemsyn: #e6bd6a;
    --gennemsyn-bg: #33260d;
    --afvist: #f08b8b;
    --afvist-bg: #341a1a;

    --enig: #58d68d;
    --enig-bg: #14301f;
    --mangler: #f08b8b;
    --mangler-bg: #341a1a;
    --overskydende: #e6bd6a;
    --overskydende-bg: #33260d;

    --accent-soft: #16283f;
    --overlay: #05070aeb;

    --handling: #79b0f5;
    --handling-kant: #4f8ad8;
    --handling-tekst: #0e1620;
  }
}

/* The toggle must win in BOTH directions, so the manual attribute repeats the
   dark values (and the light ones stay in :root above). Without the explicit
   [data-theme="dark"] block, a user on a light OS could not choose dark at all. */
:root[data-theme="dark"] {
  --ink: #e7eaee;
  --ink-soft: #c3c9d1;
  --mut: #98a2ad;
  --line: #2c333c;
  --line-strong: #3d4652;
  --bg: #14171b;
  --card: #1b1f25;
  --card-2: #232830;
  --link: #79b0f5;

  --klar: #58d68d;
  --klar-bg: #14301f;
  --gennemsyn: #e6bd6a;
  --gennemsyn-bg: #33260d;
  --afvist: #f08b8b;
  --afvist-bg: #341a1a;

  --enig: #58d68d;
  --enig-bg: #14301f;
  --mangler: #f08b8b;
  --mangler-bg: #341a1a;
  --overskydende: #e6bd6a;
  --overskydende-bg: #33260d;

  --accent-soft: #16283f;
  --overlay: #05070aeb;

  --handling: #79b0f5;
  --handling-kant: #4f8ad8;
  --handling-tekst: #0e1620;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font: 16px/1.55 "Segoe UI", system-ui, -apple-system, sans-serif;
  color: var(--ink);
  background: var(--bg);
}

/* 62rem is a READING MEASURE, right for the detail page and wrong for a table.
   `.bred` (set by views that render one) gives the page the window instead, with a
   ceiling so a 4K monitor does not stretch twelve columns across a metre of glass. */
main { max-width: 62rem; margin: 0 auto; padding: 1.5rem 1.25rem 3rem; }
main.bred, .bund.bred { max-width: min(100%, 120rem); padding-left: 2rem; padding-right: 2rem; }

.top {
  display: flex; align-items: baseline; gap: .75rem;
  padding: .85rem 1.25rem;
  background: var(--card); border-bottom: 1px solid var(--line);
}
.brand { font-weight: 600; color: var(--ink); text-decoration: none; }
.tag { color: var(--mut); font-size: .875rem; }
.tema {
  margin-left: auto; font: inherit; font-size: .8125rem; cursor: pointer;
  padding: .25rem .7rem; border-radius: var(--r-kontrol);
  border: 1px solid var(--line-strong); background: var(--card-2);
  color: var(--ink-soft);
}
.tema:hover { border-color: var(--mut); }

h1 { font-size: 1.5rem; margin: 0 0 .25rem; }
h2 { font-size: 1.1rem; margin: 2rem 0 .6rem; }

a { color: var(--link); }

/* --- the three action tiers ----------------------------------------------
   This page previously carried five unrelated treatments -- an underlined text
   link, a grey pseudo-button, a filled blue one, an outlined one and a dashed one
   -- and none of them said how important the thing was. Everything clickable now
   lands in exactly one tier:

     PRIMARY   one filled --handling control per decision (`button.gem`, and the
               front page's submit). It commits something.
     SECONDARY outlined on --card (`a.knap`, `.hent a`, the rating buttons).
               A real action, but not the one the page is asking for.
     QUIET     no underline, --mut until hovered (`.tilbage`, `a.blyant`, the
               footer). Navigation, not action.

   The tiers are what let the back control stop being an underlined string. */

/* Back to the upload page. `←` as a text glyph inherits text metrics and sits
   below the baseline of the words next to it, which is most of why this read as
   scruffy; the chevron is drawn instead. The 2px shift on hover is directional --
   it points the way the control goes -- and is the only motion on this page. */
.tilbage { margin: 0 0 1.25rem; font-size: .875rem; }
.tilbage a {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .3rem .55rem .3rem .4rem; margin-left: -.4rem;
  border-radius: var(--r-kontrol); text-decoration: none; font-weight: 600;
  color: var(--mut); transition: color .12s ease, background-color .12s ease;
}
.tilbage a:hover { color: var(--ink); background: var(--card-2); }
.tilbage a:focus-visible { outline: 2px solid var(--link); outline-offset: 1px; }
.tilbage svg { width: .8rem; height: .8rem; transition: transform .12s ease; }
.tilbage a:hover svg { transform: translateX(-2px); }
@media (prefers-reduced-motion: reduce) {
  .tilbage a, .tilbage svg { transition: none; }
  .tilbage a:hover svg { transform: none; }
}

/* --- cards and forms ---------------------------------------------------- */
.kort {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-kort);
  padding: 1.1rem 1.25rem; margin: 1rem 0;
}
.kort label { display: block; font-weight: 600; margin: .6rem 0 .25rem; }
input[type="file"], input[type="text"], select {
  font: inherit; padding: .4rem .5rem; color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--r-kontrol); background: var(--card);
}
button, .knap {
  font: inherit; font-weight: 600; margin-top: 1rem; display: inline-block;
  padding: .5rem 1.1rem; border: 0; border-radius: var(--r-kontrol); text-decoration: none;
  background: var(--link); color: #fff; cursor: pointer;
}
.hjaelp, .lille { color: var(--mut); font-size: .875rem; }

/* --- the submit row on the front page ------------------------------------- */
/* Quantity and the one action, directly under the drop zone. The button is NOT
   stretched to the card: a control that spans a whole card stops reading as a
   button and starts reading as a banner, which is what the first attempt at this
   row looked like. Sized to its content instead, left-aligned on the form's own
   edge, with the quantity field matched to its height so the row balances. */
.indsend {
  display: flex; align-items: flex-end; gap: .85rem; flex-wrap: wrap;
  margin: 1.1rem 0 .3rem;
}
.indsend .antal-felt { flex: none; }
.indsend .antal-felt label { margin: 0 0 .3rem; }
.indsend .antal-boks { display: flex; align-items: center; gap: .45rem; }
/* Matched to the button exactly: same font-size, and the padding gives back the
   1px border the button does not have, so the two boxes are the same height and
   the row does not look assembled from spare parts. */
.indsend input#antal {
  width: 4.5rem; text-align: center; font-size: 1.0625rem;
  padding: calc(.78rem - 1px) .5rem;
  font-variant-numeric: tabular-nums; border-radius: var(--r-kontrol);
}
.indsend .enhed { color: var(--mut); font-size: .9375rem; }

/* THE button. Sheet metal is sheared and pressed, so it is a 4px shear radius
   rather than the soft 8px slab, and the 2px darker bottom edge is a folded lip:
   it collapses under `:active` so the plate physically presses. That is the only
   motion on this page, and it answers a click rather than announcing itself. */
.indsend button.primaer {
  margin-top: 0; min-width: 11rem;
  font-size: 1.0625rem; letter-spacing: .01em;
  padding: .78rem 2rem; border-radius: var(--r-kontrol);
  background: var(--handling); color: var(--handling-tekst);
  box-shadow: inset 0 -2px 0 var(--handling-kant);
  transition: transform .06s ease, box-shadow .06s ease, background-color .12s ease;
}
.indsend button.primaer:hover { background: var(--handling-kant); }
.indsend button.primaer:active {
  transform: translateY(2px); box-shadow: inset 0 0 0 var(--handling-kant);
}
.indsend button.primaer:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  .indsend button.primaer { transition: none; }
  .indsend button.primaer:active { transform: none; }
}
.forklaring dt { margin-top: .8rem; }
.forklaring dd { margin: .15rem 0 0 0; color: var(--mut); }

/* --- verdict badges ----------------------------------------------------- */
.hoved { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.badge {
  display: inline-block; padding: .15rem .6rem; border-radius: var(--r-pille);
  font-size: .8125rem; font-weight: 600; white-space: nowrap;
}
.badge.klar { color: var(--klar); background: var(--klar-bg); }
.badge.gennemsyn { color: var(--gennemsyn); background: var(--gennemsyn-bg); }
.badge.afvist { color: var(--afvist); background: var(--afvist-bg); }

/* --- key/value facts ---------------------------------------------------- */
.fakta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: .35rem 1.5rem; margin: 1rem 0 0;
}
.fakta dt { color: var(--mut); font-size: .8125rem; }
.fakta dd { margin: 0; }
.noegle { margin-top: 1rem; }
.noegle .stor { font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.enig-tal { color: var(--enig); }
.mangler-tal { color: var(--mangler); }
.overskydende-tal { color: var(--overskydende); }

/* --- messages ----------------------------------------------------------- */
.fejl, .advarsel, .note {
  border-radius: var(--r-kort); padding: .8rem 1rem; margin: 1rem 0;
  border-left: 4px solid;
}
.fejl { background: var(--afvist-bg); border-color: var(--afvist); }
.advarsel { background: var(--gennemsyn-bg); border-color: var(--gennemsyn); }
.note { background: var(--card); border-color: var(--line-strong); color: var(--mut); }

/* --- tables ------------------------------------------------------------- */
table {
  width: 100%; border-collapse: collapse; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-kort); overflow: hidden;
}
th, td { text-align: left; padding: .45rem .7rem; border-bottom: 1px solid var(--line); }
thead th { background: var(--card-2); font-size: .8125rem; color: var(--ink-soft); }
tbody tr:last-child td { border-bottom: 0; }
.tal { text-align: right; font-variant-numeric: tabular-nums; }
.rutekaede { font-variant-numeric: tabular-nums; }
.svag-raekke td { background: var(--gennemsyn-bg); }
.flag {
  font-size: .75rem; font-weight: 600;
  color: var(--gennemsyn); background: var(--gennemsyn-bg);
  padding: .1rem .45rem; border-radius: var(--r-pille);
}
.noegletal th { width: 12rem; color: var(--mut); font-weight: 600; }
.noegletal .sum th, .noegletal .sum td { font-weight: 700; color: var(--ink); }

/* --- which case this is ------------------------------------------------- */
.sag {
  border-radius: var(--r-kort); padding: .7rem 1rem; margin: 1rem 0;
  background: var(--card); border: 1px solid var(--line);
}
.sag-A { border-left: 4px solid var(--enig); }
.sag-B, .sag-C { border-left: 4px solid var(--line-strong); }
.sag-A-uden-sammenligning { border-left: 4px solid var(--gennemsyn); }

/* --- the comparison ----------------------------------------------------- */
.kaeder {
  display: grid; gap: .5rem; margin: .75rem 0 1rem;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-kort); padding: .9rem 1rem;
}
.kaede { display: flex; gap: .75rem; align-items: baseline; flex-wrap: wrap; }
.kaede-navn {
  min-width: 8.5rem; color: var(--mut); font-size: .8125rem; font-weight: 600;
}
.kaede-chips { display: flex; gap: .35rem; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: .25rem;
  padding: .12rem .5rem; border-radius: var(--r-pille);
  font-size: .875rem; font-weight: 600; font-variant-numeric: tabular-nums;
  border: 1px solid transparent;
}
.chip-tegn { font-weight: 700; opacity: .85; }
.chip.enig { color: var(--enig); background: var(--enig-bg); border-color: var(--enig); }
.chip.mangler {
  color: var(--mangler); background: var(--mangler-bg); border-color: var(--mangler);
}
.chip.overskydende {
  color: var(--overskydende); background: var(--overskydende-bg);
  border-color: var(--overskydende);
}

.signatur { list-style: none; padding: 0; margin: 0 0 1rem; font-size: .875rem; }
.signatur li { margin: .25rem 0; color: var(--mut); }

.sammenlign .wc { font-weight: 600; font-variant-numeric: tabular-nums; }
.sammenlign td.ja { font-variant-numeric: tabular-nums; }
.sammenlign td.nej { color: var(--mut); }
.sammenlign .r-enig td:first-child { border-left: 4px solid var(--enig); }
.sammenlign .r-mangler td:first-child { border-left: 4px solid var(--mangler); }
.sammenlign .r-mangler td { background: var(--mangler-bg); }
.sammenlign .r-overskydende td:first-child {
  border-left: 4px solid var(--overskydende);
}
.sammenlign .r-overskydende td { background: var(--overskydende-bg); }

/* --- reasons ------------------------------------------------------------ */
.begrundelser { padding-left: 1.1rem; }
.begrundelser li { margin: .35rem 0; }
.begrundelser li.vigtig {
  list-style: none; margin-left: -1.1rem;
  background: var(--gennemsyn-bg); border-left: 4px solid var(--gennemsyn);
  border-radius: var(--r-kort); padding: .55rem .8rem; font-weight: 600;
}

/* Downloading the workbook is an ACTION, not a sentence: it produced a file and
   it was rendered as underlined body copy. Secondary tier -- it is a real thing to
   do, but the page is asking the planner to choose a route, not to export one. */
.hent { margin-top: 2rem; }
.hent a {
  display: inline-block; padding: .45rem .9rem; border-radius: var(--r-kontrol);
  color: var(--ink); background: var(--card); text-decoration: none;
  border: 1px solid var(--line-strong);
}
.hent a:hover { border-color: var(--ink-soft); background: var(--card-2); }
.hent a:focus-visible { outline: 3px solid var(--link); outline-offset: 2px; }

/* --- the batch view ----------------------------------------------------- */
/* Six tiles, one row. `auto-fit` sizes tracks to CONTENT above the minimum, so one
   long label ("Middel-Jaccard (kun sammenlignelige)") widened its track enough to
   push the sixth tile onto a row of its own. The qualifier moved under the number,
   and the labels now wrap instead of forcing the track. */
.opsummering {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: .75rem; margin: 1rem 0;
}
.opsummering dt { overflow-wrap: anywhere; }
.opsummering .kvalifikator {
  display: block; font-size: .75rem; font-weight: 400; color: var(--mut);
  margin-top: .1rem;
}
.opsummering div {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-kort);
  padding: .7rem .9rem;
}
.opsummering dt { color: var(--mut); font-size: .8125rem; }
.opsummering dd {
  margin: .1rem 0 0; font-size: 1.35rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.filtre {
  display: flex; gap: 1rem; flex-wrap: wrap; align-items: end;
  margin: 1rem 0 .5rem;
}
.filtre label { font-size: .8125rem; color: var(--mut); display: block; }
.samling { font-size: .9375rem; }
.samling th.sorter { cursor: pointer; user-select: none; white-space: nowrap; }
.samling th.sorter:hover { color: var(--link); }
.samling td.rute { font-variant-numeric: tabular-nums; }
.samling tr.ingen-sammenligning td.jac { color: var(--mut); }
.samling .gruppe th {
  border-bottom: 2px solid var(--line-strong); color: var(--mut);
  font-size: .75rem; text-transform: uppercase; letter-spacing: .04em;
}
.samling .gruppe th + th { border-left: 1px solid var(--line-strong); }
.samling td.ingen-cell {
  color: var(--mut); font-size: .8125rem; font-style: italic;
  border-left: 1px solid var(--line-strong);
}
.tabel-rul { overflow-x: auto; }

/* --- trust at a glance: the summary tiles and the confidence pill --------- */
/* Colour is never the only signal here either — the tile carries its own label and
   the pill carries a percentage, so both read on a mono printout. */
.opsummering dd.tal-klar { color: var(--klar); }
.opsummering dd.tal-gennemsyn { color: var(--gennemsyn); }
.opsummering dd.tal-afvist { color: var(--afvist); }

.konf {
  display: inline-block; padding: .1rem .45rem; border-radius: var(--r-pille);
  font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.konf.klar { color: var(--klar); background: var(--klar-bg); }
.konf.gennemsyn { color: var(--gennemsyn); background: var(--gennemsyn-bg); }
.konf.afvist { color: var(--afvist); background: var(--afvist-bg); }
/* The raw verdict token, kept beside the Danish word because the JSON and the
   workbook contain it — de-emphasised so the Danish reads first. */
.samling .kode { color: var(--mut); font-size: .6875rem; letter-spacing: .02em; }

.status-signatur {
  list-style: none; padding: 0; margin: .25rem 0 1rem;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(24rem, 1fr));
  gap: .3rem 1.5rem; font-size: .8125rem; color: var(--mut);
}
.status-signatur li { display: flex; gap: .5rem; align-items: baseline; }
.status-signatur .badge, .status-signatur .konf { flex: none; }

/* --- the drop zone -------------------------------------------------------- */
/* The native `Choose Files / No file chosen` control cannot be styled and looks
   like 2004, so it is CLIPPED rather than removed and a `<label for>` is styled in
   its place. Clipped, never `display:none`, for two reasons that both bite:
   a display-none input is not focusable, so `required` validation cannot point at
   it (Chrome logs "An invalid form control is not focusable" and submits nothing),
   and it drops out of the tab order. A label-for works with JavaScript off, so the
   whole zone degrades to a working picker. */
.sr-fil {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.slip {
  position: relative; display: grid; justify-items: center; gap: .1rem;
  border: 2px dashed var(--line-strong); border-radius: var(--r-zone);
  padding: 2rem 1.25rem; margin: .35rem 0 .75rem;
  background: var(--card-2); text-align: center; cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease,
              transform .15s ease;
}
.slip:hover { border-color: var(--link); background: var(--accent-soft); }
.slip-ikon { width: 2.5rem; height: 2.5rem; color: var(--link); opacity: .85; }
.slip-hoved { margin: .4rem 0 0; font-size: 1.05rem; font-weight: 600; color: var(--ink); }
.slip-under { margin: .15rem 0 0; color: var(--mut); font-size: .875rem; }

/* The styled stand-in for the file input. `.knap-fil` and not `.knap`, because
   `.knap` carries a top margin meant for form footers.

   OUTLINED, not filled: the submit button below is the page's one filled action,
   and when this was filled in the same blue the two competed and neither read as
   the thing to press. Choosing a file is a step on the way; proposing the route is
   the action. */
.knap-fil {
  margin-top: .9rem; display: inline-block; font-weight: 600; cursor: pointer;
  padding: .5rem 1.15rem; border-radius: var(--r-kontrol);
  background: var(--card); color: var(--link); border: 1px solid var(--line-strong);
}
.slip:hover .knap-fil { border-color: var(--link); background: var(--accent-soft); }
/* The focus ring has to follow the CLIPPED input, or a keyboard user tabs to
   something they cannot see. */
.slip:focus-within .knap-fil { outline: 3px solid var(--link); outline-offset: 3px; }

/* Dragging over: colour is never the only signal — the border goes solid, the
   zone lifts, and the overlay below states it in words. */
.slip.over {
  border-style: solid; border-color: var(--link);
  background: var(--accent-soft); transform: translateY(-1px);
}
.slip.modtog { border-style: solid; border-color: var(--enig); background: var(--enig-bg); }

/* --- the full-window drag overlay ---------------------------------------- */
/* Shown the moment a file drag enters the window, because the honest instruction
   is "anywhere on the page" and a zone-shaped affordance says the opposite.
   `pointer-events: none` throughout: the document handles the drop, and an overlay
   that swallowed it would break the very gesture it advertises. */
.drop-overlay {
  position: fixed; inset: 0; z-index: 50; display: none;
  place-items: center; padding: 2rem;
  background: var(--overlay); backdrop-filter: blur(3px);
  pointer-events: none;
}
.drop-overlay.vis { display: grid; }
.drop-overlay-kort {
  background: var(--card); border: 3px dashed var(--link); border-radius: var(--r-zone);
  padding: 2.5rem 3rem; text-align: center; max-width: 30rem;
  animation: slip-ind .18s ease-out;
}
.drop-overlay-ikon { width: 3.5rem; height: 3.5rem; color: var(--link); }
.drop-overlay-hoved {
  margin: .75rem 0 .2rem; font-size: 1.5rem; font-weight: 700; color: var(--ink);
}
.drop-overlay-under { margin: 0; color: var(--mut); }
@keyframes slip-ind {
  from { opacity: 0; transform: scale(.96); }
  to   { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .drop-overlay-kort { animation: none; }
  .slip { transition: none; }
}

/* --- the staged file list ------------------------------------------------- */
.valgte {
  list-style: none; padding: 0; margin: .5rem 0; font-size: .9375rem;
  border: 1px solid var(--line); border-radius: var(--r-kort); overflow: hidden;
}
.valgte li {
  display: flex; gap: .6rem; align-items: center;
  padding: .5rem .75rem; border-bottom: 1px solid var(--line);
  background: var(--card);
}
.valgte li:last-child { border-bottom: 0; }
.valgte li .fil-ikon { width: 1.15rem; height: 1.15rem; color: var(--mut); flex: none; }
.valgte li .navn { flex: 1; word-break: break-all; }
.valgte li .stoerrelse { color: var(--mut); font-variant-numeric: tabular-nums; }
.valgte li.advarer { background: var(--gennemsyn-bg); }
.valgte li.advarer .stoerrelse, .valgte li.advarer .fil-ikon { color: var(--gennemsyn); }
.valgte .fjern {
  font: inherit; line-height: 1; cursor: pointer; padding: .2rem .5rem; flex: none;
  color: var(--mangler); background: transparent;
  border: 1px solid var(--line-strong); border-radius: var(--r-kontrol);
}
.valgte .fjern:hover { border-color: var(--mangler); background: var(--mangler-bg); }
.hjaelp.advarer { color: var(--gennemsyn); font-weight: 600; }
button.ryd {
  font: inherit; font-size: .8125rem; cursor: pointer; padding: .15rem .6rem;
  margin-left: .4rem; color: var(--link); background: transparent;
  border: 1px solid var(--line-strong); border-radius: var(--r-kontrol);
}
button.ryd:hover { border-color: var(--link); }

/* --- route-candidate feedback -------------------------------------------- */
.rutefeedback { margin-top: 2rem; }
.rutekandidater { display: grid; gap: .85rem; }
.rutekandidat {
  padding: .9rem 1rem; background: var(--card);
  border: 1px solid var(--line); border-radius: var(--r-kort);
}
/* Three flex children under `space-between` left "modellens foerstevalg" adrift
   in the middle of the row, reading as if it belonged to neither the title nor
   the edit link. It describes the CARD, so it is grouped with the title and only
   the edit link is pushed to the far edge. */
.rutekandidat-hoved {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.rutekandidat-titel {
  display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap;
}
.rutekandidat h3 { margin: 0; font-size: 1rem; }
.kandidatkaede {
  display: flex; align-items: stretch; flex-wrap: wrap; gap: .45rem;
  list-style: none; padding: 0; margin: .75rem 0;
}
.kandidatkaede li {
  position: relative; padding: .35rem .65rem; border-radius: var(--r-kontrol);
  border: 1px solid var(--line-strong); background: var(--card-2);
}
.kandidatkaede li:not(:last-child)::after {
  content: "→"; position: absolute; right: -.55rem; top: 50%;
  z-index: 1; transform: translateY(-50%); color: var(--mut);
  background: var(--card); padding: 0 .05rem;
}
.kandidatkaede strong, .kandidatkaede span { display: block; }
.kandidatkaede span { color: var(--mut); font-size: .75rem; }
.feedback-form fieldset { border: 0; padding: 0; margin: .3rem 0 0; }
.feedback-form legend {
  margin-bottom: .35rem; color: var(--mut); font-size: .8125rem;
}
button.feedback-knap {
  margin: 0 .35rem .35rem 0; padding: .4rem .75rem;
  color: var(--ink); background: var(--card);
  border: 1px solid var(--line-strong);
}
button.feedback-knap:hover { border-color: var(--ink-soft); }
button.feedback-knap:focus-visible { outline: 3px solid var(--link); outline-offset: 2px; }
button.feedback-correct.valgt {
  color: var(--enig); background: var(--enig-bg); border-color: var(--enig);
}
button.feedback-almost_correct.valgt {
  color: var(--overskydende); background: var(--overskydende-bg);
  border-color: var(--overskydende);
}
button.feedback-not_correct.valgt {
  color: var(--mangler); background: var(--mangler-bg); border-color: var(--mangler);
}
button.feedback-knap:disabled { cursor: wait; opacity: .62; }
.feedback-gemt { margin: .25rem 0 0; }

/* --- choosing a route, and building one ---------------------------------- */
/* Existing palette variables only: the contrast and light/dark parity tests
   cover the declared set, so a new --name would need adding to all three theme
   blocks to stay covered. */
.rutekandidat-valg {
  display: flex; align-items: center; gap: .45rem;
  margin: .5rem 0 0; font-weight: 600;
}
.rutekandidat-valg input { width: 1.05rem; height: 1.05rem; }
/* The CHOSEN card, kept visually distinct from a chosen RATING button: one is a
   decision about the route, the other an opinion about it. */
.rutekandidat.valgt-rute { border-color: var(--klar); border-width: 2px; }
.rutekandidat-ingen { border-style: dashed; }
/* Quiet tier. It opens the builder rather than committing anything, and as an
   underlined blue link it drew more eye than the radio that actually chooses the
   route this card shows. */
a.blyant {
  font-size: .8125rem; white-space: nowrap; text-decoration: none;
  color: var(--mut); font-weight: 600; padding: .2rem .4rem;
  border-radius: var(--r-kontrol); margin: -.2rem -.4rem;
}
a.blyant:hover { color: var(--ink); background: var(--card-2); }
a.blyant:focus-visible { outline: 2px solid var(--link); outline-offset: 1px; }
.valgt-boks {
  padding: .75rem 1rem; margin: 0 0 1rem;
  background: var(--enig-bg); border: 1px solid var(--enig); border-radius: var(--r-kort);
}
.valgt-boks h3 { margin: 0 0 .35rem; font-size: 1rem; }
.valg-form { margin-top: 1rem; display: flex; gap: .6rem; flex-wrap: wrap; }
button.fortryd {
  padding: .45rem .9rem; color: var(--ink); background: var(--card);
  border: 1px solid var(--line-strong);
}
button.fortryd:hover { border-color: var(--ink-soft); }
/* SECONDARY. On --card rather than --card-2: sitting beside the primary on a
   card of its own, the filled grey read as heavier than the button that actually
   commits the choice. */
a.knap {
  display: inline-block; padding: .45rem .9rem; border-radius: var(--r-kontrol);
  color: var(--ink); background: var(--card);
  border: 1px solid var(--line-strong); text-decoration: none;
}
a.knap:hover { border-color: var(--ink-soft); background: var(--card-2); }
a.knap:focus-visible { outline: 3px solid var(--link); outline-offset: 2px; }
.rette.byg select { font: inherit; padding: .3rem .45rem; max-width: 22rem; }
.rette.byg td.flyt { white-space: nowrap; }
button.flyt-knap {
  padding: .2rem .45rem; color: var(--ink); background: var(--card);
  border: 1px solid var(--line-strong);
}
button.flyt-knap:disabled { opacity: .4; cursor: default; }
.rettelse-forslag {
  margin-top: 1rem; padding: .75rem 1rem;
  background: var(--card-2); border: 1px solid var(--line); border-radius: var(--r-kort);
}

/* --- the corrections editor (FRONTEND.md 6) ------------------------------ */
.rette { width: auto; min-width: 28rem; }
.rette input[type="text"] {
  font: inherit; padding: .3rem .45rem; color: var(--ink);
  background: var(--card); border: 1px solid var(--line-strong); border-radius: var(--r-kontrol);
}
.rette input[type="text"]:focus-visible { outline: 2px solid var(--link); }
.rette td.tal input { text-align: right; font-variant-numeric: tabular-nums; }
.rette .fjern {
  font: inherit; line-height: 1; cursor: pointer; padding: .25rem .5rem;
  color: var(--mangler); background: var(--mangler-bg);
  border: 1px solid var(--mangler); border-radius: var(--r-kontrol);
}
#tilfoej {
  font: inherit; cursor: pointer; padding: .35rem .7rem;
  color: var(--ink); background: var(--card-2);
  border: 1px dashed var(--line-strong); border-radius: var(--r-kontrol);
}
.rette-felter { display: flex; gap: 1rem; flex-wrap: wrap; margin: .75rem 0; }
.rette-felter label { font-size: .8125rem; color: var(--mut); display: block; }
.rette-felter input {
  display: block; font: inherit; margin-top: .15rem; padding: .35rem .5rem;
  min-width: 16rem; color: var(--ink); background: var(--card);
  border: 1px solid var(--line-strong); border-radius: var(--r-kontrol);
}
/* PRIMARY, and the same control as the front page's submit: both commit
   something, so they must not be two different blues. It carried --link on
   --card, which is also the colour of every ordinary link on the page. */
button.gem {
  font: inherit; font-weight: 600; cursor: pointer;
  padding: .58rem 1.4rem; border: 0; border-radius: var(--r-kontrol);
  color: var(--handling-tekst); background: var(--handling);
  box-shadow: inset 0 -2px 0 var(--handling-kant);
  transition: transform .06s ease, box-shadow .06s ease, background-color .12s ease;
}
button.gem:hover { background: var(--handling-kant); }
button.gem:active {
  transform: translateY(2px); box-shadow: inset 0 0 0 var(--handling-kant);
}
button.gem:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) {
  button.gem { transition: none; }
  button.gem:active { transform: none; }
}
.kvittering {
  padding: .7rem .9rem; border-radius: var(--r-kort); margin: .75rem 0;
  color: var(--enig); background: var(--enig-bg);
  border-left: 4px solid var(--enig);
}

/* --- footer ------------------------------------------------------------- */
.bund {
  max-width: 62rem; margin: 0 auto; padding: 1rem 1.25rem 2rem;
  color: var(--mut); font-size: .9rem; border-top: 1px solid var(--line);
}
.bund a { color: var(--mut); text-decoration: none; border-bottom: 1px solid var(--line-strong); }
.bund a:hover { color: var(--ink); border-bottom-color: var(--ink); }

/* --- the declined near-misses --------------------------------------------- */
/* Collapsed by default: it is the most useful thing on the page for a planner who
   suspects the model was too cautious, and noise for everyone else. */
.fravalgt { margin: .75rem 0 1rem; }
.fravalgt > summary {
  cursor: pointer; font-weight: 600; color: var(--ink-soft);
  padding: .35rem 0;
}
.fravalgt > summary:hover { color: var(--link); }
.fravalgt table { width: auto; min-width: 22rem; margin-top: .4rem; }

/* --- the detail blocks below the three routes ----------------------------- */
/* The three candidate routes are the decision this page exists for, so
   everything else is collapsed behind a summary rather than deleted: the route
   table, the caveats, the comparable past parts and the corrections editor are
   all still one click away, and still render EXPANDED when there are no
   candidate cards (an ERP lookup), because then the route table is the page.
   Existing palette variables only, per the note above. */
.detaljer-overskrift {
  margin-top: 2.25rem; padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.detalje { margin: .35rem 0; border-bottom: 1px solid var(--line); }
.detalje > summary {
  cursor: pointer; font-weight: 600; color: var(--ink-soft);
  padding: .55rem 0;
}
.detalje > summary:hover { color: var(--link); }
.detalje[open] > summary { color: var(--ink); }
/* The <summary> already carries these words. Leaving the heading in place would
   print the same label twice, so it is dropped from the rendered page and the
   accessibility tree together -- unlike a CONTROL, where this file's own rule is
   clip-never-display-none, a duplicated label loses nothing by being removed. */
.detalje > h2 { display: none; }

/* A rating is an opinion about a route; choosing one is a decision. Repeated on
   every card, the three rating buttons made each card read as a form rather than
   as a route, so they collapse to one line -- opened by default once a rating
   exists, so a planner can still see and change their own answer. */
.vurder { margin: .5rem 0 0; }
.vurder > summary {
  cursor: pointer; color: var(--mut); font-size: .8125rem; padding: .2rem 0;
}
.vurder > summary:hover { color: var(--link); }
.vurder[open] > summary { color: var(--ink-soft); }
