/* Gemeinsames Material-Design-Formular-System fuer alle Rechner-Seiten (Cashflow-Rechner,
   Kreditrechner, ...). Urspruenglich als scoped Cashflow.razor.css entstanden, jetzt global,
   damit mehrere Feature-Seiten dasselbe Design nutzen koennen, ohne die Regeln zu duplizieren
   (siehe CLAUDE.md KI-Regel 6). Alle Regeln sind bewusst auf ".material-calculator" als
   Nachfahren-Selektor beschraenkt (nicht wirklich global) - Properties.razor nutzt z.B. auch
   .card-body/.mb-3 als normales, unveraendertes Bootstrap-Formular; ohne diese Klammer wuerden
   diese seitenuebergreifenden Regeln dort das Layout kaputt machen. Jede Rechner-Seite muss ihr
   Markup daher in einen <div class="material-calculator"> wrappen. Klassennamen bleiben
   "cashflow-*" aus Kompatibilitaetsgruenden, sind aber inzwischen seitenuebergreifend gemeint. */

/* Layout-Grundprinzip (Neuaufbau nach mehreren gescheiterten Flexbox-Anläufen):
   - Jede Karte (.card-body) ist eine eigene CSS-Grid mit 3 Spalten
     (Label | Wert | optionale Checkbox), jede Spalte "max-content" - die Karte wird
     also exakt so breit UND so hoch wie ihr eigener Inhalt es braucht.
   - Die Zeilen-Wrapper (.cashflow-field-row/.cashflow-result-row) sind "display:
     contents": sie selbst erzeugen keine eigene Box, ihre Kinder (Label, Wert,
     Checkbox) werden direkte Grid-Items der Karte.
   - Weil "display: contents" die urspruengliche Zeilengrenze fuer das Grid unsichtbar
     macht, bekommt jeder Item-Typ eine FESTE Spalte (Label=1, Wert=2, Checkbox=3) statt
     sich auf die Auto-Platzierung zu verlassen - sonst packt das Grid Items einfach
     fortlaufend in die 3 Spalten und Label/Wert aus verschiedenen urspruenglichen Zeilen
     landen im selben Grid-Row (beobachtet: Werte und Labels durcheinander). Mit fester
     Spalte pro Item-Typ sucht sich jedes Item automatisch die naechste freie Zeile in
     genau dieser Spalte, wodurch die urspruengliche Zeilenzuordnung korrekt
     rekonstruiert wird.
   - Der Spalten-Stack (.cashflow-column-stack) ist ebenfalls eine Grid mit einer
     "max-content"-Spur: die breiteste Karte in dieser Spalte bestimmt die Spaltenbreite,
     alle anderen Karten strecken sich per Grid-Default (justify-items: stretch) exakt
     auf diese Breite. align-content:start verhindert, dass Karten in die Hoehe gezogen
     werden, nur weil eine andere Spalte hoeher ist.
   - Flexbox konnte "Spalte so breit wie Inhalt, alle Karten gleich breit" nicht
     zuverlaessig, weil Bootstraps .card width:100% setzt - das erzeugt in einem
     inhaltsbasierten Flexbox-Kontext einen Zirkelbezug (Spalte will sich am Inhalt
     orientieren, Karte behauptet "ich bin 100% davon"), der je nach Browser/Inhalt zu
     falsch (zu schmal) berechneten Breiten fuehrte - Werte liefen ueber den Kartenrand
     hinaus. CSS Grid berechnet die Breite eines Grid-Items fuer die Spurgroessen-
     Ermittlung anhand seines Inhalts (unabhaengig von einer width:100%-Angabe), daher
     KEIN width:max-content auf .card-body setzen - das wuerde Grids Default
     justify-items:stretch verhindern, wodurch schmalere Karten nicht mehr auf die
     Breite der breitesten Karte gezogen werden (genau das war der naechste Bug). */
/* max-width statt fixer Breite: auf einem echten Handy-Viewport (schmaler als dieser Wert)
   greift ohnehin ganz normal "width:auto" (= volle verfuegbare Breite), auf einem breiteren
   Browserfenster unterhalb des lg-Breakpoints (col-12 macht die Spalte sonst bildschirmbreit,
   siehe Bootstraps .card{width:100%}) begrenzt max-width die Karten auf eine sinnvolle,
   handy-aehnliche Breite statt sie ueber die gesamte Fensterbreite zu ziehen
   (Nutzer-Feedback: "am Handy passt es perfekt, nur im Browser ist es zu gross"). */
.material-calculator .cashflow-column-stack {
    display: grid;
    grid-template-columns: max-content;
    align-content: start;
    max-width: 420px;
}

/* Karten nebeneinander, bevor sie umbrechen (docs/026, Nachtrag): das bisherige Muster
   (.row > mehrere .col-12 col-lg-auto > .cashflow-column-stack) gruppierte Karten in eine FESTE,
   von Hand im Markup entschiedene Anzahl Spalten (z. B. zwei: eine mit allen Eingabekarten
   gestapelt, eine mit der Ergebniskarte) - bei nur zwei bis drei Karten blieb dadurch auf breiten
   Bildschirmen sichtbar Platz rechts frei, obwohl eine dritte Karte daneben gepasst haette
   (Nutzer-Feedback zu Sparplanrechner/Mietrendite-Rechner: "Kapital & Rendite" und "Sparplan"
   standen untereinander trotz freier Breite rechts). Das lag NICHT an Bootstraps
   .row-Flex-Wrap-Mechanismus selbst (der funktioniert, siehe Cashflow-Oesterreich mit vier
   Spalten) - das Problem war, dass zusammengehoerige UND unabhaengige Karten in denselben
   Stack gezwungen wurden, statt jede Karte einzeln flowen zu lassen.

   .cashflow-card-flow macht jede einzelne Karte zum Flow-Element, kein manuelles Vorab-Gruppieren
   in Spalten mehr noetig. Bewusst CSS Grid mit auto-fill/minmax statt Flexbox: siehe Kommentar
   ganz oben in dieser Datei ("Neuaufbau nach mehreren gescheiterten Flexbox-Anlaeufen") - Bootstraps
   .card{width:100%} erzeugte in einem inhaltsbasierten Flexbox-Kontext denselben Zirkelbezug wie
   damals bei .cashflow-column-stack. minmax(min(300px, 100%), 420px) ist dagegen eine EXPLIZITE,
   nicht inhaltsbasierte Spurgroesse - .card{width:100%} bezieht sich dann auf die bereits fest
   bemessene Grid-Spur, kein Zirkelbezug moeglich. auto-fill erzeugt automatisch so viele Spalten,
   wie bei der aktuellen Breite Platz haben, und bricht erst um, wenn keine weitere Spalte mehr
   passt - genau die gewuenschte "Breite zuerst nutzen"-Reihenfolge. min(300px, 100%) als
   Untergrenze verhindert horizontales Ueberlaufen auf Schmal-Viewports unter 300px verfuegbarer
   Breite (z. B. durch Sidebar-Rand). Auf 375px passt ohnehin nur eine Spalte - automatisch
   einspaltig, exakt wie zuvor, ohne eigene Media Query. Tabellen-Karten (Tilgungsplan,
   Kapitalentwicklung) bleiben bewusst AUSSERHALB dieses Grids in einer eigenen volle-Breite-Zeile -
   sie sollen nicht auf 420px begrenzt werden. */
/* align-items: stretch (docs/027, Etappe 3) statt "start": Karten mit wenigen Feldern in
   derselben Rasterzeile wie eine hohe Karte hatten dadurch ausgefranste Unterkanten (Cashflow
   AT/DE/CH, Nutzer-Feedback). "stretch" ist hier bewusst gefahrlos, obwohl dieselbe Datei oben
   explizit vor Flexbox als Loesung fuer dieses Grid warnt: der frueher gescheiterte
   Flexbox-Ansatz betraf die BREITEN-Berechnung (Zirkelbezug zwischen Bootstraps .card{width:100%}
   und einem inhaltsbasierten Flex-Kontext) - align-items:stretch betrifft nur die HOEHE einer
   bereits fest bemessenen Spur und hat dieses Zirkelbezug-Problem nicht. CardGrid.razor
   (.landing-cards) waere die naheliegende gemeinsame Komponente gewesen, ist hier aber bewusst
   NICHT verwendet: sie ist Flexbox-basiert (display:flex statt Grid) - ihr Uebertragen auf
   .cashflow-card-flow haette exakt den oben dokumentierten, bereits einmal gescheiterten
   Flexbox-Zirkelbezug reproduziert. Gleiches Ergebnis (gleiche Kartenhoehe je Zeile), ohne das
   historisch belegte Risiko. */
.material-calculator .cashflow-card-flow {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 420px));
    align-items: stretch;
    gap: 0.75rem;
}

/* Spalte 3 ist "1fr" statt "max-content": andernfalls ist die Wert-Spalte nur so breit
   wie die laengste Zahl DIESER Karte, und der Rest der (auf die breiteste Karte der
   Spalte gestreckten) Kartenbreite bleibt als Leerraum rechts vom Grid ungenutzt - die
   Zahlen enden dann je nach Karte unterschiedlich weit vor dem echten Kartenrand
   (Nutzer-Feedback per Screenshot). Mit 1fr fuellt die Wert-Spalte immer den
   verbleibenden Platz bis zum Kartenrand, "justify-self:stretch" + "text-align:right"
   auf den Werten sorgt fuer die Rechtsbuendigkeit darin. */
/* Kopfstreifen als einheitlicher oberer Abschluss aller Karten (docs/024, Nachtrag): Ergebnis-
   Karten hatten durch ihren goldenen Streifen (siehe :has(.cashflow-result-row)/:has(table) weiter
   unten) einen klaren oberen Abschluss, Eingabekarten nur Flaeche + Rahmen und wirkten dadurch
   weniger definiert (Nutzer-Feedback nach Browser-Check). Navy statt Gold als Grundfarbe -
   Farbcode bleibt erhalten (Gold = Ergebnis, Navy = Eingabe). Volles --rec-navy (Kontrast 14,1:1
   gegen --rec-card-bg) wirkte deutlich schwerer als der goldene Streifen der Ergebnis-Karten
   (Kontrast dort nur 2,42:1 gegen Weiss, gemessen) - gleiche 2px-Breite, aber ein derart harter
   Farbwert haette die beiden Kartentypen optisch aus der Balance gebracht statt sie
   anzugleichen. Auf 45% Deckkraft abgeblendet (rgba, kein neuer Hex-Ton) landet der Kontrast bei
   2,72:1 - nah am goldenen Vorbild, gleiches visuelles Gewicht statt nur gleicher Farbidee. */
.material-calculator .card-body {
    display: grid;
    grid-template-columns: max-content max-content 1fr;
    align-items: center;
    align-content: start;
    column-gap: 0.5rem;
    row-gap: 0.35rem;
    padding: 0.65rem 0.85rem;
    border-top: 2px solid rgba(11, 37, 69, 0.45);
}

.material-calculator .card-body h5 {
    font-size: 0.95rem;
    margin-bottom: 0;
}

/* Material-Design-"Outlined"-Textfeld. Karte bekommt eine einzelne Spalte statt Label/Wert
   nebeneinander, jedes Feld ist ein eigener Block. Werte sind rechtsbuendig, da es (bis auf
   "Name") ausschliesslich Zahlen sind.

   Beschriftung steht als eigene Zeile UEBER dem Feld (docs/024, Feldbeschriftung-Nachtrag,
   Variante 3 - finanzfluss-Muster), nicht mehr schwebend auf der Rahmenlinie (vorherige
   Variante 1, siehe .material-label weiter unten fuer die volle Historie/Begruendung des
   Rueckbaus). Dadurch traegt row-gap wieder den kompletten Feldabstand ohne Sonderfall - keine
   Ueberstands-Reserve fuer ein ueberlappendes Label mehr noetig, row-gap kann von 0,6rem
   zurueck auf 0,5rem (die Label-Zeile selbst braucht jetzt eigenen Platz, siehe
   .material-label margin-bottom). */
.material-calculator .cashflow-material-card {
    grid-template-columns: 1fr;
    row-gap: 0.5rem;
}

/* display:grid statt position:relative (docs/026, Nachtrag): seit die Beschriftung ueber statt in
   das Feld ragt (docs/024, Feldbeschriftung-Nachtrag) besteht .material-field aus zwei Bloecken
   (Label-Zeile, Feld-Zeile). Die Einheit (.material-field-unit, siehe unten) muss sich vertikal an
   der FELD-Zeile ausrichten, nicht an der gesamten .material-field-Hoehe (Label+Feld) - mit reinem
   "position:absolute; top:50%" relativ zur ganzen Field-Box (die alte Loesung, ein Rest aus der
   Zeit vor der Beschriftungs-Umstellung) landete die Einheit zu weit oben, an der Label/Feld-Grenze
   statt vertikal zentriert im Feld (per Messung 7,6px Versatz gefunden, nicht nur angenommen).
   grid-template-rows: Label in Zeile 1, Feld UND Einheit gemeinsam in Zeile 2 (siehe
   .material-field-unit) - Grid erlaubt mehreren Items dieselbe Zelle zu teilen ("Layering"), die
   Einheit kann sich dadurch exakt an der Feld-Zeile zentrieren, unabhaengig von der Label-Hoehe,
   ohne Magic-Number-Pixelwerte. */
.material-calculator .material-field {
    display: grid;
    grid-template-rows: auto auto;
}

.material-calculator .material-field > .material-label {
    grid-row: 1;
}

.material-calculator .material-field > .material-input {
    grid-row: 2;
    grid-column: 1;
}

/* Einheiten im Feld statt im Label (docs/024, Etappe 3): "€"/"%"/"Jahre" rechts im Feld statt als
   Label-Zusatz - kuerzere Labels, Einheit sitzt direkt am Wert. Nur fuer die eindeutigen Faelle
   (reine Einheit ohne weitere Qualifizierung) angewendet - "(%, optional)"/"(jährl.)"/
   "(%, keine Vorbelegung)" bleiben bewusst im Label, dort steckt mehr als nur die Einheit drin.
   :has() erkennt automatisch, ob ein Feld eine Einheit hat, statt einer zusaetzlichen
   Modifier-Klasse auf .material-field - dasselbe Muster wie weiter unten bei
   .card-body:has(.cashflow-result-row).

   grid-row:2 platziert die Einheit in DERSELBEN Zelle wie .material-input (siehe Kommentar oben) -
   justify-self:end + align-self:center zentrieren sie exakt vertikal in der Feld-Zeile, unabhaengig
   von der Label-Hoehe. Faerbt sich ueber das Feld (spaeter im DOM = obenauf gemalt), pointer-events
   :none laesst Klicks weiterhin beim darunterliegenden Feld ankommen. */
.material-calculator .material-field-unit {
    grid-row: 2;
    grid-column: 1;
    justify-self: end;
    align-self: center;
    margin-right: 0.85rem;
    color: var(--rec-text-muted);
    font-size: 0.85rem;
    line-height: 1;
    pointer-events: none;
}

.material-calculator .material-field:has(.material-field-unit) .material-input {
    padding-right: 2.75rem;
}

.material-calculator .material-field:has(.material-field-unit) input[type="number"].material-input {
    padding-right: 2.9rem;
}

/* Zwei Material-Felder nebeneinander statt untereinander (Nutzer-Feedback: Grundanteil+
   Wertsteigerung, Zinssatz+Tilgung, Eigenkapital-Betrag+Prozent). Eigenes 2-Spalten-Grid
   innerhalb der ansonsten einspaltigen .cashflow-material-card.

   auto-fit + minmax statt "1fr 1fr": Ein starres 1fr-1fr-Raster teilt die verfuegbare Breite
   auch dann in zwei Haelften, wenn davon nichts Lesbares uebrig bleibt - bei einem <select>
   blieb dann nur noch der Dropdown-Pfeil sichtbar (Nutzer-Feedback zum Zinssatz-/Tilgungsfeld;
   dort war die Ursache zwar eine andere, siehe Kommentar in CashflowCalculatorGermany.razor,
   aber die starre Aufteilung macht denselben Effekt auch auf schmalen Handy-Viewports moeglich).
   Mit minmax(7.5rem, 1fr) bekommt jedes Feld eine lesbare Mindestbreite - Wert plus
   Prozentzeichen ("4,00 %") passen samt Pfeil-Padding hinein -, und auto-fit stellt die beiden
   Felder automatisch untereinander, sobald zwei Spalten diese Mindestbreite nicht mehr
   einhalten koennen. Auf breiten Karten verhaelt es sich identisch zum bisherigen 1fr 1fr. */
.material-calculator .cashflow-field-pair {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
    column-gap: 0.5rem;
    row-gap: 0.5rem;
}

/* Ruhezustand neutral statt navy (Nutzer-Feedback nach finanzfluss-Vergleich, docs/024): ein
   dauerhaft navy umrandetes Feld war der letzte Rest des Blaustich-Problems aus docs/022 - dort
   wurden nur die rgba(11,37,69,X)-Werte ersetzt, diese bewusste var(--rec-navy)-Randfarbe war
   keiner davon. Farbe zieht erst bei :focus auf Gold, siehe unten - das ist das einzige Signal
   fuer "aktiv", nicht mehr staendig sichtbar. Groesse (Schrift 0,9->1rem, Padding
   0,55/0,7->0,65/0,85rem) angehoben: 1rem verhindert zusaetzlich das automatische Hineinzoomen
   von iOS Safari bei Fokus auf Felder unter 16px Schriftgroesse - ein Mobile-Bedienbarkeitsgewinn
   on top der reinen Grosszuegigkeit.

   Weisser Feldhintergrund zurueckgeholt (docs/024, Feldbeschriftung-Nachtrag, Variante 3): ein
   erster Versuch (Variante 1) hatte den Feldern dieselbe graue Flaeche wie die Karte gegeben,
   weil das ueberlappende Label sonst einen sichtbaren Flicken erzeugte - Nutzer-Korrektur: das
   nahm der gerade erst eingefuehrten Farbumkehrung (Seite weiss, Karten grau, siehe dortiger
   Nachtrag) ihre Wirkung wieder, weil dann alles einheitlich grau wirkte und Eingabefelder nicht
   mehr klar als "hier aenderbar" erkennbar waren - Erkennbarkeit wiegt hier schwerer als eine
   einheitliche Flaeche. Die eigentliche Ursache des Flickens war die ueberlappende Label-Position,
   nicht die Feldfarbe - behoben durch die Label-Umstellung oben (Beschriftung jetzt eigene Zeile
   ueber dem Feld statt auf dem Rahmen), das Problem entfaellt dadurch strukturell, unabhaengig
   von jeder Farbwahl. Der verstaerkte Rahmen (--rec-border-strong, siehe app.css) bleibt: Weiss
   gegen die Kartenflaeche --rec-card-bg kommt nur auf 1,16:1 Kontrast (gemessen) - viel zu wenig,
   um die WCAG-1.4.11-Anforderung (3:1 fuer UI-Komponentengrenzen) allein zu tragen, der Rahmen
   bleibt also der primaere Abgrenzungs-Mechanismus, die Fuellfarbe nur ein zusaetzliches Signal. */
.material-calculator .material-input {
    display: block;
    width: 100%;
    border: 1.5px solid var(--rec-border-strong);
    border-radius: 6px;
    padding: 0.65rem 0.85rem;
    font-size: 1rem;
    background-color: var(--rec-surface);
    text-align: right;
}

.material-calculator .material-input-text {
    text-align: left;
}

/* Rechtsbuendig wie alle anderen Werte; extra padding-right, damit der Text nicht unter
   dem nativen Dropdown-Pfeil landet (Bootstraps eigenes .form-select reserviert dafuer
   Platz, unser einheitliches .material-input-Padding hat das ueberschrieben).
   -webkit-appearance/appearance:none ist noetig, weil iOS Safari bei <select> die
   native (nicht ueberschriebene) Darstellung verwendet und dabei "text-align" ignoriert -
   am Desktop-Browser wirkte text-align, am iPhone blieb der Text trotzdem linksbuendig
   (Nutzer-Feedback). Mit appearance:none wird das Control vollstaendig selbst gestylt,
   der eigene Pfeil (background-image) ersetzt den weggefallenen nativen Pfeil. */
.material-calculator select.material-input {
    text-align: right;
    text-align-last: right;
    padding-right: 2rem;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%230b2545' d='M4 6l4 4 4-4z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.6rem center;
    background-size: 0.9rem;
}

/* Der native Zahlen-Spinner belegt selbst nur ca. 20px direkt nach dem Text - zu viel
   padding-right laesst ihn NICHT an den Rahmenrand wandern, sondern erzeugt Leerraum
   ZWISCHEN Spinner und Rahmen (Nutzer-Feedback). Naeher an der tatsaechlichen
   Spinner-Breite haelt ihn am rechten Rand, mit noch spuerbarem Abstand zum Wert. */
.material-calculator input[type="number"].material-input {
    padding-right: 1.4rem;
}

/* CH-Kantonsauswahl: .cashflow-column-stack sizt ihre Spaltenbreite per "max-content" am
   Inhalt der Karten (siehe Kommentar oben) - fuer ein <select> ist diese intrinsische Breite
   browserabhaengig und war bei manchen Kantonsnamen ("Luzern" -> "Luzer", "Appenzell
   Ausserrhoden") zu knapp bemessen (Nutzer-Feedback, mobiler Browser-Check). min-width erzwingt
   verlaesslich genug Platz fuer den laengsten Kantonsnamen inkl. Pfeil-Padding, unabhaengig von
   der browserspezifischen Intrinsic-Size-Berechnung des <select>. */
.material-calculator select.cashflow-canton-select {
    min-width: 15rem;
}

/* Deutlicherer Fokus-Ring statt des bisherigen 1px-Rahmen-Nachzeichnens (Nutzer-Feedback:
   Barrierefreiheit geht vor Zurueckhaltung) - derselbe Ring-Wert wie das bestehende globale
   .form-control:focus in app.css (0,25rem/4px, 0,25 Deckkraft), damit Fokus-Zustaende app-weit
   konsistent aussehen statt zwei leicht unterschiedliche Ring-Staerken zu haben. */
.material-calculator .material-input:focus {
    outline: none;
    border-color: var(--rec-gold);
    box-shadow: 0 0 0 0.25rem rgba(201, 162, 39, 0.25);
}

/* Deaktivierte Felder: einheitlich hellgrau (Rahmen + Inhalt + Label), weiterhin mit weissem
   Feldhintergrund wie aktive Felder (docs/024, Feldbeschriftung-Nachtrag, Variante 3) - das war
   die urspruengliche, bereits einmal per Nutzer-Feedback abgesegnete Loesung ("wirkt konsistenter
   als eine reine Hintergrundfarbe"): einheitlicher weisser Feldhintergrund fuer aktiv UND
   deaktiviert, Unterscheidung ausschliesslich ueber den schwaecheren Rahmen/Text
   (--rec-text-subtle, heller als das aktive --rec-border-strong). Der zwischenzeitliche Versuch,
   den deaktivierten Feldern den grauen Kartenhintergrund zu geben (waehrend Variante 1 auch
   aktive Felder grau waren), ist mit der weissen Feldflaeche hinfaellig. */
.material-calculator .material-input:disabled {
    background-color: var(--rec-surface);
    border-color: var(--rec-text-subtle);
    color: var(--rec-text-subtle);
}

.material-calculator .material-field:has(.material-input:disabled) .material-label {
    color: var(--rec-text-subtle);
}

/* Beschriftung als eigene, linksbuendige Zeile UEBER dem Feld statt schwebend auf der Rahmenlinie
   (docs/024, Feldbeschriftung-Nachtrag, Variante 3 - finanzfluss-Muster): die vorherige
   "Outlined"-Notch-Technik (position:absolute, top im Minusbereich, Label ragt ~3px in die
   Feldbox hinein) brauchte einen Label-Hintergrund, der exakt zur Flaeche hinter der
   Ueberlappung passt - das war fragil gegenueber jeder Grafarbaenderung (Farbumkehrung brach es
   einmal, siehe die inzwischen ueberholten Kommentare zur Farbumkehrung/Variante-1-Historie in
   diesem Bereich) und haette bei jeder kuenftigen Farbaenderung erneut brechen koennen. Die
   Beschriftung steht jetzt in normalem Fluss VOR dem Feld, ohne Ueberlappung - kein
   Hintergrund-Abgleich mehr noetig (padding/background-color daher entfernt), das Problem
   entfaellt strukturell, unabhaengig von jeder Farbwahl. Kostet dafuer eigenen vertikalen Platz
   pro Feld (siehe Messung docs/024) statt wie vorher komplett ueberlappend "kostenlos" zu sein -
   text-align bewusst nicht gesetzt (erbt "left" vom Block-Default), damit die Beschriftung immer
   linksbuendig steht, auch bei rechtsbuendigen Zahlenfeldern.

   white-space:nowrap entfernt (docs/026, Nachtrag): war ein Rest aus der Notch-Aera (dort noetig,
   damit das schwebende Label nicht in der schmalen Feldbox umbrach), aber seit die Beschriftung
   volle Feldbreite als eigene Zeile hat, ist eine LANGE Beschriftung samt FieldTooltip-Ausloeser
   (z. B. "Erwartete Rendite p.a. ?") in einer schmalen Spalte eines .cashflow-field-pair (zwei
   Felder nebeneinander) durch nowrap ueber den eigenen Spaltenrand hinausgelaufen und hat sichtbar
   das Label des Nachbarfelds ueberlagert (per Messung gefunden: Ausloeser-rechts-Kante 436px,
   Nachbar-Label-links-Kante 429px - Ueberlappung bestaetigt). Ohne nowrap bricht eine zu lange
   Beschriftung stattdessen sauber auf eine zweite Zeile innerhalb der eigenen Spalte um - haelt
   dadurch bei JEDER Feldbreite, nicht nur im gemessenen Fall. line-height 1->1,3, damit zwei
   umgebrochene Zeilen nicht zu eng aneinander kleben. */
.material-calculator .material-label {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.75rem;
    color: var(--rec-navy);
    line-height: 1.3;
}

/* FieldTooltip (docs/024, Etappe 2): "?"-Ausloeser inline im schwebenden Label, dieselbe Stelle,
   an der finanzfluss ihn platziert. inline-flex + position:relative auf dem Wrapper, damit das
   Popover (siehe unten) sich ohne CSS-Anchor-Positioning-API einfach per top/left relativ dazu
   positionieren laesst - ein etabliertes Muster fuer die native Popover-API ohne Anker-Attribut. */
.field-tooltip {
    position: relative;
    display: inline-flex;
    vertical-align: middle;
    margin-left: 0.2rem;
}

/* 18px sichtbar, aber per negativem margin + Padding effektiv ~26px Trefferflaeche (WCAG 2.5.8) -
   ohne dass der Button optisch groesser wirkt als im schwebenden Label sinnvoll waere. */
.field-tooltip-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 4px;
    margin: -4px;
    border: none;
    border-radius: 50%;
    background-color: rgba(201, 162, 39, 0.15);
    color: var(--rec-navy);
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
}

.field-tooltip-trigger:hover {
    background-color: rgba(201, 162, 39, 0.3);
}

.field-tooltip-trigger:focus-visible {
    outline: 2px solid var(--rec-gold-dark);
    outline-offset: 2px;
}

/* [popover]-Elemente werden im offenen Zustand in den Top-Layer verschoben - das bricht die
   normale CSS-Containing-Block-Kette zu einem "position:relative"-Wrapper-Vorfahren (per
   Messung bestaetigt: ein einfaches "position:absolute relativ zum Wrapper" landete bei
   top:906px/left:0px statt direkt unter dem Trigger, weil "top:100%" sich dann auf die
   naechste tatsaechliche Containing-Block-Referenz bezog, nicht mehr auf .field-tooltip).
   Ohne die neuere CSS-Anchor-Positioning-API (noch nicht ueberall unterstuetzt) bleibt fuer
   verlaessliche Positionierung nur "position:fixed" mit Koordinaten aus getBoundingClientRect()
   des Ausloesers - siehe der "toggle"-Event-Listener in RealEstateCalculator.Api.lib.module.js.
   top/left werden dort als Inline-Style gesetzt, hier nur die Optik. */
.field-tooltip-popover {
    position: fixed;
    margin: 0;
    width: max-content;
    max-width: 260px;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--rec-border-strong);
    border-radius: 8px;
    background-color: var(--rec-surface);
    box-shadow: 0 4px 16px var(--rec-shadow-strong);
    color: var(--rec-navy);
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.4;
    white-space: normal;
    text-align: left;
}

/* Elemente, die die volle Kartenbreite einnehmen sollen statt in die Label/Wert-Spalten
   eingeordnet zu werden (Ueberschrift, Name-Feld, Eigenkapital-Umschalter, Platzhaltertext). */
.material-calculator .cashflow-span-all {
    grid-column: 1 / -1;
}

.material-calculator .cashflow-field-row,
.material-calculator .cashflow-result-row {
    display: contents;
}

/* white-space:nowrap entfernt (docs/027, Etappe 3 - beim Mobile-Check von AT's bereits
   bestehender Kennzahlen-Karte gefunden, nicht durch den Umbau verursacht, aber durch die neuen,
   noch laengeren Kennzahlen-Labels in DE/CH ohne Fix zweifach dupliziert worden). Reicht allein
   NICHT (per Messung widerlegt, nicht nur angenommen - siehe naechster Kommentar), bleibt aber
   nötig, damit die Beschriftung ueberhaupt umbrechen KANN, sobald sie eine max-width bekommt. */
.material-calculator .cashflow-field-label,
.material-calculator .cashflow-result-label {
    grid-column: 1;
    font-size: 0.8rem;
    line-height: 1.3;
    margin-bottom: 0;
}

/* Fortsetzung des Fixes oben - der eigentliche Bug lag NICHT an white-space:nowrap. Per
   getComputedStyle nachgemessen: grid-template-columns der Karte war "287px 0px 0px" - Spalte 1
   ("max-content") bemisst sich am UNGEWICKELTEN Text, VOELLIG unabhaengig davon, ob white-space
   Umbruch erlaubt ("normal") oder verbietet ("nowrap") - das ist eine Eigenschaft der CSS-Grid-
   max-content-Spurbemessung selbst (sie misst die Breite "als ob nie umgebrochen wird"), keine
   Eigenschaft von white-space. Das Entfernen von nowrap allein aenderte deshalb nichts an der
   Spurbreite - der Wert-Spalte blieben 0px, "25,4 %" wurde buchstabenweise untereinander
   umgebrochen. Fix: max-width in vw (nicht %, das waere bei intrinsischer Spurbemessung
   unaufloesbar/wirkungslos) deckelt den max-content-Beitrag der Beschriftung selbst bei sehr
   langen Kennzahlen-Titeln wie "Eigenkapitalrendite (inkl. Wertsteigerung & Steuer)" - erst DANN
   greift das oben entfernte white-space:normal tatsaechlich als Umbruch. Nur unterhalb des
   640px-Breakpoints (wie die uebrigen mobilen Anpassungen in dieser Datei) - bei Desktop-
   Kartenbreiten (bis 420px) passt dieselbe Beschriftung bereits einzeilig, siehe Screenshot.

   Warum vw und nicht ch/rem/%: % ist bei intrinsischer (max-content-)Spurbemessung unaufloesbar
   (der Grid-Container hat zum Zeitpunkt der max-content-Berechnung noch keine aufgeloeste Breite -
   ein %-max-width auf dem Item wuerde als "none" behandelt, siehe Kommentar oben). ch/rem sind
   zeichen-/wurzel-schriftgroessenbasiert und damit unabhaengig von der tatsaechlich verfuegbaren
   Kartenbreite - ein fester ch/rem-Wert muesste fuer die laengste vorkommende Beschriftung (DE:
   "Eigenkapitalrendite (inkl. Steuer, ohne Wertsteigerung)") von Hand kalibriert werden und bricht
   bei jeder neuen, noch laengeren Kennzahlen-Beschriftung wieder. vw ist die einzige der drei
   Einheiten, die 1) bei max-content-Spurbemessung ueberhaupt aufloesbar ist (haengt nur vom
   Viewport ab, nicht vom Grid-Container) UND 2) sich mit der verfuegbaren Breite mitskaliert statt
   an einen festen Zeichenwert gebunden zu sein.

   Warum das trotzdem sicher ist, obwohl vw an den VIEWPORT gekoppelt ist, nicht an die KARTE: die
   Regel gilt nur unterhalb 640px - in diesem Bereich ist die Sidebar eingeklappt (siehe
   MainLayout.razor.css, "@media (min-width:641px) { .sidebar{width:250px...} }") und die Karte
   nimmt praktisch die volle Viewport-Breite ein (einspaltiges .cashflow-card-flow, siehe oben in
   dieser Datei) - vw-Anteil und Karten-Anteil fallen dort zusammen. Bei 768px/900px (docs/027,
   Nachtrag) greift die Regel gar nicht (oberhalb 640px), und die Karte ist dort ohnehin auf 420px
   gedeckelt (.cashflow-card-flow minmax) - genug Platz fuer die Wert-Spalte auch ohne Deckel, per
   Screenshot UND getComputedStyle bei beiden Breiten verifiziert (keine Buchstaben-Umbrueche). */
@media (max-width: 640px) {
    .material-calculator .cashflow-field-label,
    .material-calculator .cashflow-result-label {
        max-width: 55vw;
    }
}

/* Ergebnis-Karten (Spalte 3+4: Cashflow/Steuer/Kennzahlen/Vermoegensaufbau/ETF-Vergleich)
   haben keine Material-Eingabefelder, sondern nur Label/Wert-Zeilen - dort duerfen die
   Zeilen enger stehen als das globale row-gap der Karte (Nutzer-Feedback: zu viel
   vertikaler Abstand zwischen den Zeilen). row-gap muss am Grid-Container (.card-body)
   selbst gesetzt werden, nicht an .cashflow-result-row - das ist "display: contents" und
   damit selbst kein Grid-Container. :has() waehlt gezielt nur die Karten aus, die
   ausschliesslich Ergebnis-Zeilen enthalten (Kaufpreis-Karte mit Checkboxen bleibt beim
   groesseren Standard-row-gap). */
.material-calculator .card-body:has(.cashflow-result-row) {
    row-gap: 0.15rem;
}

/* Ergebnis-/Ausgabe-Karten bleiben weiss und bekommen einen goldenen Kopfstreifen, waehrend
   Eingabekarten (siehe .card in app.css) seit der Farbumkehrung (docs/024, finanzfluss-Vergleich
   Nachtrag) grau sind - explizite Vorgabe: Ergebnisbereiche duerfen nicht grau werden, muessen
   weiterhin klar als Ergebnis erkennbar sein. :has(.cashflow-result-row) erfasst alle
   Label/Wert-Ergebniskarten (Cashflow, Steuer, Kennzahlen, Vermoegensaufbau, ETF-Vergleich, ...),
   :has(table) zusaetzlich die Tilgungsplan-/Kapitalentwicklungs-Karten (Kreditrechner,
   Sondertilgung, Zinsrechner) - beides ist berechneter Output, keine Eingabe. Der 2px-Gold-Streifen
   ist dasselbe Akzent-Muster wie .table>thead/.landing-group-title/.nav-tabs .nav-link.active
   (app.css), kein neues Element eingefuehrt. */
.material-calculator .card-body:has(.cashflow-result-row),
.material-calculator .card-body:has(table) {
    background-color: var(--rec-surface);
    border-top: 2px solid var(--rec-gold);
}

/* justify-self:stretch erzwingen: ohne explizite Breite haben die Werte (Spans) nur ihre
   eigene Textbreite eingenommen statt die volle Spaltenbreite, wodurch kuerzere Zahlen
   (z.B. "-92 €") weiter links endeten als laengere in derselben Karte (z.B. "-1.109 €") -
   rechtsbuendiger Text half nichts, wenn die Box selbst schon nur textbreit war
   (Nutzer-Feedback per Screenshot). */
.material-calculator .cashflow-result-row > span:last-child {
    grid-column: 2 / -1;
    text-align: right;
    justify-self: stretch;
}

/* Die Kaufpreis-Karte hat als einzige Checkboxen (Pfandrecht/Makler) - der Wert liegt
   hier in Spalte 3, die Checkbox (falls vorhanden) in Spalte 2 davor, damit sie vor statt
   nach dem Betrag steht (Nutzer-Feedback). Dadurch bleiben alle Werte dieser Karte
   weiterhin in derselben Spalte (3) ausgerichtet, unabhaengig davon, ob eine Zeile eine
   Checkbox hat oder nicht. */
.material-calculator .cashflow-field-row > span {
    grid-column: 3;
    text-align: right;
    justify-self: stretch;
}

.material-calculator .cashflow-field-row > .form-check-input {
    grid-column: 2;
    justify-self: start;
}

/* Annahme-Badges entfernt (docs/024, Nachtrag): jeder vorbelegte Wert ist eine Annahme, auch
   Werte wie der Kaufpreis, die nie ein Badge hatten - vier davon auszuzeichnen und den Rest nicht
   war inkonsequent (Nutzer-Feedback). Die Kennzeichnung traegt jetzt ausschliesslich der
   Einleitungssatz ueber dem Formular ("Alle vorbelegten Werte sind Beispielwerte..."). Der
   Grundanteil-Hinweis, der als einziger noch als sichtbarer Text am Feld stand (docs/015, B.5 -
   "deutlichste Kennzeichnung"), ist aus demselben Grund jetzt ein FieldTooltip wie alle anderen
   Feld-Erklaerungen (siehe CashflowCalculatorGermany.razor) - die fruehere Ausnahme-Begruendung
   war an die inzwischen entfernten Badges gekoppelt und damit hinfaellig. */

.material-calculator .cashflow-toggle-btn {
    padding: 0.1rem 0.4rem;
    font-size: 0.75rem;
}

.material-calculator .cashflow-toggle-group {
    width: 100%;
}

.material-calculator .cashflow-btn {
    max-width: 140px;
}

/* Runde Icon-Buttons statt Text-Buttons fuer "Laden"/"Loeschen" in der Historie-Tabelle -
   moderneres, kompakteres Aussehen (Nutzer-Feedback), Tooltip via title-Attribut ersetzt
   den bisherigen sichtbaren Text. */
.material-calculator .btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border-radius: 50%;
    border: 1.5px solid transparent;
    transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}

.material-calculator .btn-icon-primary {
    color: var(--rec-navy);
    background-color: var(--rec-navy-tint);
}

.material-calculator .btn-icon-primary:hover {
    color: #fff;
    background-color: var(--rec-navy);
}

.material-calculator .btn-icon-danger {
    color: #b02a37;
    background-color: rgba(176, 42, 55, 0.08);
}

.material-calculator .btn-icon-danger:hover {
    color: #fff;
    background-color: #b02a37;
}

.material-calculator .cashflow-flag {
    width: 1.1rem;
    height: 0.8rem;
    object-fit: cover;
    vertical-align: -0.1rem;
    border-radius: 2px;
}

.material-calculator .cashflow-erkenntnis {
    font-size: 0.85rem;
}

.material-calculator .mb-3 {
    margin-bottom: 0.5rem !important;
}

.material-calculator .gap-3 {
    gap: 0.5rem !important;
}

/* Kein separates Mobile-Stack-Layout mehr: Label bleibt immer links vom Wert, genau wie
   am Desktop (Nutzer-Feedback). Das fruehere Umschalten auf eine gestapelte Ansicht war
   noch aus der Zeit vor col-12 auf den vier Cashflow-Spalten (siehe Cashflow.razor) - die
   Karten haben seitdem auf schmalen Bildschirmen ohnehin die volle Breite und damit
   genug Platz fuer Label+Wert nebeneinander. */

/* Tilgungs-/Kapitalentwicklungs-Tabellen (Kreditrechner, Sondertilgung, Zinsrechner, siehe
   Shared/ScheduleTable.razor, docs/020). Nutzer-Feedback: Kopfzeile ("Kapital Jahresanfang" u.
   Ae.) und erste Spalte ("Jahr 1 - Monat 1") brachen auf schmalen Viewports auf mehrere Zeilen um
   (table-layout:auto quetscht die erste Spalte zugunsten der Wert-Spalten) und blaehten dadurch
   jede Zeile auf ~66px statt ~40px auf - bei bis zu 360 Monatszeilen (30 Jahre) erheblich. white-
   space:nowrap verhindert JEDEN unbeabsichtigten Umbruch (auch bei einem einzelnen laengeren
   Zahlenwert als erwartet), die Voll-/Kurzform-Umschaltung (schedule-label-full/-short) loest das
   eigentliche Platzproblem an der Ursache (Textlaenge) statt Spalten zu verstecken - Restschuld/
   Zinsen sind gerade die gefragten Werte, die duerfen nicht wegfallen. Gleicher 640px-Breakpoint
   wie die uebrigen mobilen Anpassungen in app.css. */
.material-calculator .schedule-table th,
.material-calculator .schedule-table td {
    white-space: nowrap;
}

.material-calculator .schedule-table .schedule-label-short {
    display: none;
}

@media (max-width: 640px) {
    .material-calculator .schedule-table .schedule-label-full {
        display: none;
    }

    .material-calculator .schedule-table .schedule-label-short {
        display: inline;
    }
}

/* Rechter Scroll-Fade (docs/020 Nachtrag): auch mit Kurzformen bleibt die letzte Spalte auf
   schmalen Viewports oft breiter als der verfuegbare Platz - ohne sichtbaren Hinweis war nicht
   erkennbar, dass dort noch etwas folgt (mobile Browser blenden Scrollbalken aus). Der Fade-Layer
   liegt AUSSERHALB des scrollenden .table-responsive (eigener, nicht scrollender Wrapper
   drumherum) und bleibt dadurch beim horizontalen Scrollen visuell am rechten Rand stehen - kein
   Sticky/Float-Kampf mit dem <table>-Layout. Sichtbarkeit (opacity) wird per JS umgeschaltet
   (RealEstateCalculator.Api.lib.module.js liest scrollLeft/scrollWidth), nicht per CSS-Masken-
   Trick: Letzterer braucht einen exakt deckenden Hintergrund, was mit den alternierenden
   .table-striped-Zeilenfarben zu einem sichtbaren Farbsprung fuehren wuerde. */
.material-calculator .schedule-table-scroll-wrapper {
    position: relative;
}

.material-calculator .schedule-table-scroll-fade {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 1.5rem;
    pointer-events: none;
    background: linear-gradient(to left, var(--rec-shadow-strong), rgba(0, 0, 0, 0));
    opacity: 1;
    transition: opacity 0.15s ease;
}

.material-calculator .schedule-table-scroll-wrapper.is-not-scrollable .schedule-table-scroll-fade,
.material-calculator .schedule-table-scroll-wrapper.is-scrolled-to-end .schedule-table-scroll-fade {
    opacity: 0;
}

/* Jahresweise gruppierter Tilgungsplan (docs/025): Kreditrechner/Sondertilgung zeigten bis zu 360
   Monatszeilen (30 Jahre) in einer Tabelle - jetzt 30 aufklappbare Jahresgruppen (erstes Jahr
   offen, Rest zu), natives <details>/<summary> wie beim FAQ-Akkordeon (FaqAccordion.razor) -
   aria-expanded automatisch an "open" gekoppelt, kein eigenes JS. Struktur/Spaltenbreiten-
   Begruendung steht in ScheduleTable.razor/ScheduleTableYearGroup.razor. */
/* Feste Pixelbreiten (siehe ComputeColumnWidths in ScheduleTable.razor) sollen die Kopf-Tabelle,
   die <summary>-Zusammenfassung UND jede Detail-Tabelle bei Bedarf breiter als der Viewport werden
   lassen, damit alle drei gemeinsam im .table-responsive-Wrapper scrollen - genau wie die
   urspruengliche flache Tabelle (table-layout:auto + white-space:nowrap) das schon tat. Bootstraps
   .table setzt width:100% (deckelt die Tabelle auf die Viewport-Breite, kein Ueberlauf moeglich),
   width:max-content hebt das gezielt auf: die Box wird exakt so breit wie die Summe der
   deklarierten Spaltenbreiten, unabhaengig vom verfuegbaren Platz. table-layout:fixed erzwingt
   zusaetzlich, dass <table> die <colgroup>-Breiten auch tatsaechlich einhaelt statt sie nur als
   Vorschlag zu behandeln. Ohne diese Regel blieben Kopf-Tabelle/Summary/Detail-Tabelle bei wenig
   Platz auf 100% gedeckelt - Zellinhalte liefen dann ineinander, statt zu scrollen (per
   Browser-Screenshot bei 375px gefunden). */
.material-calculator .schedule-table-fixed-width {
    width: max-content;
}

.material-calculator table.schedule-table-fixed-width {
    table-layout: fixed;
}

.material-calculator .schedule-year-group {
    border-bottom: 1px solid var(--rec-border);
}

.material-calculator .schedule-year-group:last-of-type {
    border-bottom: none;
}

/* Eigener "+"/"-"-Indikator statt des browsereigenen Dreiecks-Markers (dieselbe Technik wie
   .faq-question in app.css) - list-style/marker-Ausblendung + eine zusaetzliche, feste
   Markerspalte am Ende des grid-template-columns (siehe GridTemplateColumns in
   ScheduleTableYearGroup.razor - dort wird "32px" an die von ScheduleTable gereichten
   Spaltenbreiten angehaengt, NUR fuer die Summary, nicht fuer <colgroup>) reserviert Platz dafuer.
   display:grid richtet die Zusammenfassungswerte an denselben Spaltenbreiten aus wie Kopftabelle
   und Detailzeilen. Bewusst OHNE column-gap/eigenes padding auf dem Grid-Container selbst (frueher
   so, per Screenshot als Fehler gefunden): beides wuerde die tatsaechliche Breite ueber die reine
   Summe der Spaltenbreiten hinaus aufblasen, wodurch Summary- und Tabellen-Gesamtbreite
   auseinanderlaufen und Spalten ab der zweiten nicht mehr uebereinander stehen. Stattdessen traegt
   jede Zelle (".schedule-year-summary > *") ihr eigenes Padding, genau wie die Bootstrap-
   Tabellenzellen darunter. white-space:nowrap wird an die Kind-<span>s vererbt, deckt sich mit dem
   nowrap-Verhalten der echten Tabellenzellen unten. */
/* Eigener Hintergrund fuer die Gruppenkopfzeile (docs/026, Nachtrag): ohne ihn war die Summary
   nur an Fettschrift und dem +/--Indikator als Zusammenfassung/aufklappbares Element erkennbar,
   zu unauffaellig. --rec-card-bg ist derselbe zurueckhaltende Grauton, der bereits fuer Eingabe-
   Karten steht ("hier ist eine eigene Flaeche") - passt zum bestehenden Farbsystem, kein neuer
   Ton. Hover geht einen Schritt weiter auf --rec-border (etwas dunkler), damit die interaktive
   Zeile beim Ueberfahren sichtbar reagiert, ohne dass Ruhe- und Hover-Zustand gleich aussehen. */
.material-calculator .schedule-year-summary {
    display: grid;
    align-items: center;
    position: relative;
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
    font-weight: 600;
    color: var(--rec-navy);
    background-color: var(--rec-card-bg);
}

.material-calculator .schedule-year-summary > * {
    padding: 0.5rem;
}

.material-calculator .schedule-year-summary::-webkit-details-marker {
    display: none;
}

.material-calculator .schedule-year-summary::after {
    content: "+";
    position: absolute;
    right: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--rec-gold-dark);
    font-weight: 700;
    font-size: 1rem;
}

.material-calculator .schedule-year-group[open] > .schedule-year-summary::after {
    content: "\2212";
}

.material-calculator .schedule-year-summary:hover {
    background-color: var(--rec-border);
}

.material-calculator .schedule-year-summary:focus-visible {
    outline: 2px solid var(--rec-gold-dark);
    outline-offset: -2px;
}

/* Detail-Tabelle je Jahr sitzt direkt unter der <summary>-Zeile, ohne eigenen Rahmen/Abstand -
   die Gruppengrenze uebernimmt .schedule-year-group{border-bottom}. */
.material-calculator .schedule-table-group-body {
    margin-bottom: 0;
}

/* Zebrastreifen entfernt (docs/026, Nachtrag): bei zwoelf Zeilen pro Jahresgruppe brachten die
   alternierenden .table-striped-Farben wenig Orientierung und wirkten altbacken (Nutzer-
   Feedback). Stattdessen feine Trennlinien zwischen den Zeilen (dezenter als eine komplette
   Hintergrundfarbe) und eine Hervorhebung der Zeile unter dem Mauszeiger - reine Hover-Angabe,
   kein extra JS. :last-child ohne eigene Linie, damit sie nicht doppelt mit der Gruppengrenze
   (.schedule-year-group{border-bottom}) zusammenfaellt. */
.material-calculator .schedule-table-group-body tbody tr {
    border-bottom: 1px solid var(--rec-border);
}

.material-calculator .schedule-table-group-body tbody tr:last-child {
    border-bottom: none;
}

.material-calculator .schedule-table-group-body tbody tr:hover {
    background-color: var(--rec-card-bg);
}

/* Sondertilgungsrechner, zusammengefasste Ergebniskarte (docs/027, Etappe 2): ersetzt die
   vorher zwei sich stark ueberschneidenden Karten "Vergleich"/"Ergebnis" (fast identische Werte
   doppelt angezeigt, Nutzer-Feedback). Die Kopfzeile ("Gesparte Zinsen" + "Frueher schuldenfrei")
   ist die eine Zahl, wegen der man den Rechner aufruft - deutlich groesser als der Rest der Karte,
   damit sie ohne Lesen der Tabelle sofort auffaellt. Primaer-/Sekundaerwert nebeneinander (Desktop)
   bzw. gestapelt (Handy, wie die uebrigen Karten dieser Seite) - reines Flexbox-Wrap statt Grid,
   weil hier nur zwei Elemente stehen, kein Label/Wert-Rasterbedarf wie bei .cashflow-result-row. */
.material-calculator .sondertilgung-headline {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 2rem;
    margin-bottom: 0.5rem;
}

.material-calculator .sondertilgung-headline-primary,
.material-calculator .sondertilgung-headline-secondary {
    display: flex;
    flex-direction: column;
}

.material-calculator .sondertilgung-headline-label {
    font-size: 0.8rem;
    color: var(--rec-text-muted);
}

.material-calculator .sondertilgung-headline-primary .sondertilgung-headline-value {
    font-size: 1.8rem;
    font-weight: 700;
    color: var(--rec-navy);
}

.material-calculator .sondertilgung-headline-secondary .sondertilgung-headline-value {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--rec-navy);
}

/* Dreispaltige Gegenueberstellung (ohne/mit Sondertilgung/Differenz) - bewusst die bestehende
   ScheduleTable-Komponente statt einer neuen Tabellen-Loesung (Nutzer-Vorgabe: pruefen, ob
   ScheduleTable mit Scroll-Fade die passende Grundlage ist). Loest die mobile Lesbarkeit
   dadurch identisch zu den Tilgungsplan-Tabellen: table-responsive-Scroll statt Spaltenumbruch,
   inkl. Scroll-Fade-Hinweis, ohne eigene Media-Query fuer diese Karte. Erste Spalte (Kennzahl-
   Label) wird fett/linksbuendig, die drei Wertespalten rechtsbuendig - Zahlen bleiben dadurch
   untereinander vergleichbar, genau der Zweck der Gegenueberstellung. */
.material-calculator .sondertilgung-comparison-table td:first-child,
.material-calculator .sondertilgung-comparison-table th:first-child {
    text-align: left;
    font-weight: 600;
}

.material-calculator .sondertilgung-comparison-table td:not(:first-child),
.material-calculator .sondertilgung-comparison-table th:not(:first-child) {
    text-align: right;
}
