:root {
  --bg: #f4f5f8;
  --panel: #ffffff;
  --panel-2: #fafbfc;
  --ink: #1a1f2b;
  --ink-soft: #5a6473;
  --line: #d5d9e2;
  /* Rahmen von Bedienelementen (Felder, Auswahllisten, Knöpfe): mindestens 3:1 gegen den
     Untergrund, damit man sie als Element erkennt. --line bleibt den Trennlinien und Karten. */
  --line-control: #8891a1;
  --accent: #4f46e5;
  --accent-soft: #eef0fe;
  /* Hellmodus auf WCAG AA gebracht: die früheren Töne lagen bei 3,2-3,8:1 auf Weiß
     bzw. auf den weichen Flächen der Badges; jetzt 4,5-5,4:1 */
  --pos: #0f8259;
  --pos-soft: #f0faf5;
  --neg: #c92941;
  --neg-soft: #fef3f5;
  --warn: #9a6414;
  --warn-soft: #fdf6e8;
  /* Serienfarben für invertierte Flächen (Tooltips): jeweils die Werte des anderen
     Themes, sonst wäre das dunkle Indigo auf dunklem Grund nicht lesbar */
  --accent-inv: #7c74ff;
  --pos-inv: #34d399;
  --neg-inv: #f77;
  --logo-2: #8b5cf6; /* zweiter Ton des Logo-Verlaufs */
  /* Akzenttöne der Eingabe-Sektionen */
  --sec-objekt: #6366f1; /* Indigo */
  --sec-nk: #0ea5e9; /* Sky */
  --sec-miete: #10b981; /* Emerald */
  --sec-bewirt: #f59e0b; /* Amber */
  --sec-finanz: #8b5cf6; /* Violet */
  --sec-steuer: #f43f5e; /* Rose */
  --sec-prognose: #14b8a6; /* Teal */
  --shadow: 0 1px 2px rgba(20, 25, 40, 0.04), 0 8px 24px rgba(20, 25, 40, 0.06);
  --radius: 16px;
  --font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0e1117;
  --panel: #171b24;
  --panel-2: #1d222d;
  --ink: #e8ebf2;
  --ink-soft: #99a2b3;
  --line: #363d4b;
  --line-control: #666f81;
  --accent: #7c74ff;
  --accent-soft: #23233f;
  --pos: #34d399;
  --pos-soft: #123227;
  --neg: #f77;
  --neg-soft: #33191f;
  --warn: #e0a13a;
  --warn-soft: #33290f;
  --accent-inv: #4f46e5;
  --pos-inv: #0f8259;
  --neg-inv: #c92941;
  --logo-2: #a78bfa;
  --sec-objekt: #8b93ff;
  --sec-nk: #38bdf8;
  --sec-miete: #34d399;
  --sec-bewirt: #fbbf24;
  --sec-finanz: #a78bfa;
  --sec-steuer: #fb7185;
  --sec-prognose: #2dd4bf;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 10px 30px rgba(0, 0, 0, 0.35);
}

* {
  box-sizing: border-box;
}

/* Alle Elemente mit Tooltip: dezent gestrichelte Unterstreichung + Hilfe-Cursor */
abbr[data-tip],
.help,
.risiken-lbl[data-tip],
.hint[data-tip]:not(:empty) {
  text-decoration: underline dashed;
  text-decoration-color: color-mix(in srgb, var(--ink-soft) 45%, transparent);
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  cursor: help;
}
/* KPI-Label mit rechtsbündigem Zusatz (z. B. "Ziel ≥ 1,2", "90 % KP") */
.kpi span.spread {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 6px;
}

body {
  margin: 0;
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  line-height: 1.45;
}

/* ---------- Topbar ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 16px;
  padding: 7px 20px;
  background: color-mix(in srgb, var(--panel) 86%, transparent);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.brand {
  flex: 1 1 0; /* gleich breite Flanke wie .topbar-actions -> Label dazwischen mittig */
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
/* Auswahl der Objektart (Eigentumswohnung, Mehrfamilienhaus) */
.topbar-scope {
  flex: 0 0 auto;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line-control);
  border-radius: 8px;
  padding: 6px 12px;
  cursor: pointer;
}
.topbar-scope:focus {
  outline: 0;
  border-color: var(--accent);
}
.logo {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--accent), var(--logo-2));
  color: #fff;
  font-size: 20px;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--accent) 45%, transparent);
}
.logo svg {
  width: 23px;
  height: 23px;
}
.brand h1 {
  margin: 0;
  font-size: 17px;
  line-height: 1.15;
  letter-spacing: -0.2px;
}
.tagline {
  margin: 0;
  font-size: 12px;
  line-height: 1.2;
  color: var(--ink-soft);
}
.topbar-actions {
  flex: 1 1 0; /* gleich breite Flanke wie .brand */
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.btn {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  border: 1px solid var(--line-control);
  background: var(--panel);
  padding: 8px 14px;
  border-radius: 10px;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s,
    transform 0.05s;
}
.btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.btn:active {
  transform: translateY(1px);
}
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.btn:disabled:hover {
  border-color: var(--line-control);
  color: var(--ink);
}
.btn.ghost {
  background: transparent;
}
.btn.icon {
  padding: 8px 11px;
  font-size: 16px;
}
.btn.small {
  padding: 7px 11px;
  font-size: 12.5px;
  white-space: nowrap;
}
.btn.icon-btn {
  font-size: 18px;
  line-height: 1;
}
.btn.small.icon-btn {
  padding: 5px 9px;
}

/* Tooltips für Elemente mit data-tip – invertiert zum Seitenhintergrund, damit sie sich klar
   abheben (hell = dunkler Tooltip, dunkel = heller). Sie ersetzen die nativen title-Tooltips;
   lange Texte brechen um.

   Ein einziges Element für alle Tooltips, am Fenster ausgerichtet. Früher trug jedes Element
   sein eigenes ::after: Das lag absolut positioniert im Dokument, verbreiterte damit die Seite
   (unter 800 px Fensterbreite lief sie um bis zu 233 px über) und wurde von jeder Karte mit
   overflow abgeschnitten. Dagegen half nur eine wachsende Zahl von Sonderregeln je Karte,
   Spalte und Fensterbreite. Ein fixiertes Element am <body> kennt beide Probleme nicht.
   Wohin der Kasten kommt, entscheidet tipPosition() in app.js aus dem Platz im Fenster. */
#tip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  background: var(--ink);
  color: var(--panel);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  white-space: pre-line; /* &#10; im Text erzwingt einen Umbruch */
  width: max-content;
  max-width: min(320px, 60vw);
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition:
    opacity 0.12s ease,
    transform 0.12s ease;
}
#tip[data-richtung="unten"] {
  transform: translateY(-4px);
}
#tip[data-offen] {
  opacity: 1;
  transform: translateY(0);
}
/* Pfeil zum Element; --pfeil ist sein Abstand von der linken Kante des Kastens */
#tip::after {
  content: "";
  position: absolute;
  left: var(--pfeil, 12px);
  margin-left: -5px;
  border: 5px solid transparent;
}
#tip[data-richtung="oben"]::after {
  top: 100%;
  border-top-color: var(--ink);
}
#tip[data-richtung="unten"]::after {
  bottom: 100%;
  border-bottom-color: var(--ink);
}

/* Solange ein Pflichtfeld leer ist, rechnet die App zwar, aber sie bewertet Lücken statt des
   Objekts - mit Kaufpreis und ohne Miete etwa "-463 €/Monat" in Rot. Deshalb verlieren die
   Zahlen im Ergebnis dort ihre Bewertungsfarbe. Statt jede der über fünfzig Stellen einzeln
   umzuschalten, werden hier die beiden Farbmarken neu belegt: Jede Regel, die var(--pos) oder
   var(--neg) nutzt, wird damit still neutral - Kacheln, Wasserfall, Tabellen und Prognose
   zugleich, in beiden Themes. Die Zahl bleibt sichtbar, nur das Urteil verschwindet.
   Gesetzt wird das Merkmal in render(); Verdict und Ampel schweigen zusätzlich im Klartext. */
.results[data-unbewertbar] {
  --pos: var(--ink);
  --neg: var(--ink);
  --pos-soft: var(--panel-2);
  --neg-soft: var(--panel-2);
}

/* ---------- Layout ---------- */
.layout {
  max-width: 1240px;
  margin: 0 auto;
  padding: 16px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: 16px;
  align-items: start;
}
@media (max-width: 900px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

/* Kein sticky: Der Effekt entstand nur bei ungleich hohen Spalten und kippte, sobald
   Eingabe-Sektionen ein- oder ausgeklappt wurden; die 56 px waren zudem geraten. */
.results {
  min-width: 0;
}
@media (max-width: 900px) {
  .results {
    position: static;
  }
}

/* Tönung der noch nötigen Felder. Ein blasses Gelb, wie ein Textmarker auf Papier - es sagt
   "hier fehlt noch etwas", ohne wie ein Fehler auszusehen. Im Dunkelmodus mit dem Panel
   gemischt, damit es nicht leuchtet. */
:root {
  --noetig-ton: color-mix(in srgb, #ffe600 13%, var(--panel-2));
}

/* Noch nötige Eingaben: Streifen am Feld, Beschriftung im Ton der Kachel. Bewusst nicht rot -
   ein leeres Feld ist keine Fehleingabe, sondern eine offene Aufgabe. Rot gehört im Projekt
   den Risiken, und das bewertet das Objekt, nicht das Formular. */
.field.noetig > .inp {
  /* Rahmen und Tönung statt eines Streifens an der Kante: Jede Kantenmarkierung folgt der
     Eckenrundung und sieht dann aus wie eine Klammer. So bleibt die Form des Feldes ganz. */
  border-color: var(--sec, var(--accent));
  background: var(--noetig-ton);
}
/* Der Fokus muss die Markierung überstimmen - sonst sieht man beim Tippen nicht, wo man ist */
.field.noetig > .inp:focus-within {
  border-color: var(--accent);
}
.field.noetig > span,
.field.noetig > .lblrow {
  color: var(--sec, var(--accent));
}

/* Dieselbe Aussage oben im Ergebnis - links steht, wo etwas fehlt, hier warum es zählt */
.hero-fehlt {
  flex-basis: 100%; /* eigene Zeile, nicht neben den Zahlen */
  margin: 0;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px;
  line-height: 1.45;
  text-align: center;
  color: var(--ink-soft);
}
/* Das Fazit schliesst die Kachel ab: Es fasst die Zahlen darüber zusammen, deshalb Trennlinie
   oben statt unten - anders als der Hinweis auf fehlende Felder, der vor dem Lesen gilt. */
.hero-fazit {
  flex-basis: 100%;
  margin: 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
  line-height: 1.45;
  text-align: center;
  color: var(--ink-soft);
}
.hero-fazit[hidden] {
  display: none;
}
.hero-fazit strong,
.hero-fehlt strong {
  color: var(--ink);
}
.hero-fehlt[hidden] {
  display: none;
}

/* ---------- Cards ---------- */
.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 13px 14px 14px;
  margin-bottom: 12px;
}
.card summary small,
.field span small {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  /* bewusst nicht opacity: die wirkt auf den gesamten Teilbaum und würde auch den
     Tooltip der enthaltenen Abkürzung blasser zeichnen als alle anderen */
  color: color-mix(in srgb, currentColor 80%, transparent);
}

/* Eingabe-Sektionen: dezenter Farbakzent (Streifen links + minimaler Tint).
   Die Töne kommen aus dem Variablensystem und sind im Dunkelmodus aufgehellt –
   der Indigo-Streifen war auf dem dunklen Panel sonst kaum zu erkennen. */
.inputs .card.sec-objekt {
  --sec: var(--sec-objekt);
}
.inputs .card.sec-nk {
  --sec: var(--sec-nk);
}
.inputs .card.sec-miete {
  --sec: var(--sec-miete);
}
.inputs .card.sec-bewirt {
  --sec: var(--sec-bewirt);
}
.inputs .card.sec-finanz {
  --sec: var(--sec-finanz);
}
.inputs .card.sec-steuer {
  --sec: var(--sec-steuer);
}
.inputs .card.sec-prognose {
  --sec: var(--sec-prognose);
}
.inputs .card[class*="sec-"] {
  background: color-mix(in srgb, var(--sec) 6%, var(--panel));
  box-shadow:
    inset 3px 0 0 var(--sec),
    var(--shadow);
}

/* ---------- Objektleiste ---------- */
.obj-bar {
  position: relative; /* Anker für den schwebenden .obj-status */
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
/* schwebt über den Icons, statt eine Zeile zu belegen – verschiebt nichts */
.obj-status {
  position: absolute;
  right: 0;
  bottom: calc(100% + 4px);
  z-index: 5;
  font-size: 11.5px;
  color: var(--ink-soft);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: var(--shadow);
  padding: 2px 8px;
  white-space: nowrap;
  pointer-events: none;
}
.obj-status:empty {
  display: none;
}
.obj-status.err {
  color: var(--neg);
}
.obj-select {
  flex: 1 1 150px;
  min-width: 120px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line-control);
  border-radius: 10px;
  padding: 8px 10px;
  cursor: pointer;
}
.obj-select:focus {
  outline: 0;
  border-color: var(--accent);
}
/* Die vier Symbole stehen in einer eigenen Gruppe mit nowrap: Sie brechen dadurch nur gemeinsam
   um, nie zwischen zwei Symbolen. Vorher hing das an der Breite, die der jeweilige Browser den
   Knöpfen gibt - auf dem iPhone rutschte das letzte allein nach unten, obwohl die Rechnung hier
   aufging. Die Schwelle liegt bei 560 px, damit auch breitere Knöpfe noch Platz haben. */
.obj-icons {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
}
@media (max-width: 560px) {
  .obj-select,
  .obj-icons {
    flex-basis: 100%;
  }
}
.obj-select.placeholder {
  color: var(--ink-soft);
}
/* Dropdown-Listen im Dark-Mode lesbar halten (native <option>) */
.inp select option,
.obj-select option,
.topbar-scope option {
  background-color: var(--panel);
  color: var(--ink);
}
/* D13: sonst überschreibt die Regel oben die Ausgrauung nicht wählbarer Einträge */
.topbar-scope option:disabled {
  color: var(--ink-soft);
}
.obj-select option[value=""] {
  color: var(--ink-soft);
}

/* Inline-Umschalter (z. B. brutto/netto) rechts im Eingabefeld */
.inp-select {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  background: transparent;
  border: 0;
  outline: 0;
  cursor: pointer;
  margin-left: 8px;
  padding-left: 8px;
  border-left: 1px solid var(--line-control);
}
/* schmale Einheiten-Selects (%/€) – Trenner weiter nach rechts */
#nichtumlmodus {
  width: 46px;
  flex: 0 0 auto;
}
/* "€/m²" braucht mehr Platz als "%" */
#kaltmietemodus {
  width: 68px;
  flex: 0 0 auto;
}

/* ---------- Fields ---------- */
.grid2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
/* Objekt: Kaufpreis/Wohnfläche (grid2) vom darunterliegenden grid3 abheben */
.sec-objekt .grid2 {
  margin-bottom: 10px;
}
/* Beim MFH kommen die Wohneinheiten dazu: Kaufpreis 40 · Wohnfläche 30 · Einheiten 30 - der
   Kaufpreis ist die längste Zahl. Schmal einspaltig wie jedes .grid2; ohne die Regel unten
   überstimmte die höhere Spezifität dieser hier die allgemeine. */
body[data-objektart="mfh"] .sec-objekt .grid2 {
  grid-template-columns: minmax(0, 40fr) minmax(0, 30fr) minmax(0, 30fr);
}
@media (max-width: 480px) {
  body[data-objektart="mfh"] .sec-objekt .grid2 {
    grid-template-columns: 1fr;
  }
}
/* Steuer: 3 schmale %-Felder in einer Zeile, Renovierung über volle Breite darunter */
.grid3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.grid3 .span3 {
  grid-column: 1 / -1;
  margin-top: 4px;
}
/* Objekt: Baujahr 30 · Energieklasse 40 · Renovierung 30. Die mittlere Spalte ist breiter, weil
   dort neben dem Auswahlfeld der Hinweis zum Energiebedarf steht ("160–200 kWh/m²·a"). */
.sec-objekt .grid3 {
  grid-template-columns: minmax(0, 30fr) minmax(0, 40fr) minmax(0, 30fr);
}
@media (max-width: 480px) {
  .grid3,
  .sec-objekt .grid3 {
    grid-template-columns: 1fr;
  }
}
/* Adresszeile: Straße breit, PLZ schmal, Ort mittel */
.grid-adr {
  display: grid;
  grid-template-columns: minmax(0, 1.7fr) 84px minmax(0, 1.3fr);
  gap: 10px;
  margin-bottom: 10px;
}
.span2 {
  grid-column: 1 / -1;
}
@media (max-width: 480px) {
  /* Dreispaltig bleiben hier rund 50 px für den Ort übrig: Straße über die volle
     Breite, PLZ und Ort darunter nebeneinander */
  .grid-adr {
    grid-template-columns: 84px minmax(0, 1fr);
  }
  .grid-adr > :first-child {
    grid-column: 1 / -1;
  }
  .grid2 {
    grid-template-columns: 1fr;
  }
  .span2 {
    grid-column: auto;
  }
}

/* Felder, die nur zu einer Objektart gehören. recalc() setzt data-objektart am <body>; solange
   das Attribut fehlt (vor dem ersten Rechnen), gilt die Eigentumswohnung. */
body:not([data-objektart="mfh"]) .nur-mfh,
body[data-objektart="mfh"] .nur-etw {
  display: none;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.field > span {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
/* Eingabefelder einer Rasterzeile stehen auf einer Höhe, auch wenn eine Beschriftung umbricht
   (schmale Spalten, etwa auf dem Handy): Das Raster streckt die Felder gleich hoch, der Kasten
   rückt an deren Unterkante. */
.field > .inp {
  margin-top: auto;
}

/* Schalter über einer Kartengruppe (z. B. "keine Finanzierung") */
.schalter {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.schalter input {
  accent-color: var(--accent);
  width: 16px;
  height: 16px;
  cursor: pointer;
}
.schalter small {
  font-weight: 400;
  color: var(--ink-soft);
}

/* ausgegrautes Feld (z. B. Renovierungs-Steuerwahl ohne Renovierung) */
.field.is-disabled {
  opacity: 0.45;
}
.field.is-disabled .inp {
  pointer-events: none;
}

.lblrow {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 8px;
}
.hint {
  font-style: normal;
  font-weight: 600;
  font-size: 11.5px;
  color: var(--ink-soft);
  /* bewusst kein nowrap: ein langer Hinweis schob das Feld sonst eine Zeile tiefer
     als seine Nachbarn in derselben Rasterzeile */
}

.inp {
  display: flex;
  align-items: center;
  border: 1px solid var(--line-control);
  background: var(--panel-2);
  border-radius: 10px;
  padding: 0 12px;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}
.inp:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.inp input,
.inp select {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
  border: 0;
  outline: 0;
  padding: 7px 0;
}
.inp em {
  font-style: normal;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  padding-left: 8px;
  white-space: nowrap;
}
.inp select {
  cursor: pointer;
}
/* gesperrte Option (z. B. "sofort" über der 15-%-Grenze) ausgrauen – erbt sonst --ink vom Select */
#renomodus option:disabled {
  color: var(--ink-soft);
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
input[type="number"] {
  -moz-appearance: textfield;
}

/* Eigener Baustein: kein bedienbares Feld, sondern eine Ergebniszeile.
   Die Beschriftung braucht dieselbe Auszeichnung wie in .field – sie kam früher von dort. */
.readout > span {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.readout {
  display: flex;
  flex-direction: row;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  border-top: 1px solid var(--line);
  padding-top: 8px;
  margin-top: 2px;
}
.readout output {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}

/* Marktmiete-Zeile (Homeday-Abruf) */
.marktmiete {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-top: 12px;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}
.marktmiete #out-marktmiete {
  font-size: 12px;
  color: var(--ink-soft);
  margin-left: auto;
  text-align: right;
}
/* Solange der Spinner läuft, steht er direkt am Knopf: Am rechten Rand sah er aus wie ein
   eigenes Bedienelement statt wie der Zustand des Knopfs, den man gerade gedrückt hat.
   Das Ergebnis rückt danach wieder nach rechts, weil der Spinner dann weg ist. */
.marktmiete #out-marktmiete:has(.spinner) {
  margin-left: 0;
}
/* Der freie Platz muss dann aber woandershin: Ohne diese Zeile wandert der Link zum
   Preisatlas mit dem Spinner nach links und springt beim Ergebnis wieder zurück. */
.marktmiete:has(.spinner) .mm-link {
  margin-left: auto;
}
.marktmiete .hint {
  color: var(--ink);
} /* Wert im Hint-Stil, aber nicht gedämpft */
.mm-link {
  display: inline-flex;
  align-self: center;
  align-items: center;
  color: var(--ink-soft);
  flex: none;
}
.mm-link:hover {
  color: var(--accent);
}
/* Knopf, der aussieht wie der Link daneben: gleiche Grösse, gleicher Ton. Als beschrifteter
   Knopf brauchte die Zeile 10 px mehr Höhe, weil der Statustext daneben umbrach. */
.mm-icon {
  display: inline-flex;
  align-self: center;
  align-items: center;
  flex: none;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
}
.mm-icon:hover {
  color: var(--accent);
}
/* Der Betrag steht schon im Feld: sichtbar, aber ohne Angebot */
.mm-icon:disabled {
  opacity: 0.35;
  cursor: default;
}
.mm-icon:disabled:hover {
  color: var(--ink-soft);
}
.mm-icon[hidden] {
  display: none;
}
.mm-link[hidden] {
  display: none;
}
.inp .mm-link {
  padding-left: 8px;
}
/* Variante neben dem Ort-Feld: unsichtbar, behält aber ihren Platz, damit das Eingabefeld
   nicht springt. Gesteuert wird beides über dasselbe hidden-Attribut. */
.mm-link--reserve[hidden] {
  display: inline-flex;
  visibility: hidden;
}
.spinner {
  display: inline-block;
  width: 12px;
  height: 12px;
  vertical-align: middle;
  border: 2px solid color-mix(in srgb, var(--ink-soft) 30%, transparent);
  border-top-color: var(--ink-soft);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}
/* Solange ein Abruf läuft, trägt die Statuszeile Spinner und Laufzeit nebeneinander. Als
   Flex-Zeile stehen beide exakt auf einer Mittelachse; über die Grundlinie ausgerichtet säße
   die Zahl sichtbar höher als der Kreisel. Der Abstand kommt aus "gap", nicht aus Leerzeichen. */
[data-belegt] {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.laufzeit {
  font-variant-numeric: tabular-nums; /* feste Ziffernbreite, damit die Zeile nicht zappelt */
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
.marktmiete .up {
  color: var(--pos);
  font-weight: 600;
} /* Markt über Ist = Potenzial (grün) */
.marktmiete .neg {
  color: var(--neg);
  font-weight: 600;
}

/* ---------- Hero ---------- */
.hero {
  display: flex;
  flex-wrap: wrap; /* damit der Hinweis eine eigene Zeile über den Zahlen bekommt */
  gap: 18px;
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 12%, var(--panel)), var(--panel));
  border-color: color-mix(in srgb, var(--accent) 30%, var(--line));
}
.hero-main {
  flex: 1;
}
.hero-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
}
.hero-value {
  font-size: clamp(30px, 5.5vw, 44px);
  font-weight: 800;
  letter-spacing: -1px;
  line-height: 1.1;
  margin: 2px 0 8px;
}
.hero-value.pos {
  color: var(--pos);
}
.hero-value.neg {
  color: var(--neg);
}
.hero-sub {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.hero-aftertax {
  font-size: 13px;
  color: var(--ink-soft);
}
.hero-aftertax strong.pos {
  color: var(--pos);
}
.hero-aftertax strong.neg {
  color: var(--neg);
}
.badge {
  font-size: 12px;
  font-weight: 700;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
}
.badge.pos {
  background: var(--pos-soft);
  color: var(--pos);
}
.badge.neg {
  background: var(--neg-soft);
  color: var(--neg);
}
/* Noch kein Urteil: grau statt farbig, sonst sähe der Platzhalter aus wie eine Aussage */
.badge.leer {
  background: color-mix(in srgb, var(--ink-soft) 12%, transparent);
  color: var(--ink-soft);
}

.hero-side {
  display: flex;
  flex-direction: column;
  gap: 10px;
  justify-content: center;
  padding-left: 20px;
  border-left: 1px solid var(--line);
}
.mini {
  text-align: right;
}
.mini > span {
  display: block;
  font-size: 11.5px;
  color: var(--ink-soft);
}
.mini strong {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.5px;
}
@media (max-width: 520px) {
  .hero {
    flex-direction: column;
  }
  .hero-side {
    flex-direction: row;
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--line);
    padding-top: 14px;
  }
  .mini {
    flex: 1;
    text-align: left;
  }
}

/* ---------- KPI grid ---------- */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}
@media (max-width: 620px) {
  .kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  /* D5: Seitenverhältnis der viewBox übernehmen. Bei fester Höhe staucht
     preserveAspectRatio="none" auf schmalen Geräten alle Beschriftungen waagerecht. */
  #chart,
  #chart-prog {
    height: auto;
    aspect-ratio: 640 / 220;
  }
}
.kpi {
  background: var(--panel);
  border: 1px solid var(--line-control);
  border-radius: 12px;
  padding: 10px 11px;
  box-shadow: var(--shadow);
}
.kpi > span {
  display: block;
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-bottom: 3px;
}
.kpi strong {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -0.4px;
}
.kpi strong.pos {
  color: var(--pos);
}
.kpi strong.neg {
  color: var(--neg);
}

/* ---------- Waterfall ---------- */
.waterfall {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Drei Stufen, in denen Bezeichnung und Wert jeweils dieselbe Größe tragen:
   Unterzeile 12,5 · normale Zeile 13,5 · (Zwischen-)Summe 14,5 und fett. */
.waterfall li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 4px 0;
  font-size: 13.5px;
}
.waterfall .lbl {
  color: var(--ink-soft);
}
.waterfall .val {
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.waterfall .val.neg {
  color: var(--neg);
}
.waterfall .val.pos {
  color: var(--pos);
}
.waterfall li.sub {
  font-size: 12.5px;
}
.waterfall li.sub .lbl {
  padding-left: 14px;
}
/* nur die (Zwischen-)Summen fett; darunter etwas mehr Abstand als darüber */
.waterfall li.total {
  margin-bottom: 9px;
  font-size: 14.5px;
}
.waterfall li.total .lbl {
  color: var(--ink);
  font-weight: 700;
}
.waterfall li.total .val {
  font-weight: 700;
}

/* ---------- Chart ---------- */
.chart-wrap {
  width: 100%;
  position: relative;
}
#chart,
#chart-prog {
  width: 100%;
  height: 200px;
  display: block;
  overflow: visible;
}
.chart-legend {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-size: 12px;
  color: var(--ink-soft);
}
.chart-legend span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.dot {
  width: 10px;
  height: 10px;
  border-radius: 3px;
  display: inline-block;
}
.dot-line,
.dot-wert {
  background: var(--accent);
}
.dot-mark {
  background: var(--neg);
  border-radius: 50%;
}
.dot-rest {
  background: var(--neg);
}
.dot-ek {
  background: var(--pos);
}
.push-right {
  margin-left: auto;
}

/* Hover-Tooltip über der Prognose-Grafik */
/* wie die data-tip-Tooltips zum Seitenhintergrund invertiert */
.chart-tip {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  display: none;
  background: var(--ink);
  color: var(--panel);
  border-radius: 8px;
  box-shadow: var(--shadow);
  padding: 6px 10px;
  font-size: 12px;
  line-height: 1.35;
  white-space: nowrap;
}
.chart-tip .tt-name {
  display: block;
  font-weight: 700;
}
.chart-tip .tt-sub {
  display: block;
  color: color-mix(in srgb, currentColor 70%, transparent);
  font-variant-numeric: tabular-nums;
}

/* ---------- Verhandlungs-Tabelle ---------- */
/* Maße wie .year-table: Verhandlung, Sensitivität, Stresstest und Jahrestabelle stehen als
   Karten untereinander – eine Tabelle mit eigener Schriftgröße fällt dort auf. */
.nego-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.nego-table th {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.3px;
  text-align: right;
  white-space: nowrap;
  padding: 0 0 6px 10px;
  border-bottom: 1px solid var(--line);
}
.nego-table th:first-child {
  text-align: left;
  padding-left: 0;
}
.nego-table td {
  padding: 4px 0;
  border-bottom: 1px dashed var(--line);
}
.nego-table tr:last-child td {
  border-bottom: 0;
}
.nego-table td.lbl {
  color: var(--ink-soft);
  width: 100%;
}
.nego-table td.val {
  text-align: right;
  white-space: nowrap;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding-left: 10px;
}
.nego-table td.val.pos {
  color: var(--pos);
}
.nego-table td.val.neg {
  color: var(--neg);
}
.nego-table td.val:last-child {
  font-weight: 500;
} /* Differenz nicht fett */

/* ---------- Bauzinsen-Panel ---------- */
.rates {
  margin-top: 12px;
  border-top: 1px solid var(--line);
  padding-top: 10px;
}
.rates-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
/* Stand und Link wie bei der Marktmiete: Der freie Platz sammelt sich vor dem Stand, Link und
   Stand stehen danach dicht beieinander – nicht auseinandergezogen wie bei space-between. */
.rates-head .hint {
  font-weight: 400;
  font-size: 12px;
  margin-left: auto;
}
.rates-chips {
  display: flex;
  gap: 8px;
}
.rate-chip {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 7px 4px;
  border: 1px solid var(--line-control);
  border-radius: 10px;
  background: var(--panel-2);
  cursor: pointer;
  font: inherit;
  transition:
    border-color 0.15s,
    background 0.15s;
}
.rate-chip:hover {
  border-color: var(--accent);
}
.rate-chip .ry {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--ink-soft);
  white-space: nowrap;
}
.rate-chip .rv {
  font-size: 14px;
  font-weight: 800;
  letter-spacing: -0.3px;
  color: var(--ink);
}
.rate-chip.active {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.rate-chip.active .rv {
  color: var(--accent);
}

/* ---------- Ansicht-Umschalter Jahr 1 / Prognose ---------- */
.mode-toggle {
  display: inline-flex;
  gap: 4px;
  background: var(--panel-2);
  border: 1px solid var(--line-control);
  border-radius: 12px;
  padding: 4px;
  margin-bottom: 16px;
}
.mode-toggle button {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-soft);
  background: transparent;
  border: 0;
  border-radius: 9px;
  padding: 7px 18px;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}
.mode-toggle button.active {
  background: var(--accent);
  color: #fff;
}

/* ---------- Einklappbare Karten (summary statt h2) ---------- */
.card > summary {
  cursor: pointer;
  list-style: none;
  margin: 0;
  font-size: 12.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--accent);
}
.card > summary::-webkit-details-marker {
  display: none;
}
/* Abstand über margin: Leerzeichen im content verwirft ein Flex-Container (Risiken-Karte) */
.card > summary::before {
  content: "▸";
  margin-right: 8px;
}
.card[open] > summary::before {
  content: "▾";
}
.card[open] > summary {
  margin-bottom: 10px;
}

/* ---------- Risiken & Signale (Ampel-Panel) ---------- */
.card.risiken > summary {
  display: flex;
  align-items: baseline;
}
.risiken-badges {
  margin-left: auto;
  text-transform: none;
  letter-spacing: 0;
}
.risiken-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  margin-left: 5px;
  white-space: nowrap;
}
.risiken-badge.bad {
  background: var(--neg-soft);
  color: var(--neg);
}
.risiken-badge.warn {
  background: var(--warn-soft);
  color: var(--warn);
}
.risiken-badge.ok {
  background: var(--pos-soft);
  color: var(--pos);
}
.risiken-row {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 9px 0;
  font-size: 13.5px;
  line-height: 1.45;
  border-top: 1px solid var(--line);
}
.risiken-row:first-child {
  border-top: 0;
  padding-top: 5px; /* Textabstand zur Titelzeile wie in den Nachbarkarten */
}
.risiken-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  align-self: center;
  cursor: help;
}
.risiken-dot.bad {
  background: var(--neg);
}
.risiken-dot.warn {
  background: var(--warn);
}
.risiken-dot.ok {
  background: var(--pos);
}
.risiken-lbl {
  font-weight: 600;
}
.risiken-rsn {
  margin-left: auto;
  text-align: right;
  color: var(--ink-soft);
}
/* Solange ein Pflichtfeld fehlt, steht hier statt der Bewertung, woran es liegt – leise und
   mittig, denn es ist kein Befund in einer Liste, sondern eine Ansage, was noch zu tun ist.
   Bewusst kein Flex wie bei den Bewertungszeilen: Dort trennt gap die drei Spalten, hier
   würde er jedes hervorgehobene Wort zum eigenen Element machen und Lücken in den Satz reißen. */
.risiken-row.leer {
  display: block;
  text-align: center;
  font-size: 12.5px; /* wie der gleichlautende Hinweis über dem Ergebnis, nicht wie eine Bewertungszeile */
  color: var(--ink-soft);
}
/* Die Feldnamen in normaler Schriftfarbe, wie im Hinweis über dem Ergebnis */
.risiken-row.leer strong {
  color: var(--ink);
}
#p-vermoegen.pos {
  color: var(--pos);
}
#p-vermoegen.neg {
  color: var(--neg);
}

/* ---------- Exposé-Import ---------- */
/* Linkfeld über die Breite, Knopf daneben, Meldung rechts */
.expose-zeile {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.expose-zeile #expose-url {
  flex: 1;
  min-width: 0;
  padding: 7px 10px;
  font-size: 13px;
  color: var(--ink);
  background: var(--panel-2);
  border: 1px solid var(--line-control);
  border-radius: 8px;
}
.expose-zeile #out-expose {
  font-size: 12px;
  color: var(--ink-soft);
  white-space: nowrap;
}
#expose-vorschau {
  margin-bottom: 12px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
}
#expose-vorschau[hidden] {
  display: none;
}
/* Trennt die Objektverwaltung samt Import von den Daten des Objekts - dieselbe Linie wie
   zwischen den Abschnitten der übrigen Karten. */
.sec-objekt .grid-adr {
  border-top: 1px solid var(--line);
  padding-top: 12px;
}
/* Die dritte Spalte ist der bisherige Stand - leiser als der neue Wert daneben */
#expose-table td:last-child {
  color: var(--ink-soft);
}
.expose-wahl {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
}
.expose-aktion {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.expose-aktion .hint {
  margin-right: auto;
}

/* ---------- Lage (Klappbereich in der Objekt-Kachel) ---------- */
/* Untergeordneter Klappbereich in einer Karte (Lage im Objekt). Bewusst nicht als .card
   gestaltet: dezenter, mit Trennlinie statt Rahmen, damit die Kachel eine Kachel bleibt.
   Hiess früher "sub" - wie die Unterzeilen des Wasserfalls. Die Trennlinie hier oben traf
   dadurch auch jede Zeile der Cashflow-Rechnung und zerlegte sie in Streifen. */
.subcard {
  border-top: 1px solid var(--line);
  margin-top: 13px;
  padding-top: 11px;
}
.subcard > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  list-style: none;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--ink-soft);
}
.subcard > summary::-webkit-details-marker {
  display: none;
}
.subcard > summary::before {
  content: "▸";
}
.subcard[open] > summary::before {
  content: "▾";
}
.subcard[open] > summary {
  margin-bottom: 10px;
}
/* Knopf und Meldung im Titel: Der Knopf steht rechts und klappt nichts auf oder zu –
   das unterbindet der Klick-Handler in app.js. */
.subcard > summary .btn {
  text-transform: none;
  letter-spacing: 0;
}
.subcard > summary #out-lage {
  margin-left: auto;
  font-size: 12px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-soft);
  text-align: right;
}
/* Bewusst ohne .table-scroll: Drei schmale Spalten brauchen keinen Bildlauf, und "overflow-x"
   zwingt die Y-Achse mit auf "auto" - die Tooltips der unteren Zeilen wären dann beschnitten
   und die Tabelle bekäme eine senkrechte Bildlaufleiste. */
#lage-table {
  margin-bottom: 12px;
}
/* Deutlicher als der übliche Tooltip-Hinweis: In einer Zahlenspalte rechnet niemand damit,
   dass sich hinter dem Wert noch etwas verbirgt. */
#lage-table td [data-tip] {
  text-decoration-color: var(--ink-soft);
}
/* Einschränkung zur Genauigkeit: sichtbar, aber nicht alarmierend - es ist kein Fehler,
   sondern eine Lücke in den Daten. Erscheint nur, wenn sie zutrifft. */
.lage-warnung {
  margin: -4px 0 12px;
  font-size: 12px;
  color: var(--ink-soft);
  text-align: center;
}
.lage-warnung[hidden] {
  display: none;
}
/* Die Kategorie ist hier keine Achsenbeschriftung wie in den Jahrestabellen, sondern
   gleichrangig mit der Zahl daneben - also dieselbe Schriftfarbe. */
#lage-table td:first-child {
  color: var(--ink);
}
#lage-table[hidden] {
  display: none;
}

/* Verweise auf amtliche Portale: mittig, in Zeilen umbrechend, durch eine Linie vom
   abgerufenen Teil darüber getrennt - hier endet das Gerechnete und beginnt das Nachschlagen. */
.lage-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 16px;
  border-top: 1px solid var(--line);
  padding-top: 11px;
}
.lage-links a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
}
.lage-links a:hover {
  color: var(--accent);
}

/* ---------- Tabellen mit Bildlauf (Jahrestabelle, Sensitivität, Stresstest) ---------- */
.table-scroll {
  overflow-x: auto;
}
.year-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.year-table th {
  text-align: right;
  white-space: nowrap;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--ink-soft);
  padding: 0 0 6px 10px;
  border-bottom: 1px solid var(--line);
}
.year-table th:first-child {
  text-align: left;
  padding-left: 0;
}
.year-table td {
  text-align: right;
  white-space: nowrap;
  padding: 4px 0 4px 10px;
  font-variant-numeric: tabular-nums;
  border-bottom: 1px dashed var(--line);
}
.year-table td:first-child {
  text-align: left;
  padding-left: 0;
  color: var(--ink-soft);
}
.year-table tbody tr:last-child td {
  border-bottom: 0;
}
.year-table td.pos {
  color: var(--pos);
}
.year-table td.neg {
  color: var(--neg);
}
/* Stresstest: Basis- und Worst-Case-Zeile hervorheben */
.hl-table .hl td:first-child {
  font-weight: 700;
  color: var(--ink);
}

/* nur im Druck sichtbar (Objektkopf) */
.print-only {
  display: none;
}

/* ---------- Druckansicht ---------- */
@media print {
  /* helles Layout erzwingen, unabhängig vom Theme */
  :root,
  :root[data-theme="dark"] {
    --bg: #fff;
    --panel: #fff;
    --panel-2: #fff;
    --ink: #000;
    --ink-soft: #444;
    --line: #bbb;
    --line-control: #777;
    --accent: #3730a3;
    --accent-soft: #eee;
    --pos: #0a7a4f;
    --pos-soft: #eef7f1;
    --neg: #b3283c;
    --neg-soft: #fbeef0;
    --warn: #8a5a12;
    --warn-soft: #fdf3e2;
    --accent-inv: #3730a3;
    --pos-inv: #0a7a4f;
    --neg-inv: #b3283c;
    --logo-2: #6d28d9;
    --shadow: none;
  }
  @page {
    margin: 14mm;
  }
  body {
    background: #fff;
  }

  /* Bedienelemente ausblenden – das Ergebnis der Marktmiete bleibt stehen, sonst fehlt
     dem Hinweis "Miete über Vergleichsmiete" im Bericht die Bezugsgröße */
  .topbar,
  .mode-toggle,
  .obj-bar,
  .expose-zeile,
  #expose-vorschau,
  #btn-marktmiete,
  #btn-lage,
  .lage-links,
  .rates,
  .mm-link,
  .mm-icon,
  .chart-tip,
  .spinner {
    display: none !important;
  }
  /* Die Zinskacheln (.rates) sind ein Auswahlwerkzeug: In die Rechnung geht nur der Satz im Feld
     "Sollzins" darüber. Das Häkchen "keine Finanzierung" bleibt dagegen stehen - es sagt, wie
     gerechnet wurde.
     Ohne abgerufene Marktmiete ist nach dem Ausblenden des Knopfes nichts mehr in der Zeile; ihre
     Trennlinie stünde dann allein unter den Mieteinnahmen. */
  .marktmiete:has(#out-marktmiete:empty) {
    display: none;
  }
  /* Vom Lage-Bereich bleibt im Druck nur die Tabelle der abgerufenen Umgebung. Ohne Abruf stünde
     dort die Überschrift allein - dann entfällt der Bereich ganz. */
  .subcard:has(#lage-table[hidden]) {
    display: none;
  }
  /* Tabelle und Hinweis halten am Bildschirm Abstand zu den Verweisen darunter. Die fehlen hier,
     der Abstand stünde also als Leerraum am Fuß der Karte. Der Hinweis behält seinen Abstand zur
     Tabelle (oben 12 px minus 4 px). */
  #lage-table {
    margin-bottom: 0;
  }
  .lage-warnung {
    margin: 8px 0 0;
  }

  /* Objektkopf zeigen */
  .print-only {
    display: block;
  }
  #print-head {
    margin-bottom: 14px;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--ink);
  }
  #print-head .ph-typ {
    font-size: 12px;
    font-weight: 600;
    color: var(--accent);
  }
  #print-head h1 {
    margin: 1px 0 3px;
    font-size: 20px;
  }
  #print-head .ph-meta {
    font-size: 12px;
    color: var(--ink-soft);
  }

  /* eine Spalte, beide Ansichten untereinander */
  .layout {
    display: block;
    max-width: none;
    padding: 0;
    gap: 0;
  }
  .results {
    position: static;
  }
  #view-jahr1,
  #view-prognose {
    display: block !important;
  }
  #view-prognose {
    break-before: page;
  }

  /* Karten drucktauglich, nicht über Seitenumbrüche zerreißen */
  .card,
  .inputs .card[class*="sec-"] {
    background: #fff !important;
    box-shadow: none !important;
    break-inside: avoid;
  }
  .chart-wrap,
  .year-table,
  .waterfall,
  .hl-table {
    break-inside: avoid;
  }

  /* Ampelpunkte und Badges tragen ihre Aussage in der Hintergrundfarbe. Browser drucken
     Hintergründe standardmäßig nicht – ohne diese Anweisung bliebe das Risiken-Panel farblos. */
  .risiken-dot,
  .risiken-badge,
  .badge {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* D19/D20: Papier kann nicht scrollen, und eine 40-zeilige Tabelle passt auf keine Seite */
  .table-scroll {
    overflow: visible;
  }
  .card:has(#year-table),
  #year-table {
    break-inside: auto;
  }
  #year-table thead {
    display: table-header-group; /* Spaltenköpfe auf Folgeseiten wiederholen */
  }

  /* Tooltip-Unterstreichungen und Cursor sind im Druck sinnlos. Dieselbe Liste wie oben bei der
     Unterstreichung: Fehlt ein Eintrag oder ist er schwächer geschrieben, bleibt die Linie stehen. */
  abbr[data-tip],
  .help,
  .risiken-lbl[data-tip],
  .hint[data-tip]:not(:empty) {
    text-decoration: none;
    cursor: auto;
  }
  /* Ein fixiertes Element erschiene sonst auf jeder Seite */
  #tip {
    display: none;
  }

  /* Aufklapp-Dreieck der Sektionen ist im statischen Druck sinnlos
     (die [open]-Variante muss mitgetroffen werden – höhere Spezifität) */
  .card > summary::before,
  .card[open] > summary::before {
    content: "";
  }
}
