:root {
  --bg: #f5f6f8;
  --card: #ffffff;
  --ink: #1c2430;
  --muted: #6b7684;
  --line: #e2e6ec;
  --accent: #1f5f8b;
  --accent-soft: #eaf2f8;
  --good: #2e7d5b;
  --warn: #b8860b;
  --bad: #b4453a;
  --radius: 8px;
}

* { box-sizing: border-box; }

/* hidden-attributten skjuler via display:none i browserens egen stilart, men
   enhver display-regel her i filen vinder over den. Uden dette forbliver fx
   login-boksen (display:grid) synlig, selv når koden har skjult den. */
[hidden] { display: none !important; }

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

h1, h2, h3 { margin: 0 0 .4rem; font-weight: 600; }
h2 { font-size: 1.05rem; }
code { font-family: Consolas, monospace; font-size: .9em; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.error { color: var(--bad); }

/* ---------- Login ---------- */
.login-screen {
  min-height: 100vh; display: grid; place-items: center; padding: 1rem;
}
.login-box {
  background: var(--card); padding: 2rem; border-radius: var(--radius);
  border: 1px solid var(--line); width: min(400px, 100%);
  display: flex; flex-direction: column; gap: .75rem;
}
.login-box input {
  padding: .6rem .7rem; border: 1px solid var(--line);
  border-radius: 6px; font-size: 1rem;
}

/* ---------- Ramme ---------- */
header {
  display: flex; align-items: center; gap: 1.5rem;
  background: var(--card); border-bottom: 1px solid var(--line);
  padding: .6rem 1.25rem; position: sticky; top: 0; z-index: 10;
  flex-wrap: wrap;
}
.brand { font-weight: 600; display: flex; align-items: center; gap: .6rem; }
/* Logoet har sit eget højde/bredde-forhold (43,9 x 56,9) - lad bredden følge. */
.brand-mark { height: 24px; width: auto; display: block; }
/* align-self er nødvendig: login-boksen er en kolonne-flexbox, og uden den
   strækkes billedet til hele bredden i stedet for at beholde sit forhold. */
.login-mark { height: 44px; width: auto; align-self: flex-start; margin-bottom: .3rem; }
header nav { display: flex; gap: .25rem; flex: 1; flex-wrap: wrap; }
header nav button {
  background: none; border: none; padding: .45rem .8rem; cursor: pointer;
  border-radius: 6px; font: inherit; color: var(--muted);
}
header nav button:hover { background: var(--bg); }
header nav button.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.header-right { display: flex; align-items: center; gap: .75rem; }

main { padding: 1.25rem; max-width: 1500px; margin: 0 auto; }

.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.15rem; margin-bottom: 1.1rem;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
@media (max-width: 950px) { .grid-2 { grid-template-columns: 1fr; } }

/* ---------- Knapper ---------- */
button {
  font: inherit; cursor: pointer; border-radius: 6px;
  border: 1px solid var(--accent); background: var(--accent); color: #fff;
  padding: .45rem .9rem;
}
button:hover { filter: brightness(1.08); }
button.secondary { background: #fff; color: var(--accent); }
button.link {
  background: none; border: none; color: var(--accent);
  text-decoration: underline; padding: .2rem;
}
button.tiny { padding: .2rem .5rem; font-size: .82rem; }

/* ---------- Nøgletal ---------- */
.kpi-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: .8rem; margin-bottom: 1.1rem;
}
.kpi {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .8rem 1rem;
}
.kpi .value { font-size: 1.5rem; font-weight: 600; }
.kpi .label { color: var(--muted); font-size: .82rem; }
.kpi.alert .value { color: var(--bad); }
.kpi.ok .value { color: var(--good); }

/* ---------- Tabeller ---------- */
table { border-collapse: collapse; width: 100%; font-size: .9rem; }
th, td { text-align: left; padding: .4rem .55rem; border-bottom: 1px solid var(--line); }
th {
  position: sticky; top: 0; background: var(--card);
  font-weight: 600; font-size: .82rem; color: var(--muted);
  text-transform: uppercase; letter-spacing: .02em;
  white-space: nowrap;
}
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--accent); background: var(--accent-soft); }
th.sorted { color: var(--accent); }

/* Pilen fylder altid, så kolonnen ikke hopper i bredden ved sortering. */
.sort-arrow { display: inline-block; width: .9em; text-align: center; opacity: .35; }
.sort-arrow::after { content: "↕"; }
th.sorted .sort-arrow { opacity: 1; }
th.sorted[data-dir="asc"] .sort-arrow::after { content: "↑"; }
th.sorted[data-dir="desc"] .sort-arrow::after { content: "↓"; }
tbody tr:hover { background: var(--accent-soft); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tr.clickable { cursor: pointer; }

.scroll-box { max-height: 340px; overflow: auto; }
.scroll-box.tall { max-height: 62vh; }

/* ---------- Dækningsbjælker ---------- */
.cov-row {
  display: grid; grid-template-columns: 1fr 92px 60px;
  align-items: center; gap: .6rem; padding: .3rem 0;
  border-bottom: 1px solid var(--line);
}
.bar { background: var(--bg); border-radius: 4px; height: 8px; overflow: hidden; }
.bar > div { height: 100%; background: var(--good); }
.bar.partial > div { background: var(--warn); }
.bar.none > div { background: var(--bad); }

/* ---------- Filtre ---------- */
.filters {
  display: flex; gap: .6rem; flex-wrap: wrap; align-items: center;
  margin: .7rem 0 .9rem;
}
.filters input, .filters select {
  padding: .4rem .55rem; border: 1px solid var(--line);
  border-radius: 6px; font: inherit;
}
.filters input[type=search] { min-width: 240px; }
.filters label { display: flex; align-items: center; gap: .35rem; font-size: .88rem; }
.filters label.check { gap: .3rem; }

/* ---------- Til/fra-kontakt (rediger stamdata) ---------- */
.switch { display: inline-flex; align-items: center; gap: .45rem; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 38px; height: 21px; border-radius: 20px; background: #c9d0d8;
  position: relative; transition: background .15s; flex: none;
}
.switch-knob {
  position: absolute; top: 2px; left: 2px; width: 17px; height: 17px;
  border-radius: 50%; background: #fff; transition: transform .15s;
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
}
.switch input:checked + .switch-track { background: var(--bad); }
.switch input:checked + .switch-track .switch-knob { transform: translateX(17px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--accent); outline-offset: 2px; }
.switch-label { font-size: .88rem; }
.switch input:checked ~ .switch-label { font-weight: 600; color: var(--bad); }

/* ---------- Låst første kolonne ----------
   Brede tabeller scrolles vandret, og uden dette forsvinder navnet ud til
   venstre, så man ikke kan se hvilken række man kigger på. Cellen skal have
   sin egen baggrund - ellers scroller de øvrige kolonner igennem den. */
table.sticky-first th:first-child,
table.sticky-first td:first-child {
  position: sticky;
  left: 0;
  background: var(--card);
  border-right: 1px solid var(--line);
}
table.sticky-first td:first-child { z-index: 1; }
/* Hjørnecellen ligger over både den låste kolonne og den låste overskriftsrække. */
table.sticky-first th:first-child { z-index: 4; }
table.sticky-first tbody tr:hover td:first-child { background: var(--accent-soft); }

/* Stamdata-tabellen har faste kolonnebredder, så navnekolonnen ikke klemmes
   sammen, når en filtrering efterlader få rækker. */
table.grid { table-layout: fixed; }
table.grid td {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
table.grid td:has(.cell-edit) { overflow: visible; }
/* Det navn rapporterne bruger, når visningsnavnet står tomt. */
.fallback { color: var(--muted); font-style: italic; }

/* Redigerbare celler markeres tydeligt, så man ved hvornår data kan ændres. */
table.editable td.editable { cursor: text; }
table.editable td.editable:hover { background: #fff9e0; box-shadow: inset 0 0 0 1px var(--warn); }
table.editable td.locked { color: var(--muted); background: var(--bg); }
td.saving { opacity: .5; }
td input.cell-edit, td select.cell-edit {
  width: 100%; box-sizing: border-box; font: inherit; padding: .1rem .25rem;
  border: 1px solid var(--accent); border-radius: 3px; background: #fff;
}

/* ---------- Afkrydsningsfiltre (fx risikoniveau) ---------- */
.chipset-row {
  display: flex; align-items: baseline; gap: .7rem;
  flex-wrap: wrap; margin: 0 0 .9rem;
}
.chipset-label { font-size: .82rem; color: var(--muted); }
.chipset { display: flex; gap: .4rem; flex-wrap: wrap; }

.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .22rem .6rem; border: 1px solid var(--line);
  border-radius: 20px; font-size: .85rem; cursor: pointer;
  background: var(--card); user-select: none;
}
.chip:hover { border-color: var(--accent); }
.chip input { margin: 0; cursor: pointer; }
/* :has lader selve brikken vise, om den er valgt - ikke kun det lille felt. */
.chip:has(input:checked) {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
  font-weight: 600;
}

.pill {
  background: var(--accent-soft); color: var(--accent);
  padding: .2rem .6rem; border-radius: 20px; font-size: .82rem; font-weight: 600;
}
.tag {
  display: inline-block; padding: .1rem .45rem; border-radius: 4px;
  font-size: .78rem; background: var(--bg); color: var(--muted);
}
.tag.bad { background: #fbeceb; color: var(--bad); }
.tag.good { background: #eaf5ef; color: var(--good); }

.pos { color: var(--good); }
.neg { color: var(--bad); }

/* ---------- Skuffe (produktdetalje) ---------- */
#drawer-backdrop {
  position: fixed; inset: 0; background: rgba(20,28,38,.35); z-index: 20;
}
#drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(720px, 96vw);
  background: var(--card); border-left: 1px solid var(--line);
  z-index: 21; overflow: auto; padding: 1.1rem 1.3rem;
  box-shadow: -4px 0 24px rgba(20,28,38,.12);
}
.drawer-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 1rem; margin-bottom: 1rem; border-bottom: 1px solid var(--line);
  padding-bottom: .8rem;
}
.field-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: .7rem; margin-bottom: .9rem;
}
.field label { display: block; font-size: .8rem; color: var(--muted); margin-bottom: .15rem; }
.field input, .field select {
  width: 100%; padding: .4rem .5rem; border: 1px solid var(--line);
  border-radius: 6px; font: inherit;
}
.field input:disabled { background: var(--bg); color: var(--muted); }

/* Lille formular i produktvinduet, fx til at sætte ÅOP. */
.inline-form {
  display: flex; align-items: flex-end; gap: .7rem; flex-wrap: wrap;
  padding: .7rem .8rem; background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.inline-form label { display: flex; flex-direction: column; gap: .2rem;
                     font-size: .8rem; color: var(--muted); }
.inline-form input {
  padding: .35rem .5rem; border: 1px solid var(--line);
  border-radius: 6px; font: inherit; color: var(--ink);
}
.inline-form input[type=text] { width: 8rem; }

.section-title {
  margin: 1.2rem 0 .5rem; font-weight: 600; font-size: .95rem;
  padding-bottom: .3rem; border-bottom: 1px solid var(--line);
}

/* ---------- Allokeringsbjælker ----------
   De tre hovedgruppefarver er valideret mod kravene til farveblindhed og
   kontrast (worst all-pairs deltaE 9.2 CVD / 24.0 normalt syn). Aktivklasserne
   selv vises som tal i tabellen - ti farver i én stak kan ikke skelnes. */
:root {
  --bucket-aktier: #2a78d6;
  --bucket-obligationer: #eb6834;
  --bucket-alternativer: #1baf7a;
}

.legend { display: flex; gap: 1.1rem; flex-wrap: wrap; margin: .5rem 0 .9rem; }
.legend span { display: flex; align-items: center; gap: .4rem; font-size: .85rem; }
.legend i {
  width: 12px; height: 12px; border-radius: 3px; display: inline-block;
}

.alloc-row {
  display: grid; grid-template-columns: minmax(180px, 1fr) 3fr;
  gap: .8rem; align-items: center; padding: .28rem 0;
  border-bottom: 1px solid var(--line);
}
.alloc-row:hover { background: var(--accent-soft); }
.alloc-name { font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.alloc-name .sub { color: var(--muted); font-size: .78rem; }

/* 2px mellemrum mellem segmenterne, så de ikke smelter sammen */
.alloc-bar { display: flex; gap: 2px; height: 22px; }
.alloc-bar > div {
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: .72rem; font-variant-numeric: tabular-nums;
  overflow: hidden; white-space: nowrap;
}
.alloc-bar > div:first-child { border-radius: 4px 0 0 4px; }
.alloc-bar > div:last-child { border-radius: 0 4px 4px 0; }
.alloc-bar .b-aktier { background: var(--bucket-aktier); }
.alloc-bar .b-obligationer { background: var(--bucket-obligationer); }
.alloc-bar .b-alternativer { background: var(--bucket-alternativer); }

.alloc-row.average { background: var(--bg); font-weight: 600; }
.alloc-row.average .alloc-name { font-weight: 600; }

/* ---------- Graf ---------- */
.spark { width: 100%; height: 90px; }
.spark rect { fill: var(--accent); }
.spark rect.neg { fill: var(--bad); }

/* ---------- Besked ---------- */
#toast {
  position: fixed; bottom: 1.2rem; left: 50%; transform: translateX(-50%);
  background: var(--ink); color: #fff; padding: .6rem 1.1rem;
  border-radius: 20px; z-index: 40; font-size: .9rem;
}
#toast.bad { background: var(--bad); }

.empty { color: var(--muted); padding: 1rem 0; font-style: italic; }
.loading { color: var(--muted); padding: 1rem 0; }

/* ---------- Underfaner ----------
   Risikomærkning, ratings og AUM hører sammen, men er tre forskellige
   tabeller. De deler én fane i topmenuen og skiftes ud her, så topmenuen ikke
   vokser til femten knapper. */
.subnav {
  display: flex; gap: .2rem; flex-wrap: wrap;
  border-bottom: 1px solid var(--line); margin-bottom: 1.1rem;
}
.subnav button {
  background: none; border: none; border-bottom: 2px solid transparent;
  border-radius: 0; color: var(--muted); padding: .5rem .9rem; font: inherit;
  margin-bottom: -1px;
}
.subnav button:hover { color: var(--ink); }
.subnav button.active {
  color: var(--accent); border-bottom-color: var(--accent); font-weight: 600;
}

/* ---------- Foldbart afsnit ---------- */
.foldout { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: .7rem; }
.foldout summary {
  cursor: pointer; color: var(--accent); font-size: .88rem; user-select: none;
}
.foldout summary:hover { text-decoration: underline; }
.foldout > div { margin-top: .7rem; }

/* ---------- Formular inde i et kort (fx nyt produkt) ---------- */
.inset-form {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem; margin-bottom: 1rem;
}
.inset-form button { margin-right: .5rem; }

/* ---------- Risikomærkningens matrix ----------
   66 rækker gange 30 serier. Uden en farveskala er det bare et hav af tal;
   med den kan man se, hvor et produkt ligger, uden at læse hver celle.
   Skalaen går fra 1 (lav risiko) til 7 (høj) efter F&P's inddeling. */
/* Tallene centreres. Højrestillet ville et tal stå klods op ad den NÆSTE
   kolonnes overskrift, og med 33 kolonner er det nok til at læse forkert. */
.matrix td.rl { text-align: center; font-variant-numeric: tabular-nums; }
.matrix th { text-align: center; }
.matrix th:first-child, .matrix td:first-child { text-align: left; }

/* Farveskalaen er absolut: et 4-tal har samme farve uanset hvad der ellers
   står i tabellen. Halve trin, fordi risikotallene inden for én profil ligger
   tæt - med hele trin ville hele tabellen få samme farve.
   Klassen er risikotallet gange to, altså rl-h9 = 4,5. */
.rl-h2  { background: #e4f3ea; }
.rl-h3  { background: #e9f4e8; }
.rl-h4  { background: #eef5e6; }
.rl-h5  { background: #f4f6e4; }
.rl-h6  { background: #f9f6e2; }
.rl-h7  { background: #fdf4de; }
.rl-h8  { background: #fdefd9; }
.rl-h9  { background: #fde8d4; }
.rl-h10 { background: #fbe1d1; }
.rl-h11 { background: #fadacd; }
.rl-h12 { background: #f8d2c9; }
.rl-h13 { background: #f5cac4; }
.rl-h14 { background: #f2c1bd; }
/* Aggregaterne (F&P-gennemsnit, øvre og nedre grænse) er
   sammenligningsgrundlag, ikke produkter - de skal kunne skelnes. */
.matrix th.aggregate, .matrix td.aggregate { font-style: italic; color: var(--muted); }
.matrix th.aggregate { border-left: 2px solid var(--line); }
.matrix td.aggregate { border-left: 2px solid var(--line); }

/* Risikoskalaen under matricen. */
.scale-row { display: flex; gap: .3rem; flex-wrap: wrap; }

/* ---------- Ændringer i en indlæsning ---------- */
.change-detail { color: var(--muted); font-size: .82rem; }
.arrow { color: var(--muted); padding: 0 .3rem; }

/* ---------- Advarselsbjælke ----------
   Til det, der gør resten af siden utroværdig - fx at serveren kører en anden
   kode end den, browseren har hentet. Skal ikke kunne overses. */
.banner {
  background: #fbeceb; border-bottom: 2px solid var(--bad); color: var(--bad);
  padding: .8rem 1.25rem; font-size: .92rem;
  position: sticky; top: 0; z-index: 15;
}
.banner b { display: block; margin-bottom: .15rem; }
.banner code {
  background: #fff; padding: .05rem .3rem; border-radius: 3px;
}

/* Sammensætningen af et benchmark ("70A/25O/5Alt/42FX") eller den aktivklasse,
   det dækker. Står i stamdata i samme felt som risikoniveauet, men er ikke en
   risikoprofil - og skal derfor heller ikke se ud som en. */
.composition {
  font-family: Consolas, monospace; font-size: .82rem; color: var(--muted);
  background: var(--bg); padding: .05rem .35rem; border-radius: 4px;
}

/* En produkttype uden rækker bag sig, når de øvrige filtre er lagt på.
   Brikken skjules - der er ikke noget at hente ved at klikke den til, og en
   række knapper, der ikke gør noget, gør kun filterrækken sværere at læse.
   Afkrydsningen bliver stående i DOM'en, så tilstanden er intakt, når typen
   kommer i spil igen. */
.chip.empty { display: none; }

/* Summen over dækningen. Uden den kunne man ikke se, om oversigten dækkede
   alle aktive produkter - og det gjorde den ikke: 575 af 690. */
.cov-total {
  font-size: .9rem; font-weight: 600; color: var(--good);
  padding: .15rem 0 .6rem; border-bottom: 1px solid var(--line);
  margin-bottom: .5rem;
}
.cov-total.alert { color: var(--bad); }
