/* ==========================================================================
   1-zu-1-festgeld.min.css — 1:1-eigenes CSS (Phase 2, Paritaet-Optik)
   Neuaufbau 1-zu-1-Festgeld-Tool modern-banking.at.

   LADEREIHENFOLGE (zwingend, sonst kippen Badge-Farben / fehlen Variablen):
     vergleich.min.css  ->  tabelle.min.css  ->  DIESE Datei.

   Rollenteilung:
     - vergleich.min.css : .vergleich-dashboard-Variablenblock (--accent, --space-*,
                           --text-* …), .anbieter-link, Badge-Basis.
     - tabelle.min.css   : Zell-/Badge-/Zins-/Logo-/Fussnoten-Optik, .anbieter-spalte
                           (Subgrid), .vp-gruppentitel-Grundregel.
     - DIESE Datei       : Grid-GERUEST (grid-template-*, in shared NICHT enthalten),
                           Zell-Einfaerbungen (in der Tabelle inline), 1:1-Spezifika
                           (Auswahl-Formular, Zins-Matrix, Sektions-/Gruppentitel,
                           Merkmal-HTML-Wrapper, Flaggen-Variante).

   Dunkler Panel-Kontext kommt GRATIS aus der globalen style.css:
     body{background:#0070C0}  +  #vergleich{linear-gradient(#0067B0,#0070C0 …)}.
   Das Tool laeuft in <body id="offen"> > #content > #vergleich, hat den blauen
   Grund also automatisch; die transparenten Datenzellen zeigen ihn durch.

   Phase 4 (Section 11-13): Gewinner-Highlight (Hintergrund), Differenz-Toggle,
   Boolean-Icons, Sticky-Kopf + Sticky-Kriterienspalte (dual-axis Scrollbox),
   Mobile Mini-Label + Wisch-Indikator (Phase 6.5/D2: Dots + Edge-Fade statt Stepper).
   Phase 6.5 (Design-Pivot Richtung Alt-Tool, KEINE Rueck-Angleichung an die
   Tabelle): D6 Kriterien-Panel (Section 3/4/11) — seit Anwender-Entscheid
   2026-07-06 im Seiten-Grundton #0070C0 (ohne eigene Hinterlegung, ebenso die
   Logo-/Badge-Kopfzeilen), D3 positionsabhaengige Spaltenfaerbung Pos.1+3
   #0061A6 nur noch auf den Produktdaten (Section 14), D1+P2 Empty-State-
   Ghost-Geruest (Section 15), D4 Kopf entblaut + 2px-Felder an Spaltenposition
   (Section 2/2b), D5 Intro-Abstand (Section 1).
   Bewusst NICHT hier (spaetere Phasen): Combobox (3, Section 2b);
   A11y-/ARIA-Feinschliff, Kopf-Pills (6).
   ========================================================================== */

/* -------------------------------------------------------------------------- *
 * 1. Site-Integration — heller Text auf blauem #vergleich-Grund
 * -------------------------------------------------------------------------- */
.einszueins-tool {
    margin: 0 0 1.5em;
    color: #F1F6FC;
}
/* Intro-Satz: seit 2026-07-06 ein klassenloses <p> (Anwender-Entscheid) —
   Abstaende/Typo kommen aus der style.css (p{margin:2em 0 0} + #vergleich p).
   Die frueheren .einszueins-intro-/.einszueins-hinweis-Regeln sind entfallen
   (Hinweis "Bitte oben bis zu drei ..." ersatzlos gestrichen). */
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 2): ~2em Luft UNTER dem Intro-Satz
   vor den Auswahlfeldern (style.css p{margin:2em 0 0} setzt nur den TOP-Abstand,
   bottom bleibt 0). Eng gescopt aufs direkte <p>-Kind der .einszueins-tool. Die
   per JS spaeter eingehaengten .fg-sr-only-<p> (Diff-Status) sind position:absolute
   -> die margin ist dort layout-neutral. (AP3a) */
.einszueins-tool > p { margin-bottom: 2em; }

/* -------------------------------------------------------------------------- *
 * 2. Auswahl-Formular (native Baseline, Phase 2 — Combobox folgt Phase 3)
 * -------------------------------------------------------------------------- */
/* Phase 6.5/D4: Panel entblaut — kein Kasten mehr, der Kopf wird "leicht";
   alleiniger Blickfang sind die 2px-umrahmten Eingabefelder (Alt-Tool-Anmutung
   "Ihre Auswahl"). padding:0 -> die Felder fluchten mit der Dashboard-Kante. */
.ab-auswahl {
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 2): Bottom-Margin 1.3em -> 0.4em
       -> der "+ drittes Produkt gegenueberstellen"-Slot (Reihe 2 des Formular-Grids)
       rueckt naeher an die Produktdaten (mit .einszueins-dashboard{padding-top:0.25em}
       ergibt sich ~0.65em Gesamtabstand statt ~1.55em). (AP3b) */
    margin: 0 0 0.4em;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
}
.ab-auswahl-reihe {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9em;
}
.ab-auswahl-label {
    display: flex;
    flex-direction: column;
    flex: 1 1 15em;
    min-width: 12em;
    font-size: 0.8rem;
}
.ab-auswahl-labeltext {
    margin-bottom: 0.35em;
    font-weight: 600;
    color: #F1F6FC;
    letter-spacing: 0.02em;
}
.ab-auswahl-select {
    padding: 0.5em 0.6em;
    /* Phase 6.5/D4: 2px-Umrahmung als Blickfang (statt 1px #b9bec7) — dunkler
       Ring um das weisse Feld definiert es klar auf dem blauen Seiten-Grund.
       Bewusst NICHT accent-farbig, damit der :focus-visible-Ring (accent)
       unterscheidbar bleibt. Gilt auch fuer die No-JS-Baseline (gleiche Klasse). */
    border: 2px solid var(--primary-darker, #004578);
    border-radius: 6px;
    background: #fff;
    color: #222;
    font-size: 0.95rem;
    font-family: inherit;
}
.ab-auswahl-select:focus-visible {
    outline: 2px solid var(--accent, #00d4aa); /* Ring bei offset:2px auf blauem Panel -> ~3,4:1 (WCAG 1.4.11) */
    outline-offset: 2px;
}
.ab-auswahl-btn {
    margin-top: 1em;
    padding: 0.6em 1.4em;
    border: 0;
    border-radius: 6px;
    background: var(--accent, #00d4aa);
    color: var(--primary-darker, #004578);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 150ms ease;
}
.ab-auswahl-btn:hover { background: var(--accent-light, #00ffcc); }
.ab-auswahl-btn:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* -------------------------------------------------------------------------- *
 * 2b. Such-/Auswahl-Combobox (Phase 3, Progressive Enhancement)
 *     Das JS setzt .fg-enhanced auf das Formular -> native Reihe + Button
 *     werden ausgeblendet (bleiben im DOM als No-JS-Baseline + Wert-Speicher),
 *     die .fg-combo-Instanzen treten an ihre Stelle. Mobil (<=600px) enhanct
 *     das JS nicht -> die native Reihe bleibt sichtbar (Section 10).
 * -------------------------------------------------------------------------- */
.ab-auswahl.fg-enhanced .ab-auswahl-reihe { display: none; }
.ab-auswahl.fg-enhanced .ab-auswahl-btn  { display: none; }

.fg-combo-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9em;
    align-items: flex-start;
}
/* Phase 6.5/D4: Felder an Spaltenposition (Alt-Tool-Zeile "Ihre Auswahl").
   Gleiche Spaltenlogik wie das Geruest: 1. Track = vp-Breite (leerer Offset,
   Feld A startet via grid-column:2), dann je sichtbarem Feld eine Spalte
   (--fg-felder setzt das JS: 2 default, 3 nach Zuschalten). minmax(0,1fr)
   statt minmax(11em,1fr): das Formular scrollt nicht — bei genug Platz (kein
   H-Scroll im Geruest) sind beide 1fr und fluchten; bei H-Scroll-Engstellen
   schrumpfen die Felder statt ueberzulaufen (bewusste Naeherung). */
.ab-auswahl.fg-enhanced .fg-combo-wrap {
    display: grid;
    grid-template-columns: var(--e1-vp-breite, 13em) repeat(var(--fg-felder, 2), minmax(0, 1fr));
    gap: 0.5em 0;
    align-items: start;
    /* Gleiche horizontale Einrueckung wie .vergleich-dashboard{margin:.. 1%}
       (vergleich.min.css) — sonst sitzen die Felder ~1% links vom Geruest
       (live gemessen: 16px Versatz). Beide sind Kinder von .einszueins-tool
       -> 1% derselben Bezugsbreite = exakte Fluchtung. */
    margin: 0 1%;
}
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-combo {
    min-width: 0;
    padding-right: 1em; /* Luft zur Nachbarspalte; Feld-Start fluchtet mit Spaltenkante */
}
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-combo[data-slot="a"] { grid-column: 2; }
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 3 / AP2): Entfernen-Links sind jetzt
   DIREKTE Grid-Kinder der .fg-combo-wrap (nicht mehr in der .fg-combo) — die
   DOM-Reihenfolge (buildComboWrap) ist Felder-zuerst, dann alle Clears -> Tab-Fluss
   erst durch alle Auswahlfelder, dann durch die Entfernen-Links. Optisch sitzt jeder
   Clear in Grid-Zeile 2 unter seiner Feld-Spalte (Spuren: 1=vp-Track, 2=Slot A,
   3=Slot B, 4=Slot C). Da die Wrap auf ALLEN sichtbaren Breiten ein Grid ist (601px+;
   <601px komplett display:none, native Reihe), fluchtet Zeile 2 automatisch — es gibt
   KEIN gestapeltes Layout, daher auch kein CSS-order-Interleave noetig. */
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-combo-clear {
    grid-row: 2;
    align-self: start;
    justify-self: start;
    margin-top: 0.15em; /* dezent unter dem Feld (statt der Innen-Combo-Luft 0.4em) */
}
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-combo-clear[data-slot="a"] { grid-column: 2; }
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-combo-clear[data-slot="b"] { grid-column: 3; }
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-combo-clear[data-slot="c"] { grid-column: 4; }
/* [hidden] muss die .fg-combo-clear{display:inline-flex}-Basis schlagen (gleiche
   Spezifitaet -> das UA-[hidden]{display:none} verloere sonst per Quellreihenfolge).
   Betrifft v.a. den immer angelegten, aber bis zum Reveal versteckten Slot-C-Clear. */
.fg-combo-clear[hidden] { display: none; }
/* "+ drittes Produkt gegenueberstellen": Anwender-Entscheid 2026-07-06 (Runde 3 /
   AP2): in Grid-Zeile 3 (UNTER den Clears), NICHT mehr Zeile 2 — sonst kollidierte
   der Button bei gefuelltem Slot B mit Clear-B (beide row 2, Spalte 3, wenn Slot C
   leer ist -> --fg-felder=2, grid-column:-2 == Spalte 3). Spannt die Feldbreite
   (Spalte 2..-1), links ausgerichtet. Bei sichtbarem Slot C ist der Reveal hidden
   (display:none) -> Zeile 3 existiert nicht, die Clears sind letzte Reihe. */
.ab-auswahl.fg-enhanced .fg-combo-wrap > .fg-add-slot {
    grid-row: 3;
    grid-column: 2 / -1;
    justify-self: start;
    align-self: start;
    margin-top: 0;
}
/* Fluchtung im 601-640px-Fenster: das Dashboard verschmaelert --e1-vp-breite
   auf 8.5em (Section 10) — die Var lebt auf .einszueins-dashboard und erreicht
   das Formular nicht, daher hier der gleiche Wert explizit. */
@media (max-width: 40em) {
    .ab-auswahl.fg-enhanced .fg-combo-wrap {
        grid-template-columns: 8.5em repeat(var(--fg-felder, 2), minmax(0, 1fr));
    }
}
/* Anwender-Entscheid 2026-07-06: auf groesseren Displays schliesst die
   Kriterienspalte BUENDIG mit dem ersten Navigations-Feld (Logo) ab, das 1/6
   von 100% breit ist (style.css: #nav li{width:16.66%}; unterhalb 72em schaltet
   die Nav auf 33% -> gleicher Breakpoint hier). Herleitung der Prozentkette
   (Bezug = Seitenbreite): #vergleich margin .9% + width 98% (style.css),
   Dashboard/Formular margin 1% davon -> Scroller-/Formular-Linke bei 1.88%,
   Breite 96.04%. Track = (100%/6 - 1.88%) / 0.9604 der eigenen Breite ->
   rechte Kante exakt bei 16.667%. Gilt fuer Dashboard UND Formular-Grid
   (D4-Spaltenfluchtung, identische Bezugsbreite, s. Kommentar oben). Ab 140em
   kappt style.css nur die Nav (max-width) — dort wandert die Kante minimal
   weiter (akzeptierter Extremfall). */
@media (min-width: 72.0625em) {
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 2 / AP2): --e1-vp-breite (der
       Dashboard-Track) wird hier NICHT mehr gesetzt. Diese Deklaration stand VOR
       der unbedingten Basis .einszueins-dashboard{--e1-vp-breite:13em} (Section 3,
       weiter unten) — gleiche Spezifitaet (0,1,0), Media-Queries geben keinen
       Spezifitaets-Bonus -> die spaetere 13em-Basis gewann per Quellreihenfolge,
       sodass die vp-Spur im Dashboard-Grid trotz calc auf 13em haengenblieb (der
       calc kam nie am Scroller-var(--e1-vp-breite) an). Der Track wird jetzt in
       Section 17 NACH der Basis gesetzt und gewinnt. Das Formular-Grid unten nutzt
       den calc DIREKT (kein var -> keine Cascade-Kollision) und bleibt daher hier. */
    .ab-auswahl.fg-enhanced .fg-combo-wrap {
        grid-template-columns: calc((100% / 6 - 1.88%) / 0.9604) repeat(var(--fg-felder, 2), minmax(0, 1fr));
    }
}
.fg-combo {
    display: flex;
    flex-direction: column;
    flex: 1 1 15em;
    min-width: 12em;
    font-size: 0.8rem;
    position: relative;
}
.fg-combo[hidden] { display: none; }
.fg-combo-label {
    margin-bottom: 0.35em;
}
.fg-combo-field {
    position: relative;
}
/* Selektor mit .ab-auswahl-Praefix (0,2,0): die globale style.css-Regel
   input[type="text"],...{border-width:1px} hat (0,1,1) und schluege die blosse
   Klasse — live gemessen (AP3-Smoke-Check). Der Select braucht das nicht
   (Element-Selektor verliert gegen .ab-auswahl-select). */
.ab-auswahl .fg-combo-input {
    width: 100%;
    box-sizing: border-box;
    padding: 0.5em 2.1em 0.5em 0.6em; /* rechts Platz fuer den Toggle */
    border: 2px solid var(--primary-darker, #004578); /* Phase 6.5/D4, wie .ab-auswahl-select */
    border-radius: 6px;
    background: #fff;
    color: #222;
    font-size: 0.95rem;
    font-family: inherit;
}
.fg-combo-input::placeholder { color: #6b7280; }
.fg-combo-input:focus-visible {
    outline: 2px solid var(--accent, #00d4aa); /* Ring bei offset:2px auf blauem Panel -> ~3,4:1 (WCAG 1.4.11) */
    outline-offset: 2px;
}
.fg-combo-toggle {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 2em;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: transparent;
    color: #4a5568;
    font-size: 0.85rem;
    cursor: pointer;
}
.fg-combo-toggle:focus-visible {
    outline: 2px solid #0a6353; /* inset (offset:-2px) auf weissem Toggle-Grund -> ~7:1 (WCAG 1.4.11) */
    outline-offset: -2px;
}
.fg-combo-clear {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;  /* WCAG 2.5.8 AA Zielgroesse (Combobox = Desktop) */
    min-height: 24px;
    margin-top: 0.4em;
    padding: 0.15em 0.3em;
    border: 0;
    background: transparent;
    color: #F1F6FC;
    font-size: 0.78rem;
    text-decoration: underline;
    cursor: pointer;
    opacity: 0.85;
}
.fg-combo-clear:hover { opacity: 1; }
.fg-combo-clear:focus-visible {
    outline: 2px solid var(--accent, #00d4aa);
    outline-offset: 2px;
    opacity: 1;
}

/* Popup-Liste */
.fg-combo-list {
    position: absolute;
    z-index: 30;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 0.25em 0;
    max-height: 18em;
    overflow-y: auto;
    list-style: none;
    background: #fff;
    color: #222;
    border: 1px solid #b9bec7;
    border-radius: 6px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28);
    font-size: 0.9rem;
}
.fg-combo-list[hidden] { display: none; }
.fg-combo-group {
    padding: 0.45em 0.7em 0.2em;
    font-weight: 700;
    font-size: 0.78rem;
    color: #09578f;
    text-transform: none;
}
.fg-combo-option {
    padding: 0.4em 0.7em 0.4em 1.1em; /* leicht eingerueckt unter dem Bank-Header */
    cursor: pointer;
    color: #222;
}
/* is-active = aria-activedescendant-Proxy (kein DOM-Fokus); Hover gleichwertig.
   Farbwechsel statt transparenter Raender (High-Contrast-sicher, APG). */
.fg-combo-option:hover,
.fg-combo-option.is-active {
    background: var(--accent, #00d4aa);
    color: var(--primary-darker, #004578);
}
/* Highlight sowohl in Optionen ALS AUCH im Bank-Gruppenkopf (sonst Browser-
   Default-Gelb im Header). Kein Hintergrund -> High-Contrast-sicher. */
.fg-combo-list mark {
    background: transparent;
    color: inherit;
    font-weight: 700;
    text-decoration: underline;
}
.fg-combo-none {
    padding: 0.5em 0.7em;
    color: #666;
    font-style: italic;
}

/* Reveal-Buttons ("+ Produkt gegenueberstellen" / "+ drittes Produkt") */
.fg-add-slot {
    align-self: center;
    margin-top: 1.4em; /* auf Hoehe der Input-Reihe (Label-Hoehe kompensiert) */
    padding: 0.55em 0.9em;
    border: 1px dashed rgba(255, 255, 255, 0.5);
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.08);
    color: #F1F6FC;
    font-size: 0.85rem;
    cursor: pointer;
    white-space: nowrap;
}
.fg-add-slot:hover { background: rgba(255, 255, 255, 0.16); }
.fg-add-slot:focus-visible {
    outline: 2px solid var(--accent, #00d4aa);
    outline-offset: 2px;
}
.fg-add-slot[hidden] { display: none; }

/* Screenreader-only (Live-Region) — clip-Technik, NICHT display:none. */
.fg-sr-only {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
@media (prefers-reduced-motion: reduce) {
    .fg-combo-option { scroll-behavior: auto; }
}

/* -------------------------------------------------------------------------- *
 * 3. Dashboard-Panel + Grid-Geruest
 *    (.tabelle-scroller/.vp-spalte/.tabelle-grid-Grundmechanik liegt in der
 *     Tabelle inline, NICHT in shared CSS -> hier nachgebaut. .anbieter-spalte
 *     [Subgrid] kommt aus tabelle.min.css.)
 * -------------------------------------------------------------------------- */
.einszueins-dashboard {
    /* Zeilenhoehen — als minmax-Fallbacks in den --e1-rows-Tracks referenziert
       (der Core setzt die Track-Liste je nach Slotzahl per Inline-style). */
    --e1-hdr-logo-h: 6.5rem;
    --e1-hdr-badge-h: 2rem;
    /* Phase 6.5/P4: Titel-Zeilen-Track leicht erhoeht (2.6rem -> 2.9rem) -> die
       Gruppen-/Sektionsbaender bekommen mehr Luft, verstaerkt die Segmentierung.
       Zentrale Var (Subgrid-Fluchtung bleibt: Core referenziert sie im --e1-rows). */
    --e1-row-titel-h: 2.9rem;
    --e1-row-data-h: 2.75rem;
    --e1-row-cta-h: 2.4rem;
    --e1-vp-breite: 13em;
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 3 / AP6): der Rest-Abstand nach
       "+ drittes Produkt" bis zur ersten Dashboard-Zeile kam zu ~8px aus der
       Shared-Regel .vergleich-dashboard{margin:var(--space-sm) 0} (vergleich.min.css)
       — deren margin-top hier gekillt (eigenes CSS laedt zuletzt, gleiche Spezifitaet
       -> gewinnt). Rest: Formular-Bottom 0.4em (.ab-auswahl) + padding-top 0.25em =
       ~0.65em wie gewuenscht. margin-bottom der Shared-Regel bleibt (unter den
       Fussnoten, AP6-irrelevant). */
    margin-top: 0;
    padding-top: 0.25em;
}

/* Scroller wird zum AEUSSEREN Grid (ueberschreibt das shared .tabelle-scroller-
   Flex per Ladereihenfolge): 1 Label-Spalte + Anbieter-Bereich; traegt die
   Row-Tracks. vp-Spalte und Anbieter-Grid uebernehmen die Rows per SUBGRID, die
   .anbieter-spalte (shared) verschachtelt ihrerseits per Subgrid. So werden die
   auto-Zeilenhoehen EINMAL zentral (ueber Label + alle Werte einer Zeile)
   berechnet -> perfekte Fluchtung, auch bei mehrzeiligen Merkmal-Werten.
   (Getrennte Grids mit minmax(...,auto) wuerden ihre Hoehen unabhaengig
   berechnen und die Labels aus der Fluchtung schieben.) */
.einszueins-scroller {
    display: grid;
    grid-template-columns: var(--e1-vp-breite, 13em) minmax(0, 1fr);
    grid-template-rows: var(--e1-rows);
    align-items: stretch;
    /* Scroll-Container fuer den HORIZONTALEN Ueberlauf (Sticky-Kriterienspalte,
       Section 12). Anwender-Entscheid 2026-07-06: KEINE Innen-Hoehe mehr
       (frueher max-height:82vh + scroll-padding-top) — der Vergleich scrollt
       normal mit der Seite, nicht zusaetzlich in sich selbst. Konsequenz: das
       vertikale top-Sticking der Kopfzellen (Section 11) ist inert, weil
       position:sticky nur im eigenen Scrollport klebt und der Kasten vertikal
       nicht mehr scrollt. position:sticky aendert WEDER Box-Groesse NOCH
       Track-Teilnahme -> die Subgrid-Fluchtung bleibt unberuehrt (§3). */
    overflow: auto;
    padding-bottom: 0.5em;
}

/* Vergleichspunkt-Spalte (Kriterien-Labels links). Phase 4: Sticky-Kriterienspalte
   (Desktop) — klebt beim HORIZONTALEN Scroll am linken Rand des Scrollers (z-4,
   ueber den Kopf-Zellen z-3, damit die Ecke beim Diagonal-Scroll obenauf liegt).
   Solider Hintergrund (nicht 0.92), sonst scheinen gescrollte Spalten durch.
   Auf Mobile ausgeblendet (Section 13, Mini-Labels ersetzen sie). */
.einszueins-dashboard .vp-spalte {
    grid-column: 1;
    grid-row: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: subgrid;
    position: sticky;
    left: 0;
    z-index: 4;
    /* Anwender-Entscheid 2026-07-06: Kriterienspalte OHNE eigene Hinterlegung —
       optisch der normale Seiten-Grund. Technisch trotzdem der Seiten-Grundton
       #0070C0 (body, style.css) statt transparent: ZWINGEND deckend (sticky-
       left!), sonst schienen beim H-Scroll die Datenspalten durch. */
    background: #0070C0;
    border-right: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 6px 0 0 6px;
    box-shadow: 0.25em 0 0.5em rgba(0, 0, 0, 0.2);
}

/* Anbieter-Grid: fuellt den Rest neben der vp-Spalte (1-3 Slots gleichbreit).
   Subgrid-Rows vom Scroller; die .anbieter-spalte (shared) verschachtelt weiter.
   Phase 4: minmax(11em,1fr) statt minmax(0,1fr) -> Spalten schrumpfen nicht mehr
   unlesbar; bei drei Produkten auf mittlerer Breite laeuft der Scroller horizontal
   ueber -> die Sticky-Kriterienspalte wird wirksam. Weit genug fuellt 1fr. */
.einszueins-dashboard .tabelle-grid {
    grid-column: 2;
    grid-row: 1 / -1;
    display: grid;
    grid-template-columns: repeat(var(--anzahl-anbieter, 1), minmax(11em, 1fr));
    grid-template-rows: subgrid;
    min-width: 0;
}

/* Fallback fuer Browser OHNE CSS-Subgrid (~vor 2023): die verschachtelte
   Subgrid-Fluchtung greift nicht. Konsistent auf ein gestapeltes Block-Layout
   degradieren, statt halb-grid/halb-block zu brechen (der shared
   @supports-Fallback in tabelle.min.css setzt nur vp-spalte/anbieter-spalte/
   zellen auf block, nicht den hier neu eingefuehrten Grid-Scroller). Lesbar,
   wenn auch ohne zeilenweise Label/Wert-Fluchtung. Moderne Zielbrowser (Baseline
   2023+) betreten diesen Pfad nicht. Voller Mobile/Fluchtungs-Ersatz = Phase 4. */
@supports not (grid-template-rows: subgrid) {
    .einszueins-scroller {
        display: block;
        overflow: visible;
        max-height: none;
    }
    .einszueins-dashboard .vp-spalte,
    .einszueins-dashboard .tabelle-grid,
    .einszueins-dashboard .anbieter-spalte {
        display: block;
        width: auto;
        grid-template-rows: none;
    }
    /* Ohne Scrollport wuerde Sticky am Viewport kleben -> im Block-Fallback aus. */
    .einszueins-dashboard .vp-spalte,
    .einszueins-dashboard .vp-spalte .vp-header,
    .einszueins-dashboard .anbieter-spalte .ab-zelle.ab-logo,
    .einszueins-dashboard .anbieter-spalte .ab-zelle.ab-badge {
        position: static;
    }
    .einszueins-dashboard .vp-spalte {
        border-right: none;
        border-radius: 6px 6px 0 0;
        box-shadow: none;
    }
}

/* -------------------------------------------------------------------------- *
 * 4. Zell-Einfaerbungen — in der Tabelle inline (Z.1022/1061), hier nachgezogen
 * -------------------------------------------------------------------------- */
/* Anwender-Entscheid 2026-07-06: Logo-Zeile ("Anbieter") und Badge-Zeile
   (Inlands-/Auslandsanlage) OHNE Hinterlegung in ALLEN Spalten — das Banklogo
   soll auf dem normalen Seiten-Grund stehen und nie umrahmt wirken. Technisch
   der Seiten-Grundton #0070C0 statt transparent: die Kopfzellen sind sticky
   (Section 11) und muessen die darunterlaufenden Zeilen deckend verbergen;
   zugleich deckt er die Spalten-Tinte (Section 14) hinter den Kopfzeilen ab.
   Die frueheren Kopf-Toene (Logo #0070C0/Badge #09578f) und der Pos.1/3-
   Override sind damit entfallen; einziger Badge-Setzer ist Section 11.
   (border-top-right-radius der Logo-Zelle entfernt: im Seiten-Grundton ist die
   Rundung unsichtbar, liesse aber in Pos.1/3 die Spalten-Tinte als Eck-Keil
   durchblitzen.) */
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 3 / AP3): Logo-Zeile jetzt auf ALLEN
   Breiten transparent (frueher #0070C0, dann Desktop-transparent in Section 17). Die
   Logo-Zelle ist NIE sticky-left; ihr top-Sticking ist inert (Innen-Scrollport
   entfallen) -> die Deckungs-Invariante ist nicht betroffen (vp-Spalte + fg-sticky-mini
   bleiben deckend). In Pos.1+3 scheint die Spalten-Tinte #0061A6 (Section 14) durch,
   in Pos.2 der Seiten-Verlauf — kohaerent mit der Spalte darunter, wie die Tabelle. */
.einszueins-dashboard .ab-zelle.ab-logo {
    background: transparent;
}

/* -------------------------------------------------------------------------- *
 * 5. "Alle Zinssaetze" — 3-Spalten-Zins-Matrix (1:1-Differenzierer, eigen)
 * -------------------------------------------------------------------------- */
.einszueins-dashboard .ab-zelle.ab-matrix-titel,
.einszueins-dashboard .ab-zelle.ab-matrix-zeile {
    justify-content: stretch;
    align-items: center;
    padding: 0.3em 0.625em;
}
.einszueins-dashboard .ab-zins-matrix {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.4em;
    width: 100%;
}
.einszueins-dashboard .ab-zins-matrix > span {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary, #fff);
    font-size: 0.85rem;
    min-width: 0;
    overflow-wrap: anywhere;
}
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 4 / AP3): Bestwert-Toenung fuellt die
   Zellhoehe (Girokonto-Anmutung "ganze Zelle"). Hoehenmodell: die Matrix-Datenzelle
   streckt (statt zentriert) ihre .ab-zins-matrix auf die volle Zellhoehe, die Matrix
   streckt ihre einzige Grid-Reihe (align-content:stretch), die Spans fuellen die Reihe
   und zentrieren den Text INNEN per Flex -> die Textposition bleibt exakt (war schon
   zentriert), nur die Span-/Toenungsflaeche waechst. Zellhoehe unveraendert (Track
   minmax(2.75rem,auto); Inhalt <=44px -> kein Wachstum -> Klapp-Tween/--e1-rows
   unberuehrt). NUR die Daten-Reihe (.ab-matrix-zeile), NICHT die Legende
   (.ab-matrix-titel). Die Zell-Umstellung (vertikales Padding 0 + stretch) nur >=601px
   (Tabellen-Layout); <601px bleibt die Karten-Matrix (flex-column, eigenes Padding)
   unangetastet — dort ist die Matrix ohnehin inhaltshoch (kein Full-Height-Effekt). */
@media (min-width: 601px) {
    .einszueins-dashboard .ab-zelle.ab-matrix-zeile {
        align-items: stretch;
        padding-top: 0;
        padding-bottom: 0;
    }
}
.einszueins-dashboard .ab-matrix-zeile .ab-zins-matrix { align-content: stretch; }
.einszueins-dashboard .ab-matrix-zeile .ab-zins-matrix > span {
    display: flex;
    align-items: center;        /* Text vertikal zentriert -> Position wie zuvor */
    justify-content: flex-end;  /* rechtsbuendig (Flex-Ersatz fuer text-align:right) */
}
.einszueins-dashboard .ab-matrix-legende > span {
    font-size: 0.62rem;
    line-height: 1.15;
    /* AA-Kontrast auf #0070C0/#0061A6: 0.55 lag bei ~2,6:1 (Verstoss bei echtem
       Inhalts-Text); 0.92 ~4,9:1 auf #0070C0, auf dem dunkleren #0061A6 besser. */
    color: rgba(255, 255, 255, 0.92);
    text-align: right;
    text-transform: none;
}

/* "Anbieter"-Label (Kriterien-Kopf): shared .75 laege bei ~3,6:1 auf dem hellen
   Grund -> hier auf .92 (~4,6:1). Nur diese Text-Farbe, gescoped. */
.einszueins-dashboard .vp-header.vp-logo {
    color: rgba(255, 255, 255, 0.92); /* ~4,6:1 auf #0070C0 */
}
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 4 / AP2): Kriterien-Dunkelblau der
   Merkmal-Labels entfernen. Quelle ist die SHARED Basis-Regel .vp-zelle{background:
   rgba(9,87,143,0.92)} (tabelle.min.css) — sie faerbt ALLE vp-Zellen; hier fuer die
   Merkmal-Labels neutralisiert (eigenes CSS laedt zuletzt, Selektor 0,3,0 schlaegt
   die 0,1,0-Basis zusaetzlich). Wirkung je Breite: Desktop (vp-Spalte transparent,
   Section 17) zeigt den Seiten-Verlauf (Plateau ~#0070C0); 601-72em zeigt die
   deckende, sticky-left vp-Spalte #0070C0 (Deckungs-Invariante ueber den CONTAINER
   gewahrt, nicht angefasst); <601px ist die vp-Spalte display:none (Mini-Labels).
   AA: der SHARED Kriterien-Text ist rgba(255,255,255,0.78) — auf dem nun HELLEN
   #0070C0 nur ~3,8:1 (auf dem dunklen alten Grund war er ok). Darum hier auf VOLL
   #fff angehoben -> ~5,1:1 auf #0070C0 (bzw. ~5,5:1 auf dem etwas dunkleren
   Verlaufs-Tief #0067B0) -> AA ok. NUR vp-merkmal (Merkmal- + Laufzeit-Labels);
   Sektions-/Gruppen-Baender unberuehrt. HINWEIS (Bericht): vp-matrix-legende
   ("Anlagebetrag"), vp-footer, vp-print tragen dieselbe Basis-Faerbung + 0.78-Text
   weiter — bewusst NICHT in AP2-Scope. */
.einszueins-dashboard .vp-zelle.vp-merkmal {
    background: transparent;
    color: #fff;
}
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 4 / AP2b): die restlichen dunkelblauen
   Kriterien-Zellen konsequent mitziehen — vp-matrix-legende ("Anlagebetrag"), vp-footer
   ("Zum Anbieter") und vp-print ("Druck"). Diese drei sind LEERE vp-Zellen (nur
   aria-label, kein sichtbarer Text -> keine Textkontrast-Anhebung noetig): sie tragen
   bisher denselben Shared-.vp-zelle-Grund rgba(9,87,143,0.92) bzw. (vp-footer) die
   Shared-Override rgba(9,87,143,0.96) und standen als dunkelblaue Streifen zwischen den
   nun transparenten Merkmal-Reihen. Jetzt transparent wie vp-merkmal. NUR die Baender
   (vp-gruppentitel) behalten ihre Band-Optik. Deckung bei H-Scroll (601-72em) kommt vom
   deckenden vp-Spalte-Container #0070C0 (nicht angefasst); <601px vp-Spalte display:none. */
.einszueins-dashboard .vp-zelle.vp-matrix-legende,
.einszueins-dashboard .vp-zelle.vp-footer,
.einszueins-dashboard .vp-zelle.vp-print {
    background: transparent;
}
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 3 / AP3): der fruehere 1:1-Badge-
   Override (rgba(0,77,64,0.5)/#d8f8ee, rgba(90,62,0,0.5)/#ffeab0) ist ENTFALLEN —
   er stammte aus der Zeit des hellen #0070C0-Badge-Zeilen-Grunds; seit die Badge-
   Zelle transparent ist (Section 11/AP3), greift wieder die Shared-Basis aus
   tabelle.min.css (badge-inland rgba(76,181,160,0.18)/#b9f0e1, badge-ausland
   rgba(220,180,40,0.18)/#ffe49a) -> volle Tabellen-Parität (leichte Tints).
   AA (bewusste Paritaets-Ausnahme): die Inland-Pill ueber #0061A6 (Pos.1+3) liegt
   bei ~4,3:1 (knapp unter AA 4,5:1); ueber #0070C0 (Pos.2) etwas besser. Nicht rein
   farb-codiert (die Pill traegt Klartext "Inlandsanlage"/"Auslandsanlage"). */

/* -------------------------------------------------------------------------- *
 * 6. Gruppentitel-Baender (inkl. "Alle Zinssaetze")
 *    Die Titel bleiben statische <div> (No-JS-Baseline). Phase 6.5/P9: das JS
 *    ruestet den vp-Gruppentitel (Desktop) bzw. den Gruppentitel-Spacer der 1.
 *    Anbieter-Spalte (Mobile) zu einem Klapp-Button auf (Chevron + aria-expanded)
 *    -> Sektion 6b. Seit 2026-07-06 ist auch "Alle Zinssaetze" eine klappbare
 *    Gruppe in identischer Reihen-Struktur (vp-gruppentitel + Spacer-Zellen);
 *    der fruehere inerte .vp-sektiontitel ist aus dem Markup entfallen.
 * -------------------------------------------------------------------------- */
/* Gestreifte Band-Optik — EINE Regel fuer Titel-Label (vp) UND Spacer-Zellen
   (anbieter), damit Label + Wert einer Titel-Reihe identisch aussehen und nicht
   auseinanderdriften. Alpha 0.04 = Paritaet zu tabelle.min.css Z.39/41
   (.ab-gruppe-spacer / button.vp-gruppentitel). */
.einszueins-dashboard .vp-zelle.vp-gruppentitel,
.einszueins-dashboard .ab-zelle.ab-gruppe-spacer {
    /* AP1b (Politur-Runde 4): der 0.04-Ueberzug ist jetzt ein IMAGE-Layer (letzte
       Ebene, direkt ueber der Farbe) statt background-color -> er kompositioniert
       ueber der Zell-Tinte (Section 14), ohne von deren hoeherer Spezifitaet
       geschlagen zu werden. background-color explizit transparent: in Pos.1/3 setzt
       die Zell-Tinte #0061A6, sonst scheint der Backdrop durch (Optik unveraendert). */
    background-color: transparent;
    background-image:
        radial-gradient(circle, rgba(255, 255, 255, 0.08) 0 0.7px, transparent 1.1px),
        radial-gradient(circle, rgba(4, 36, 64, 0.14) 0 0.7px, transparent 1.1px),
        linear-gradient(rgba(0, 0, 0, 0.04), rgba(0, 0, 0, 0.04));
    background-size: 6px 6px, 8px 8px, auto;
    background-position: 0 0, 3px 4px, 0 0;
    background-repeat: repeat, repeat, no-repeat;
    /* Phase 6.5/P4: kraeftigere Trennlinie (1px/.10 -> 1.5px/.16) zwischen den
       Kriterien-Gruppen -> die Segmentierung wird deutlicher lesbar. */
    border-top: 1.5px solid rgba(255, 255, 255, 0.16);
    border-bottom: 1px solid rgba(255, 255, 255, 0.07);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
/* Textliche Titel-Optik nur fuer die Label-Zellen.
   Phase 6.5/D6: Textfarbe von var(--accent-light,#5fd4b8) auf helleres Mint
   gehoben — auf hellem Panel-Grund laege #5fd4b8 weit unter 4,5:1 (12px bold =
   normaler Text, AA verlangt 4,5:1). Seit dem Seiten-Grundton #0070C0 der
   Kriterienspalte (2026-07-06) nochmals leicht aufgehellt: #c9f2e6 laege auf
   dem Band ueber #0070C0 nur noch bei ~4,5:1, #d9f7ee ~4,9:1. */
.einszueins-dashboard .vp-zelle.vp-gruppentitel {
    color: #d9f7ee;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em; /* Phase 6.5/P4: leicht geweitet, betont die Gruppen-Titel */
    line-height: 1.15;
}
/* Spacer-Zelle selbst bleibt inert (die shared .ab-gruppe-spacer{cursor:pointer}
   zuruecksetzen) — geklappt wird ueber den eingebetteten Button (P9, Sektion 6b),
   nicht die ganze Zelle; der Button traegt seinen eigenen cursor:pointer. */
.einszueins-dashboard .ab-zelle.ab-gruppe-spacer {
    cursor: default;
}

/* -------------------------------------------------------------------------- *
 * 6b. PHASE 6.5 / P9 — Klapp-Button der Kriterien-Gruppen (JS-Aufwertung)
 *     Das JS zieht den statischen Titel-Text in einen transparenten <button>
 *     (Desktop: im vp-Gruppentitel; Mobile: Icon-Button im Spacer der 1. Spalte).
 *     Cross-View-Vertrautheit zur Tabelle: Chevron rotiert bei aria-expanded.
 *     Band-Optik + Text-Farbe kommen weiter von der Titel-Zelle (Sektion 6) —
 *     der Button erbt sie (font/color:inherit), traegt selbst keine Flaeche.
 * -------------------------------------------------------------------------- */
.einszueins-dashboard .fg-gruppe-btn {
    flex: 1 1 auto;
    align-self: stretch;      /* fuellt die Band-Hoehe -> volle Klickflaeche */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5em;
    width: 100%;
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    font: inherit;            /* erbt Titel-Typo (Groesse/Gewicht/Familie) */
    color: inherit;           /* erbt Titel-Farbe (#d9f7ee, Sektion 6) */
    letter-spacing: inherit;
    text-transform: inherit;
    text-align: left;
    cursor: pointer;
}
.einszueins-dashboard .fg-gruppe-btn:focus-visible {
    outline: 2px solid var(--accent, #00d4aa);
    outline-offset: -2px;     /* inset: bleibt in der Zelle, kein Sticky-Ueberlauf */
}
.einszueins-dashboard .fg-gruppe-btn-text {
    min-width: 0;
    overflow-wrap: break-word;
    /* "Ausschüttung/Auszahlung" braucht 2 Zeilen: break-word bricht sonst nackt
       mitten im Wort (AUSZAH|LUNG). Mit hyphens bricht der Browser am deutschen
       Trennpunkt inkl. Trennstrich; greift nur bei gesetztem lang-Attribut. */
    hyphens: auto;
}
.einszueins-dashboard .fg-gruppe-caret {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 0;
    color: inherit;
    transition: transform 180ms ease;
}
.einszueins-dashboard .fg-gruppe-btn[aria-expanded="true"] .fg-gruppe-caret {
    transform: rotate(180deg);
}
/* Mobile-Icon-Button: Desktop ausgeblendet (dort toggelt der vp-Button); wird
   erst <=600px eingeblendet (Sektion 13). Dashboard-gescopet (0,2,0), damit es
   die .einszueins-dashboard .fg-gruppe-btn{display:flex}-Basisregel schlaegt. */
.einszueins-dashboard .fg-gruppe-btn--mobile { display: none; }

/* -------------------------------------------------------------------------- *
 * 7. Merkmal-HTML-Wrapper — laesst <br> im DB-Wert als Umbruch wirken
 *    (.ab-zelle ist Flex-Container; ein einzelnes Span-Kind buendelt den Inhalt)
 * -------------------------------------------------------------------------- */
.einszueins-dashboard .ab-merkmal-html {
    display: block;
    text-align: right;
    line-height: 1.35;
}

/* -------------------------------------------------------------------------- *
 * 8. Laenderflagge — KEIN eigener Override. Die Variante (Emoji vs. PNG) regelt
 *    die shared tabelle.min.css: Default Emoji, `.no-emoji-flags` -> PNG. Das
 *    `.no-emoji-flags`-Flag setzt die Canvas-Feature-Detection im Entry (wie die
 *    Tabelle), damit Emoji-faehige Clients Emoji, nicht-emoji-faehige (z.B.
 *    Windows) die PNG-Grafik sehen -> volle Paritaet zur Tabelle/Liste.
 * -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- *
 * 9. Fussnoten — Block .tabelle-fussnoten kommt aus shared CSS; hier nur Abstand
 * -------------------------------------------------------------------------- */
.einszueins-fussnoten {
    margin-top: 1.5em;
}

/* -------------------------------------------------------------------------- *
 * 9b. Druck-Icon je Produktspalte (CTA-Fusszeile). Reiner <a> (No-JS), sitzt
 *     neben dem "zum Anbieter"-Link in der .ab-cta-Zelle. Kompaktes, dezent
 *     abgesetztes Icon-Ziel (der Anbieter-CTA bleibt der solide Accent-Button);
 *     Mobile-Touch-Target >=44px in Section 13. Phase 6.5/D8: .ab-cta von der
 *     shared flex-row auf flex-column umgestellt -> das Druck-Icon sitzt UNTER dem
 *     "zum Anbieter"-Button (Alt-Tool-Anmutung), rechtsbuendig (align-items:flex-end,
 *     spiegelt das shared justify-content:flex-end der Row). Reihenfolge stimmt im
 *     Markup (Core: Anbieter-Link vor Druck-Icon) -> kein Markup-Change.
 * -------------------------------------------------------------------------- */
.einszueins-dashboard .ab-zelle.ab-cta {
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5em;
    /* AP1b (Politur-Runde 4): der shared 0.04-Overlay (.ab-zelle.ab-cta{background:
       var(--bg-card,rgba(0,0,0,0.04))}, tabelle.min.css Z.36) wird hier auf einen
       IMAGE-Layer + explizit transparente background-color umgestellt -> er
       kompositioniert ueber der Zell-Tinte (Section 14, Pos.1/3), statt von deren
       hoeherer Spezifitaet geschlagen zu werden; Pos.2 zeigt den 0.04 ueber dem
       Verlauf (Optik unveraendert). */
    background-color: transparent;
    background-image: linear-gradient(rgba(0, 0, 0, 0.04), rgba(0, 0, 0, 0.04));
}
.einszueins-dashboard .fg-print-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 2 / AP6): kein Quader mehr —
       nur noch das Symbol sichtbar (background/border weg). Klick-/Touch-Flaeche
       bleibt voll (min-width/height 2.2em, mobil 44px in Section 13); border-radius
       bleibt fuer den :focus-visible-Ring. */
    min-width: 2.2em;
    min-height: 2.2em;
    padding: 0.3em 0.45em;
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm, 6px);
    color: var(--text-primary, #fff);
    text-decoration: none;
    line-height: 1;
    cursor: pointer;
    transition: color 150ms ease, opacity 150ms ease;
}
/* AP6: der Rahmen war zuvor der einzige Hover-/Interaktivitaets-Hinweis -> als
   Ersatz dezentes Icon-Feedback (Accent-Faerbung), damit Anklickbarkeit erkennbar
   bleibt. Die :focus-visible-Regel (Tastatur-Sichtbarkeit) bestand bereits. */
.einszueins-dashboard .fg-print-link:hover { color: var(--accent-light, #5fd4b8); }
.einszueins-dashboard .fg-print-link:focus-visible {
    outline: 2px solid var(--accent, #00d4aa);
    outline-offset: 2px;
}
/* Phase 6.5/D8: Icon auf Alt-Tool-Groesse (~1.55em); line-height:1 am Link haelt
   die Zentrierung, das 2.2em/44px-Ziel bleibt gross genug (Touch-Target). */
.einszueins-dashboard .fg-print-link .icon { font-size: 1.55em; }

/* AP4b (Politur-Runde 3): Einzeldruck-Reihe unter den Daten (letzte Grid-Reihe).
   Symbol rechtsbuendig wie die CTA-Zelle (flex-end), kleiner Abstand zur CTA-Reihe
   darueber. Kein Band, keine eigene Hinterlegung: background transparent -> zeigt (wie
   die CTA-Reihe) die Spalten-Tinte in Pos.1+3 durch. Die .fg-print-link-Optik
   (transparent, Focus-Ring, 44px-Touch mobil) kommt aus Section 9b oben / Section 13.
   Die Zelle traegt bewusst kein data-label -> kein Mobile-::before (Symbol genuegt). */
.einszueins-dashboard .ab-zelle.ab-print {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    background: transparent;
    padding-top: 0.45em;
}

/* -------------------------------------------------------------------------- *
 * 10. Responsive-Basics (voller Mobile-Feinschliff = Phase 4)
 * -------------------------------------------------------------------------- */
@media (max-width: 40em) {
    .einszueins-dashboard {
        --e1-vp-breite: 8.5em;
    }
    .einszueins-dashboard .ab-zins-matrix > span { font-size: 0.72rem; }
    .einszueins-dashboard .ab-matrix-legende > span { font-size: 0.55rem; }
    .ab-auswahl-label { flex-basis: 100%; }
}

/* Mobile-Combobox-Weiche (<=600px, Entscheidung Phase 3): CSS-getrieben, NICHT
 * init-gesteuert (resize-fest). Das JS baut die Combobox immer (.fg-enhanced),
 * hier wird sie ausgeblendet und die native <select>-Reihe + Button (OS-Picker)
 * treten wieder hervor. Gleicher 600px-Breakpoint wie der JS-Submit-Guard (kein
 * px/em-Desync). font-size 16px verhindert den iOS-Auto-Zoom beim Fokus. */
@media (max-width: 600px) {
    .ab-auswahl.fg-enhanced .fg-combo-wrap { display: none; }
    .ab-auswahl.fg-enhanced .ab-auswahl-reihe { display: flex; }
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 5 / AP4c): der "Vergleich anzeigen"-
       Button wird bei .fg-enhanced NICHT mehr mobil wieder eingeblendet -> er bleibt
       ueber die unbedingte Regel (Z.133) versteckt; das JS submittet bei Auswahl-
       Aenderung direkt (enhance). Ohne JS (.fg-enhanced fehlt) zeigt der Button wie
       bisher. (Die fruehere Zeile .ab-auswahl-btn{display:inline-block} ist entfallen.) */
    /* AP4a (Runde 5): Slot C nur zeigen, wenn gefuellt — der Core setzt fg-native-leer
       auf das leere C-Feld; hier im enhanced Mobile ausblenden -> nur zwei Felder. Ohne
       JS bleibt die volle 3-Feld-Baseline (.fg-enhanced fehlt -> Regel greift nicht). */
    .ab-auswahl.fg-enhanced .ab-auswahl-label.fg-native-leer { display: none; }
    .ab-auswahl-select { font-size: 16px; }
}

/* ========================================================================== *
 * 11. GEGENUEBERSTELLUNG (Phase 4) — Sticky-Kopf, Gewinner-Highlight, Boolean
 * ========================================================================== */

/* --- Kopf-Zellen: das top-Sticking ist seit dem Wegfall der Innen-Scrollhoehe
   INERT (Anwender-Entscheid 2026-07-06, Section 3: der Kasten scrollt vertikal
   nicht mehr in sich; position:sticky klebt nur im eigenen Scrollport). Die
   Regeln bleiben bewusst stehen — harmlos, und bei Rueckkehr einer Innen-Hoehe
   sofort wieder aktiv. Solide Hintergruende bleiben Pflicht: die Sticky-LEFT-
   Kriterienspalte (Section 12) schiebt sich beim H-Scroll ueber die Spalten,
   z-3 (Kopf) < z-4 (Kriterienspalte). Die --e1-hdr-*-Variablen speisen weiter
   die Row-Tracks (--e1-rows, JS-nachgemessen). Den Seiten-Scroll-Kopf
   uebernimmt die Sticky-Mini-Leiste (Section 12, .fg-sticky-mini +
   setupStickyMini im JS — Tabellen-Paritaet). */
.einszueins-dashboard .ab-zelle.ab-badge {
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 3 / AP3): Badge-Zelle jetzt auf
       ALLEN Breiten transparent (frueher #0070C0, dann Desktop-transparent Section 17)
       -> die Shared-Pill-Tints (badge-inland/-ausland, Section 5) wirken wieder wie in
       der Tabelle. Nie sticky-left; top-Sticking inert -> Deckungs-Invariante nicht
       betroffen (vp-Spalte + fg-sticky-mini bleiben deckend). Pos.1+3 zeigt die
       Spalten-Tinte #0061A6, Pos.2 den Seiten-Verlauf durch. */
    background: transparent;
}
/* Kopf-Labels der Kriterienspalte: solide (sticky!), gleiche Deckfarbe wie
   .vp-spalte (Seiten-Grundton, Anwender-Entscheid 2026-07-06), damit die
   Sticky-Ecke beim Diagonal-Scroll nahtlos bleibt. */
.einszueins-dashboard .vp-zelle.vp-header {
    background: #0070C0;
}
.einszueins-dashboard .anbieter-spalte .ab-zelle.ab-logo,
.einszueins-dashboard .anbieter-spalte .ab-zelle.ab-badge {
    position: sticky;
    z-index: 3;
}
.einszueins-dashboard .anbieter-spalte .ab-zelle.ab-logo  { top: 0; }
.einszueins-dashboard .anbieter-spalte .ab-zelle.ab-badge { top: var(--e1-hdr-logo-h, 6.5rem); }
/* Kopf-Labels in der (sticky-left) Kriterienspalte auch sticky-top -> die Ecke
   bleibt oben links stehen (nested sticky: top-im-left-Sticky-Elternteil). */
.einszueins-dashboard .vp-spalte .vp-header { position: sticky; }
.einszueins-dashboard .vp-spalte .vp-header.vp-logo  { top: 0; }
.einszueins-dashboard .vp-spalte .vp-header.vp-badge { top: var(--e1-hdr-logo-h, 6.5rem); }

/* --- Gewinner-Highlight (E10, „nur Hintergrund"): der eindeutig hoechste Zins je
   Zeile ueber die aktiven Slots. WCAG-Hinweis: der KLEINE weisse Matrix-Text auf
   dem dunklen #vergleich-Grund liegt schon nahe an AA (~5:1) — eine AUFHELLUNG
   wuerde ihn unter 4.5:1 druecken. Darum ein dunkles Akzent-Teal (Marken-
   Highlightfarbe), das den Kontrast HAELT/erhoeht statt ihn zu senken. Zusaetzlich
   traegt jede Gewinnerzelle serverseitig ein .fg-sr-only „(hoechster Wert)" ->
   nicht rein farb-codiert (WCAG 1.4.1). Nur Hintergrund, kein Badge/Rahmen. */
.einszueins-dashboard .ab-zins-matrix > span.ab-mz--top {
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 2 / AP5): flache Zellen-Toenung
       im Girokonto-AT-Stil (girokonto-tabelle-core.inc.php Z.681-684) statt des
       radialen Chips — kein Gradient, keine Pille. Der Span ist ein Grid-Item der
       .ab-zins-matrix (align-items:stretch default) -> die Toenung fuellt die Zelle
       voll (Hoehe der Zeile, Breite der Matrix-Spur), wirkt als Flaeche, nicht als
       Streifen. E10-konform (NUR Hintergrund).
       AA-Pruefung (weisser Matrix-Text #fff, ~0.85rem = normaler Text, verlangt
       4,5:1) — rgba(76,181,160,0.28) alpha-compositiert:
         ueber #0061A6 (Positionen 1+3, Section 14) -> ~rgb(21,121,164) -> ~4,9:1 (AA ok).
         ueber #0070C0 (Position 2, ohne Spalten-Tinte)  -> ~rgb(21,131,183) -> ~4,2:1
         (UNTER AA 4,5:1!). Der fruehere dunkle Verlauf (#0d7a66/#0a6353) hielt hier
         >5:1; die flache helle Toenung senkt den Kontrast in Position 2 knapp unter
         AA. Nicht rein farb-codiert (E10): jede Gewinnerzelle traegt zusaetzlich das
         .fg-sr-only "(hoechster Wert)". OFFENER PUNKT an den Anwender (s. Bericht):
         ggf. Toenung leicht abdunkeln/opaker, falls AA in Position 2 zwingend. */
    background: rgba(76, 181, 160, 0.28);
    border-radius: 0;
}

/* BR5 (Brokerage): das Gewinner-Highlight der Order-Zeilen liegt auf GANZEN
   Merkmal-Zellen (.ab-zelle.ab-mz--top) und ist in Section 14 definiert — es
   MUSS im Quelltext NACH den Positions-Tinten stehen (Kaskade bei gleicher
   Spezifitaet 0,5,0), sonst schluckt die nth-child(1/3)-Zell-Tinte den Tint.
   Tint-Wert dort mit dieser Matrix-Regel synchron halten! */

/* --- Boolean-Icons (Gemeinschaftskonto/Minderjaehrige): Haken statt Roh-Marker,
   rechtsbuendig wie die uebrigen Merkmal-Werte. aria-label ja/nein tragen die
   Spans (Core). Haken in normaler Schriftfarbe der Zelle (inherit), NICHT in
   Akzentfarbe — Anwender-Entscheid 2026-07-09 (TG-2-Politur). */
.einszueins-dashboard .ab-merkmal-bool { justify-content: flex-end; }
.einszueins-dashboard .ab-bool { font-size: 1.05rem; line-height: 1; }
.einszueins-dashboard .ab-bool-ja   { color: inherit; font-weight: 700; }
.einszueins-dashboard .ab-bool-nein { color: rgba(255, 255, 255, 0.5); }

/* ========================================================================== *
 * 12. DIFFERENZ-TOGGLE (Phase 4, reine JS-Aufwertung) + Wisch-Indikator
 * ========================================================================== */

/* Das JS injiziert den Toggle nur bei >= 2 Slots (.is-active). Zeilen mit in
   allen aktiven Spalten identischen Werten werden komplett ausgeblendet: das JS
   setzt den Row-Track im --e1-rows auf 0 UND die Zellen auf .fg-row-collapsed
   (kollabiert; overflow:hidden verhindert Ueberlaufen des 0-Tracks). Phase 6.5/P9:
   .fg-row-collapsed ist der GEMEINSAME Kollaps-Hook fuer Diff UND zugeklappte
   Gruppen (ein Sichtbarkeits-Pfad updateRowVisibility, AP5 §2.1). */
.fg-diff-toggle { display: none; }
.fg-diff-toggle.is-active {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    /* CT-0247: Einheitshoehe der ganzen Familie. Der Hint-Zusatz macht den Text
       auf fg/tg/rt zweizeilig, ohne ihn bleibt er einzeilig -> zwei Hoehenklassen
       (live gemessen 2026-09-04, Playwright 1280px: 42,09px gegen 29,86px). Die
       Untergrenze rechnet deshalb in derselben em-Basis wie der Inhalt statt in
       festen px: 0.8em Padding + 1.25em Hauptzeile + 0.9em Hint (0.72em bei
       line-height 1.25) = 2.95em, dazu 2px Rahmen. Ein fester px-Wert eint nur
       bei 16px Wurzelschrift; bei 20px kaeme der Versatz mit 10px zurueck, bei
       12px stuenden beide Varianten auf 42px und damit rund 10px zu hoch fuer
       ihre Schrift (beides gemessen). box-sizing steht hier, damit der Wert die
       Aussenhoehe bleibt, auch wenn die globale style.css fehlt oder nach diesem
       Blatt laedt. Mobil hebt Section 13 den Wert per max() auf das 44px-Touch-
       Ziel an, ohne die Einheitshoehe zu verlieren. */
    box-sizing: border-box;
    --fg-diff-toggle-hoehe: calc(2.95em + 2px);
    min-height: var(--fg-diff-toggle-hoehe);
    margin: 0 0 0.9em;
    padding: 0.4em 0.75em;
    background: rgba(9, 87, 143, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 8px;
    color: #F1F6FC;
    font-size: 0.85rem;
    cursor: pointer;
}
/* Zweizeiliger Text-Block: Haupt-Label + kleinerer Hint darunter (TG-4-Folge:
   Zins-/Rendite-Matrix bleibt beim Diff-Toggle stehen). */
.fg-diff-toggle-text { display: inline-flex; flex-direction: column; line-height: 1.25; }
.fg-diff-toggle-hint { font-size: 0.72em; font-weight: 400; opacity: 0.85; }
/* Phase 6.5/P7: "Nur Unterschiede zeigen" als moderner Switch (appearance:none).
   Track 2.2em x 1.2em, Knopf via ::before; :checked = Accent + dunkler Knopf.
   Das Touch-Ziel >=44px traegt das umschliessende Label (.fg-diff-toggle, mobil
   min-height:44px, Section 13) -> Klick aufs Label kippt den nativen Checkbox-
   Zustand (SR liest checked/unchecked). Non-Text-Kontrast (WCAG 1.4.11): weisser
   Knopf auf Accent/Track >=3:1, Track-Rand delineiert. Transition wird unter
   prefers-reduced-motion neutralisiert (Section 12). */
.fg-diff-toggle input {
    appearance: none;
    -webkit-appearance: none;
    position: relative;
    flex: 0 0 auto;
    width: 2.2em;
    height: 1.2em;
    margin: 0;
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-radius: 1em;
    background: rgba(255, 255, 255, 0.22);
    cursor: pointer;
    transition: background 150ms ease, border-color 150ms ease;
}
.fg-diff-toggle input::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 0.14em;
    width: 0.86em;
    height: 0.86em;
    border-radius: 50%;
    background: #fff;
    transform: translateY(-50%);
    transition: transform 150ms ease, background 150ms ease;
}
.fg-diff-toggle input:checked {
    background: var(--accent, #00d4aa);
    border-color: var(--accent, #00d4aa);
}
.fg-diff-toggle input:checked::before {
    transform: translate(1em, -50%);
    background: var(--primary-darker, #004578);
}
.fg-diff-toggle input:focus-visible {
    outline: 2px solid var(--accent, #00d4aa);
    outline-offset: 2px;
}
.einszueins-dashboard .fg-row-collapsed {
    min-height: 0 !important;
    height: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    border-top: 0 !important;
    border-bottom: 0 !important;
    box-shadow: none !important;
    overflow: hidden !important;
    /* Phase 6.5/AP5-F9: nimmt fokussierbaren Inhalt (Links in html-Feldern) aus
       Tab-Order + Accessibility-Tree (WCAG 2.4.7) — sonst unsichtbarer Fokus in
       der 0-Hoehe-Reihe. Layout unveraendert (keine Transition; Messungen [Header/
       Wisch] betreffen nur sichtbare Kopf-/Spalten-Boxen). */
    visibility: hidden !important;
}

/* ("Link kopieren"/Share-Button 2026-07-06 entfernt — Anwender-Entscheid.) */

/* Klapp-Hoehen-Tween (Paritaet zur Tabellenansicht .gruppe-anim, 200ms ease +
   opacity-Soft-Fade 180ms). Transient: das JS setzt .fg-gruppe-anim nur fuer
   die Tween-Dauer auf den Scroller (die Row-Tracks leben dort zentral, Subgrid
   haelt vp + Spalten synchron) — permanent ginge nicht, weil --e1-rows
   minmax(...,auto) enthaelt (auto nicht interpolierbar, Endzustand spraenge).
   .fg-row-fade/.fg-row-fading blenden die Reihen-Zellen parallel weich ein/aus;
   overflow:hidden clippt den Inhalt sauber im schrumpfenden Track. */
.einszueins-scroller.fg-gruppe-anim {
    transition: grid-template-rows 200ms ease;
}
.einszueins-dashboard .fg-row-fade {
    transition: opacity 180ms ease;
    overflow: hidden;
    min-height: 0;
}
.einszueins-dashboard .fg-row-fade.fg-row-fading { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    /* Zustands-Sprung statt Animation; das JS ueberspringt den Tween zusaetzlich. */
    .einszueins-scroller.fg-gruppe-anim { transition: none; }
    .einszueins-dashboard .fg-row-fade { transition: none; }
}

/* Sticky-Mini-Leiste — Seiten-Scroll-Kopf (Paritaet zur Tabelle, tabelle.min.css
   Z.57-62 .tabelle-sticky-mini): position:fixed-Logo-Leiste, die das JS
   (setupStickyMini) einfahren laesst, sobald der echte Kopf oben aus dem
   Viewport gescrollt ist — das inerte position:sticky kann das seit dem
   Wegfall des Innen-Scrollports nicht mehr (Section 3/11). Eigene fg-*-Klassen
   statt der shared .tabelle-sticky-mini: deren @supports-scroll-timeline haengt
   an .tabelle-wrapper/timeline-scope + --scroll-max-x (Tabellen-JS) — hier
   uebernimmt JS-translateX den H-Sync. left/right + Spalten-Tracks (gemessene
   px der 1fr-Spalten) setzt das JS inline. */
.fg-sticky-mini {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 30;
    transform: translateY(-100%);
    transition: transform 0.18s ease;
    pointer-events: none;
    overflow: hidden;
    background: #0070C0;
    box-shadow: 0 0.25em 0.5em rgba(0, 0, 0, 0.3);
}
.fg-sticky-mini.is-active { transform: translateY(0); }
.fg-sticky-mini-track {
    display: grid; /* Spalten-Tracks inline per JS (gemessene px-Breiten) */
    will-change: transform;
}
.fg-mini-spalte {
    display: flex;
    flex-direction: column;
    /* Rechtsbuendig wie .anbieter-spalte-mini der Tabelle — und wie die eigene
       Logo-Kopfzelle darunter (.ab-logo-wrap: justify-content flex-end, Zelle
       text-align right). Der fruehere `center` war doppelt falsch: er brach die
       Paritaet zur Tabelle UND liess das Logo beim Einfahren der Leiste von
       rechts in die Mitte springen (Anwender-Befund 2026-08-11). Mit
       flex-direction: column wirkt align-items horizontal. */
    align-items: flex-end;
    justify-content: center;
    /* Gilt dem Text-Fallback (Zelle ohne Logo-Bild): sonst stuende eine
       umbrechende Zeichenkette linksbuendig in der rechtsbuendigen Box. */
    text-align: right;
    min-width: 0;
    padding: 0.375em 0.625em;
    border-right: 1px solid rgba(255, 255, 255, 0.05);
    overflow: hidden;
    /* BEWUSST OHNE font-size (Politur 2026-08-11). Die Zelle erbt die
       Site-Typo-Skala aus style.css — `body{font-size:96%}` bzw. `80%` im
       `@media (max-width:38em)`-Block. Der Logo-Cap unten haengt in em daran
       und ergibt damit von selbst 92,16 px auf Desktop und 76,8 px mobil,
       exakt wie die Tabelle (deren `.anbieter-spalte-mini` ebenfalls keine
       font-size deklariert). Die fruehere feste `font-size: 0.8rem` war der
       Grund fuer die kleineren Logos im 1:1-Sticky-Kopf (Anwender-Befund
       2026-08-11) — sie NICHT wieder einsetzen, auch nicht mit dem heutigen
       Zielwert: ein fester Wert friert die Paritaet zur Tabelle auf den
       Zeitpunkt ein und bricht sie bei der naechsten globalen Typo-Aenderung
       still. Der Text-Fallback ohne Logo-Bild skaliert so ebenfalls mit. */
}
.fg-mini-spalte:last-child { border-right: none; }
/* Auch svg: der Anker-Klon zieht das ganze Logo-Markup des DB-Feldes mit, und
   ein Inline-SVG ohne intrinsische Groesse fiele sonst auf die 300x150-Default-
   Box zurueck und blaehte die fixe Leiste auf (frueher unmoeglich — geklont
   wurde ein einzelnes <img>). */
.fg-mini-spalte img,
.fg-mini-spalte svg {
    max-height: 6em; /* Cap wie .ab-mini-logo der Tabelle */
    max-width: 100%;
    height: auto;
    width: auto;
    object-fit: contain;
    /* Block statt inline: sonst laesst der Descender-Raum des Anker-Kastens
       einen Spalt unter dem Logo. Bewusst hier und nicht als line-height:0 am
       Anker — der wuerde ein reines Text-Logo (Logo-Feld ohne Bild) im Anker
       zusammenfallen lassen. */
    display: block;
}
/* Anbieterinfo-Anker im Sticky-Kopf (Klon der Logo-Kopfzelle). Block, damit der
   Klick-Hotspot die ganze Logo-Flaeche deckt.
   pointer-events NUR am Anker, nicht an der ganzen Leiste (dort anders als in
   der Tabelle, tabelle.min.css Z.58): der 1:1-Vergleich scrollt am Mittel-/
   Mobile-Breakpoint horizontal, und ein Wisch, der auf der Leiste beginnt, soll
   weiterhin zum Scroller darunter durchgehen. Nur im eingefahrenen Zustand —
   ausgefahren liegt die Leiste ohnehin ausserhalb des Viewports. */
.fg-mini-spalte .ab-logo-link {
    display: block;
    max-width: 100%;
}
.fg-sticky-mini.is-active .ab-logo-link { pointer-events: auto; }
@media (max-width: 38em) {
    /* Mobile bleibt bei der bisherigen 1:1-Groesse (0.8rem -> 76,8 px). Die
       Tabelle ist hier mit 0.72rem (69,12 px) etwas kleiner; angeglichen wurde
       bewusst nur der Desktop-Wert (Anwender-Entscheid 2026-08-11), weil die
       1:1-Leiste mobil ohnehin schon die groesseren Logos zeigt. */
    .fg-mini-spalte { font-size: 0.8rem; }
}
@media (prefers-reduced-motion: reduce) {
    .fg-sticky-mini { transition: none; }
}

/* Wisch-Indikator (Edge-Fade + Dots) — ersetzt den fruehen Ziffern-Stepper.
   Sichtbarkeit rein JS-gesteuert nach realer Scrollbreite (kein Breakpoint noetig):
   das JS setzt .has-overflow (Fade) bzw. .is-visible (Dots) nur bei echtem Overflow;
   auf Desktop passen alle Spalten -> beides bleibt aus. */

/* Positionsbezug fuers Edge-Fade-Overlay. Das JS huellt den Scroller pro Render in
   diese Shell; sie scrollt nicht -> der Scroller bleibt Sticky-Containing-Block. */
.fg-scroll-shell { position: relative; }

/* Edge-Fade: absolut positioniertes Overlay-GESCHWISTER am rechten Scroller-Rand
   (NICHT als mask auf dem Scroller -> das braeche position:sticky, §P3). Nur sichtbar,
   solange rechts noch Scroll-Rest ist (.has-overflow). pointer-events:none -> faengt
   keine Klicks/Wische ab. Weit weg von der sticky-left vp-Spalte -> kein Konflikt. */
.fg-edge-fade {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 2.5em;
    z-index: 2;
    pointer-events: none;
    background: linear-gradient(to right, transparent, rgba(0, 112, 192, 0.55));
    opacity: 0;
    transition: opacity 150ms ease;
}
.fg-scroll-shell.has-overflow .fg-edge-fade { opacity: 1; }

/* Dot-Indikatoren: Button-Gruppe (KEIN tablist). Optisch kleiner Pip, Klickflaeche
   >=44px via Button-Groesse (Touch, WCAG 2.5.5). Nur bei Overflow (.is-visible). */
.fg-dots {
    display: none;
    justify-content: center;
    gap: 0.15em;
    margin: 0.6em 0 0;
}
.fg-dots.is-visible { display: flex; }
.fg-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}
.fg-dot-pip {
    width: 0.55em;
    height: 0.55em;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.4);
    transition: background 150ms ease, transform 150ms ease;
}
.fg-dot[aria-current="true"] .fg-dot-pip {
    background: var(--accent, #00d4aa);
    transform: scale(1.25);
}
.fg-dot:hover .fg-dot-pip { background: rgba(255, 255, 255, 0.7); }
.fg-dot:focus-visible {
    outline: 2px solid var(--accent, #00d4aa);
    outline-offset: 2px;
    border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
    /* 150ms-Farb-Transitions neutralisieren (kein Flackern beim Fokus/Hover). */
    .ab-auswahl-btn,
    .fg-print-link,
    .fg-diff-toggle input,
    .fg-diff-toggle input::before,
    .fg-edge-fade,
    .fg-dot-pip { transition: none; }
    /* P9-Caret: die Transition liegt dashboard-gescopet (0,2,0) — hier gleiche
       Spezifitaet, sonst greift das Neutralisieren nicht. */
    .einszueins-dashboard .fg-gruppe-caret { transition: none; }
    /* Scroller: kein Smooth-Scroll, kein Snap (Snap = Bewegung). Erhoehte
       Spezifitaet (.einszueins-dashboard ...) schlaegt die mobile x-mandatory-Regel
       [Section 13] unabhaengig von der Quellreihenfolge. */
    .einszueins-dashboard .einszueins-scroller {
        scroll-behavior: auto;
        scroll-snap-type: none;
    }
}

/* ========================================================================== *
 * 13. MOBILE (<=600px, Phase 4) — vp-Spalte weg, Mini-Labels, Wisch-Indikator
 *     Ein Muster je Breakpoint (§8). Duell: 2 Spalten fitten (minmax 45vw + 1fr).
 *     Trio: 3x45vw > Viewport -> horizontaler Scroll-Snap (2 sichtbar + Peek);
 *     der Wisch-Indikator (Dots + Edge-Fade, Section 12) fuehrt zum naechsten Slot.
 * ========================================================================== */
@media (max-width: 600px) {
    /* Kriterienspalte weg; der 1. Grid-Track kollabiert (Scroller nur noch 1fr). */
    .einszueins-dashboard .vp-spalte { display: none; }
    .einszueins-scroller {
        grid-template-columns: minmax(0, 1fr);
        scroll-snap-type: x mandatory;
        /* max-height entfallen (2026-07-06): scrollt mit der Seite, wie Desktop. */
    }
    .einszueins-dashboard .tabelle-grid {
        grid-column: 1 / -1;
        grid-template-columns: repeat(var(--anzahl-anbieter, 1), minmax(45vw, 1fr));
    }
    .einszueins-dashboard .anbieter-spalte { scroll-snap-align: start; }

    /* Mini-Label je Datenzelle (data-label) — ersetzt die ausgeblendete
       Kriterienspalte. In JEDER Spalte, damit beim Wischen (2 von 3 sichtbar)
       das Label immer am Wert klebt (robuster als ein scroll-synchronisierter
       Einzelbanner; kein --mini-label-x-Transform-Sync noetig).
       .ab-zelle ist ein Flex-Container -> Spalten-Richtung erzwingen, damit das
       ::before-Label OBEN steht und der Wert darunter (Karten-Layout). */
    .einszueins-dashboard .ab-zelle[data-label] {
        display: flex;
        flex-direction: column;
        align-items: stretch;
    }
    .einszueins-dashboard .ab-merkmal-bool { align-items: flex-end; } /* Icon bleibt rechts */
    .einszueins-dashboard .ab-zelle[data-label]::before {
        content: attr(data-label);
        display: block;
        width: 100%;
        margin-bottom: 0.15em;
        font-size: 0.6rem;
        font-weight: 700;
        line-height: 1.2;
        text-transform: uppercase;
        letter-spacing: 0.03em;
        /* AA-Kontrast wie die Matrix-Legende (F7): 0.55 ~2,6:1 -> 0.92 ~4,9:1. */
        color: rgba(255, 255, 255, 0.92);
    }

    /* Leerzustand (Anwender-Entscheid 2026-09-12): In einer Skelett-Spalte
       (.fg-slot-leer, "oben im Feld den Anbieter waehlen") erscheinen die
       Kriterien-Labels erst, wenn dort ein Anbieter gewaehlt ist. Die 1. Spalte
       behaelt sie - sie vertritt mobil die ausgeblendete vp-Spalte. Trifft
       Daten- UND Gruppentitel-Zellen (beide tragen data-label); die Reihen-
       Baender bleiben, die Zeilenhoehe kommt per Subgrid aus Spalte 1. Der
       Server liefert die Zellen im Leerzustand ohne Leer-Marker, hier ist nur
       das ::before-Label zu unterdruecken. */
    .einszueins-dashboard .anbieter-spalte.fg-slot-leer:not(:first-child) .ab-zelle[data-label]::before {
        content: none;
    }
    /* Dieselbe Regel fuer die Betragsstufen-Legende der Zins-/Rendite-Matrix
       (Festgeld/Tagesgeld, .ab-matrix-titel ohne data-label): visibility statt
       display, damit die Zelle ihren Subgrid-Track behaelt. Desktop bleibt
       unveraendert (Geruest-Optik der Matrix, Anwender-Entscheid 2026-07-07). */
    .einszueins-dashboard .anbieter-spalte.fg-slot-leer:not(:first-child) .ab-zelle.ab-matrix-titel {
        visibility: hidden;
    }

    /* Phase 6.5/P9: Klapp-Button auf Mobile. Die vp-Spalte (mit dem Desktop-Button)
       ist hier ausgeblendet -> der Icon-Button im Gruppentitel-Spacer der 1. Spalte
       uebernimmt (JS). Der Spacer wird zum Akkordeon-Kopf: Titel-Mini-Label (::before)
       links, Chevron-Button rechts. Nur die 1. Spalte traegt den Button; Spalte 2/3
       zeigen weiter das reine ::before-Titel-Label (kein SR-Doppel-Control). */
    .einszueins-dashboard .ab-gruppe-spacer.fg-gruppe-has-btn {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
    .einszueins-dashboard .ab-gruppe-spacer.fg-gruppe-has-btn::before {
        width: auto;       /* neben dem Button statt 100% darueber */
        margin-bottom: 0;
    }
    /* Anwender-Entscheid 2026-07-06 (Politur-Runde 3 / AP5): Band-Label in Spalte 2/3
       vertikal zentrieren. Die Spacer erben aus der Paritaets-CSS justify-content:
       flex-end (Wert-unten-Ausrichtung der Datenzellen); da der Spacer nur das
       ::before-Titel-Label enthaelt (flex-direction:column via .ab-zelle[data-label]),
       klebte es an der Unterkante. center hebt es auf die Button-Hoehe der Spalte 1
       (.fg-gruppe-has-btn ist bereits zentriert). Nur Spalte 2/3 (ohne Klapp-Button). */
    .einszueins-dashboard .ab-gruppe-spacer:not(.fg-gruppe-has-btn) {
        justify-content: center;
    }
    .einszueins-dashboard .fg-gruppe-btn--mobile {
        display: inline-flex;
        flex: 0 0 auto;
        align-self: center;
        align-items: center;
        justify-content: center;
        width: auto;
        min-width: 44px;   /* Touch-Target WCAG 2.5.5 */
        min-height: 44px;
        margin: 0;
        padding: 0;
        background: transparent;
        border: 0;
        color: #d9f7ee; /* wie Titel-Farbe (Sektion 6) */
        cursor: pointer;
    }

    /* Wisch-Indikator (Dots + Edge-Fade) rein JS-gesteuert nach Scrollbreite —
       kein eigener Breakpoint noetig (siehe Section 12). */

    /* Druck-Icon: volles Touch-Target in der Spalten-Karte (>=44px). */
    .einszueins-dashboard .fg-print-link {
        min-width: 44px;
        min-height: 44px;
    }

    /* Touch-Targets >=44px fuer die auf Touch sichtbaren Controls (WCAG 2.5.5).
       Nativer Select: nur min-height (kein display-Wechsel — zentriert nativ).
       .fg-dot/.fg-print-link sind mobil bereits 44px (nicht doppeln);
       Combobox bleibt <=600px ausgeblendet -> keine 44px noetig. */
    .ab-auswahl-select { min-height: 44px; }
    .ab-auswahl-btn,
    .fg-diff-toggle.is-active {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    /* CT-0247: die 44px darueber sind ein Touch-Ziel, keine Einheitshoehe — sie
       ersetzen die Untergrenze aus Section 12 und liessen die beiden Hoehenklassen
       mobil zurueckkehren, sobald der Zweizeiler ueber 44px waechst (ab rund 18px
       Wurzelschrift). max() nimmt beides: nie unter dem Touch-Ziel, nie unter der
       Einheitshoehe. Der Wert steht weiterhin nur an einer Stelle (Section 12). */
    .fg-diff-toggle.is-active { min-height: max(44px, var(--fg-diff-toggle-hoehe)); }
}

/* Phase-6 VRT-Fix (axe color-contrast): Platzhalter "derzeit nicht im Angebot"
   im leeren Slot erbte rgba(255,255,255,.7) = 3,32:1 auf #0070c0 (< AA 4,5:1).
   #ebf4fa = 4,61:1, live per axe bestaetigt. Attribut-/farb-only, kein Layout. */
.einszueins-dashboard .ab-logo-leer { color: #ebf4fa; }

/* ========================================================================== *
 * 13b. MITTLERER BREAKPOINT (601px–47em) — 2 Spalten + Peek, Wischen statt 3-Spalten
 *   Oberhalb passen 3 Spalten nebeneinander (Default-Mechanik --anzahl-anbieter,
 *   minmax(11em,1fr), unangetastet). Hier passen nur 2 sauber, die 3. wird per
 *   Wischen erreicht (bestehende Snap-Mechanik) und lugt ~1em herein (Affordance).
 *
 *   Herleitung der Obergrenze 47em: der Default zeigt 3 Spalten ueberlaufsfrei erst,
 *   wenn 3x11em (col-min) + 13em (--e1-vp-breite) = 46em Scroller-Inhalt passen; das
 *   Dashboard hat margin:0 1% (vergleich.min.css) -> ~46em/0.98 ≈ 47em Viewport.
 *   Darunter -> dieser 2+Peek-Modus. Der 601px-Boden koppelt an MOBILE_MAX (JS/CSS,
 *   NICHT verschieben); darunter greift die Mobile-Mechanik (Section 13, vp weg).
 *
 *   Spaltenbreite = (100% − 1em)/2: 2 Spalten fuellen die Grid-Breite exakt, 1em
 *   bleibt als Peek der 3. Spalte. minmax(...,1fr) laesst bei nur 2 Produkten beide
 *   voll fuellen (kein Peek, kein Overflow -> Indikator bleibt aus). 100% = Breite
 *   der .tabelle-grid (Scroller-Track 2, also schon OHNE die vp-Spalte) -> robust
 *   gegen die vp-Verschmaelerung auf 8.5em im 601-640px-Fenster (Section 10).
 * ========================================================================== */
@media (min-width: 601px) and (max-width: 47em) {
    /* Snap niedrig-spezifisch (0,1,0) — der reduced-motion-Block [Section 12,
       .einszueins-dashboard .einszueins-scroller = 0,2,0] schlaegt ihn dann
       unabhaengig von der Quellreihenfolge (gleiche Logik wie die Mobile-Regel). */
    .einszueins-scroller {
        scroll-snap-type: x proximity;
        scroll-padding-left: var(--e1-vp-breite, 13em); /* Snap raeumt die sticky vp-Spalte frei */
    }
    .einszueins-dashboard .tabelle-grid {
        grid-template-columns: repeat(var(--anzahl-anbieter, 1), minmax(calc((100% - 1em) / 2), 1fr));
    }
    .einszueins-dashboard .anbieter-spalte { scroll-snap-align: start; }
}

/* ========================================================================== *
 * 14. PHASE 6.5 / D3 — Positionsabhaengige Spaltenfaerbung (Alt-Tool-Anmutung)
 *     Anbieter-Position 1 + 3 dunkelblau #0061A6 (Alt-Tool .spalte), Position 2
 *     ohne Hinterlegung (Seiten-Grund scheint durch) — bewusster Design-
 *     Pivot, die Schwester-Tabelle faerbt NICHT positionsabhaengig.
 *     Anwender-Entscheid 2026-07-06: die Tinte gilt nur noch fuer die PRODUKT-
 *     DATEN — die Kopfzeilen (Logo "Anbieter" + Inland/Ausland-Badge) stehen in
 *     allen Positionen im Seiten-Grundton (Section 4/11, deckend wegen sticky)
 *     und decken die Spalten-Tinte hinter sich ab, damit das Banklogo nie
 *     umrahmt wirkt.
 *     nth-child-Zaehlung: .vp-spalte ist KEIN Kind von .tabelle-grid (sie ist
 *     dessen Geschwister im Scroller, core Z.688/693) -> nth-child(N) ==
 *     Anbieter-Position N. Gilt fuer 1-3 Slots (Pos.1 blau auch im Duell/Solo)
 *     und mobil (Wisch-Orientierung).
 *     Kontraste auf #0061A6 (dunkler als Seiten-Grund #0070C0 -> heller Text
 *     gewinnt ueberall): #fff ~6,5:1, #F1F6FC ~6,0:1, Gewinner-Teal-Mix
 *     rgba(0,110,92,.5) + weisser Matrix-Text ~6,4:1 — Ton bleibt (D3-Regel). */
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 4 / AP1b): die Positions-Tinte liegt
   jetzt auf den ZELLEN (background-color — bewusst KEIN Shorthand, damit Band-/Overlay-
   background-images kompositionsfaehig bleiben), NICHT mehr auf dem .anbieter-spalte-
   Container. So werden Logo/Badge/Druck echt SEITENTRANSPARENT (Container transparent
   -> Seiten-Verlauf scheint durch, auch unterhalb des Plateaus ~#0066AE), waehrend
   Daten/Baender/CTA/Skelett die Tinte behalten. nth-child(1/3) = Anbieter-Position 1/3
   (vp-Spalte ist kein Kind von .tabelle-grid). Kontraste auf #0061A6: #fff ~6,5:1,
   Gewinner-Teal-Mix ~6,4:1 (unveraendert). */
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(1) > .ab-zelle,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(3) > .ab-zelle {
    background-color: #0061A6;
}
/* Anwender-Entscheid 2026-07-06 (Politur-Runde 5 / AP2): die in Runde 4 ergaenzte
   Skelett-CONTAINER-Tinte ist ENTFALLEN. Sie lag hinter den (desktop) transparenten
   Ghost-Logo/-Badge/-Druck-Zellen und liess deshalb die "Anbieter"-Zeile leerer Slot-
   Spalten in Pos.1+3 dunkelblau erscheinen. Ohne sie greift die >=601px-Ausnahme-
   Regel (Logo/Badge/Druck transparent) auch fuer fg-slot-leer -> diese Zeilen sind
   jetzt echt seitentransparent (Seiten-Verlauf, konsistent zu AP1b/den echten Spalten).
   Die Ghost-DATENzellen tragen weiter die Zell-Tinte (#0061A6, > .ab-zelle) bei
   0.5-Opacity (Section 15) -> faint/halb -> der Skelett-Look (ghosthaft) bleibt, die
   Zellen wirken lediglich etwas leichter als mit der frueheren Voll-Container-Tinte
   (risikoaermste Variante: nur eine Regel entfernt, keine Opacity-/Inhalts-Umbauten). */
/* Anwender-Entscheid 2026-07-07: die Ausnahme (Logo/Badge/Druck transparent) gilt jetzt
   auf ALLEN Breiten — der fruehere <601px-Scope (Mobile-Karte durchgaengig getintet)
   ist entfallen; auch mobil scheinen Anbieter-/Badge-/Druck-Zeile seitentransparent
   durch, identisch zum Tabellen-Layout. */
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(1) > .ab-zelle.ab-logo,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(1) > .ab-zelle.ab-badge,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(1) > .ab-zelle.ab-print,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(3) > .ab-zelle.ab-logo,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(3) > .ab-zelle.ab-badge,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(3) > .ab-zelle.ab-print {
    background-color: transparent;
}

/* BR5 (Brokerage): Gewinner-Highlight auf GANZEN Order-Merkmal-Zellen (Klasse
   vergibt der BR-Core; niedrigster Order{N}_int ueber die aktiven Spalten).
   BEWUSST HIER (nach den Positions-Tinten) und NICHT bei der Matrix-Regel
   (Section ~11): bei gleicher Spezifitaet (0,5,0) entscheidet die Reihenfolge —
   stuende die Regel frueher, schluckte die nth-child(1/3)-Zell-Tinte (#0061A6,
   direkt oben) den Tint in Pos. 1+3 (Review-Befund BR-1). background-COLOR,
   kein Shorthand (AP1b-Vertrag: Overlays wie die .fg-row-hover-Leselinie sind
   background-images und muessen kompositionsfaehig bleiben — Order-Zeilen tragen
   data-row, anders als die Matrix-Zeilen!). Nicht rein farb-codiert: die Zelle
   traegt serverseitig ein .fg-sr-only "(guenstigster Preis)".
   Tint = derselbe Wert wie die Matrix-Gewinner-Regel rgba(76,181,160,0.28) —
   BEIDE STELLEN SYNCHRON AENDERN (offener AA-Punkt dort gilt auch hier):
   Pos. 2 komposittiert live ueber dem Panel-Verlauf (translucent), Pos. 1+3
   brauchen den VORAB komposittierten Opak-Wert ueber #0061A6 = rgb(21,121,164)
   (0.28*76+0.72*0 / 0.28*181+0.72*97 / 0.28*160+0.72*166), weil background-color
   die Zell-Tinte ERSETZT statt darueber zu liegen. */
.einszueins-dashboard .tabelle-grid > .anbieter-spalte > .ab-zelle.ab-mz--top {
    background-color: rgba(76, 181, 160, 0.28);
}
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(1) > .ab-zelle.ab-mz--top,
.einszueins-dashboard .tabelle-grid > .anbieter-spalte:nth-child(3) > .ab-zelle.ab-mz--top {
    background-color: rgb(21, 121, 164);
}

/* ========================================================================== *
 * 15. PHASE 6.5 / D1+P2 — Empty-State: Ghost-Geruest der Pseudo-Slots
 *     .fg-slot-leer = Skelett-Spalte des immer sichtbaren Vergleichsgeruests
 *     (Core rendert sie bei 0/1 Auswahl; das JS zaehlt sie nicht als Slot).
 *     Kein Shimmer (prefers-reduced-motion), Ghost-Text #ebf4fa >=4,5:1 auf
 *     #0070C0 (belegt, Section-14-Grund #0061A6 ist dunkler -> noch besser).
 * ========================================================================== */
/* Gestrichelter Innenrahmen als outline (FLIP-/Subgrid-sicher: keine Box-
   Groessenaenderung wie bei border) + Radius. */
.einszueins-dashboard .anbieter-spalte.fg-slot-leer {
    outline: 1px dashed rgba(255, 255, 255, 0.28);
    outline-offset: -5px;
    border-radius: 0.5em;
}
/* Reveal-Reserve: dritte Skelett-Spalte, vom Core hidden MIT-gerendert, solange
   kein echter dritter Slot existiert; das JS (syncReserveSpalte) blendet sie
   beim Zuschalten des dritten Feldes ein. Explizite display:none-Regel noetig:
   die display-Setzung der .anbieter-spalte (Author-Style, tabelle.min.css)
   schluege das blosse UA-[hidden]. */
.einszueins-dashboard .tabelle-grid > .anbieter-spalte.fg-slot-reserve[hidden] {
    display: none;
}
/* Datenzellen ghosten. Kopfzellen (Logo/Badge) AUSGENOMMEN: sie sind sticky
   (Section 11) — opacity < 1 liesse beim V-Scroll Zeilen durchscheinen; die
   Logo-Zelle traegt zudem den vollkraeftigen Einladungs-Text. */
.einszueins-dashboard .fg-slot-leer .ab-zelle:not(.ab-logo):not(.ab-badge) {
    opacity: 0.5;
}
/* "+ Anbieter waehlen" (statt "derzeit nicht im Angebot" der echten Leer-Slots). */
.einszueins-dashboard .fg-slot-leer .ab-zelle.fg-slot-cta {
    justify-content: center;
    align-items: center;
    text-align: center;
    font-size: 0.95rem;
    font-weight: 600;
}

/* (Der fruehere Leerzustand-Hinweis unter dem Geruest ist 2026-07-06
   ersatzlos entfallen — Anwender-Entscheid.) */

/* ========================================================================== *
 * 16. PHASE 6.5 / P1 — Hover-/Fokus-Leselinie ueber die ganze Merkmal-Zeile
 *     (Alt-Tool-Paritaet: das Auge verfolgt einen Wert ueber 2-3 Spalten). Das
 *     JS setzt .fg-row-hover auf alle Zellen gleicher data-row; NUR die Kriterien-
 *     Merkmal-Reihen tragen ein data-row (Core P1) -> Kopf-/Titel-/Zins-Matrix-/
 *     CTA-Reihen sind ausgenommen (die Leselinie ueberdeckt sonst das Gewinner-
 *     Teal der Zins-Zeilen). Reine Hintergrund-Aenderung, KEINE Transition
 *     (FLIP-/Subgrid-sicher, kein Konflikt mit den --e1-rows-Track-Wechseln des
 *     Diff-Toggle -> prefers-reduced-motion unkritisch).
 *     AP1b (Politur-Runde 4): der Schleier ist jetzt ein IMAGE-Layer (linear-gradient)
 *     statt background-color. Seit die D3-Positions-Tinte auf den ZELLEN sitzt
 *     (background-color, Section 14) statt auf dem .anbieter-spalte-Container, laege
 *     ein background-color-Schleier auf DERSELBEN Zelle wie die Tinte -> die
 *     hoeher-spezifische Tinte schluege ihn. Als background-image kompositioniert er
 *     wieder ueber der Zell-Tinte (Pos.1/3 #0061A6) bzw. dem Verlaufs-/Panel-Grund
 *     (Pos.2 / vp-Spalte, D6), ohne Spezifitaets-Kampf. */
.einszueins-dashboard .fg-row-hover {
    background-image: linear-gradient(rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.06));
}

/* ========================================================================== *
 * 17. PHASE POLITUR-RUNDE 2 (Anwender-Entscheid 2026-07-06) — Desktop-Feinschliff
 *     Alles hier im Desktop-Breakpoint (min-width:72.0625em): dort gibt es KEINEN
 *     horizontalen Ueberlauf (3 Spalten + vp-Spur passen 1fr-basiert), position:
 *     sticky ist also inert. BEWUSST am Dateiende, damit diese Regeln die Basis-
 *     Deklarationen in Section 2b/3/4/11/14 per Quellreihenfolge schlagen (gleiche
 *     Spezifitaet, kein MQ-Bonus) — insbesondere die AP2-Track-Breite muss NACH
 *     der unbedingten 13em-Basis (Section 3) stehen.
 * ========================================================================== */
@media (min-width: 72.0625em) {
    /* AP2 — 1/6-Breite an die Kriterien-Spalte verdrahten: hier gewinnt der calc
       ueber die 13em-Basis (Section 3), sodass die vp-Spur des Dashboard-Grids
       (Scroller-Track 1 = var(--e1-vp-breite)) buendig mit dem ersten Nav-Feld
       (Girokonto, 1/6 der Seitenbreite) abschliesst. Herleitung der Prozentkette
       s. Section 2b. Das Formular-Grid nutzt denselben calc direkt (Section 2b). */
    .einszueins-dashboard {
        --e1-vp-breite: calc((100% / 6 - 1.88%) / 0.9604);
    }

    /* AP1 — Kriterien-Spalte OHNE Panel-Look: der Seiten-Verlauf soll durch die
       vp-Spalte scheinen. Da sticky-left hier inert ist (kein H-Scroll), ist
       transparent gefahrlos. border/radius/shadow (Panel-Anmutung) entfallen. */
    .einszueins-dashboard .vp-spalte {
        background: transparent;
        border-right: 0;
        border-radius: 0;
        box-shadow: none;
    }
    /* AP1 — Kriterien-Kopf ("Anbieter"/"Einlagenherkunft") transparent: auf der nun
       durchscheinenden vp-Spalte erfuellt transparent das "ohne Hinterlegung". Sitzt
       im sticky-left vp-Container, daher desktop-only (unterhalb 72em ist die vp-Spalte
       display:none, Section 13 — kein Effekt). Die Logo-/Badge-Zellen sind seit
       Politur-Runde 3 UNBEDINGT transparent (Section 4/11, nie sticky-left) und darum
       hier NICHT mehr gelistet. */
    .einszueins-dashboard .vp-zelle.vp-header {
        background: transparent;
    }

    /* AP1-Sicherheitsnetz — nur falls im Desktop doch H-Scroll auftraete (setzt das
       Wisch-Modul .has-overflow auf die .fg-scroll-shell): dann klebt die vp-Spalte
       sticky-left ueber gescrollten Datenspalten und MUSS wieder decken. Hoehere
       Spezifitaet (0,3,0) als die transparent-Regel (0,2,0) -> gewinnt bei Overflow.
       Im Normalfall (kein Overflow) inaktiv. */
    .fg-scroll-shell.has-overflow .vp-spalte {
        background: #0070C0;
        border-right: 1px solid rgba(255, 255, 255, 0.18);
        box-shadow: 0.25em 0 0.5em rgba(0, 0, 0, 0.2);
    }
}

/* ========================================================================== *
 * === Tagesgeld: Rendite-Doppelzelle (TG-1) ===
 *
 * Overrides ans DATEIENDE (Kaskaden-Lehre: keine Bestandsbloecke umschreiben,
 * spaetere Regel gleicher/hoeherer Spezifitaet gewinnt). Die Rendite-Sektion
 * „Jahresrenditen" nutzt die Festgeld-Matrix-Klassen (.ab-zins-matrix, .ab-mz,
 * .ab-mz--top, .ab-matrix-zeile/-titel/-legende) und schaltet ueber die
 * Zusatzklasse .ab-rendite von der Festgeld-3-Spalten-Matrix auf ZWEI Spalten
 * (Standard | mit Sonderzins). Festgeld bindet weiter seine eigene CSS — an
 * 1-zu-1-festgeld.min.css wurde NICHTS geaendert.
 * ========================================================================== */

/* Zwei Spalten statt der Festgeld-3 (Basis .einszueins-dashboard .ab-zins-matrix
   = 0,2,0; dieser Selektor 0,3,0 -> gewinnt). Gilt fuer Werte-Reihen UND die
   Modus-Legende (beide tragen .ab-rendite). */
.einszueins-dashboard .ab-zins-matrix.ab-rendite {
    grid-template-columns: repeat(2, 1fr);
}

/* Teilwert-Span der Rendite-Zelle: Prozentwert oben, EUR-Ertrag als eigene
   Zeile darunter -> Spalten-Flex (die Festgeld-Basisregel .ab-matrix-zeile
   .ab-zins-matrix > span setzt row/center/flex-end; hier 0,5,1 -> gewinnt).
   Rechtsbuendig wie die Festgeld-Zins-Zahl. */
.einszueins-dashboard .ab-matrix-zeile .ab-zins-matrix.ab-rendite > span.ab-mz {
    flex-direction: column;
    justify-content: center;
    align-items: flex-end;
    text-align: right;
}

/* (TG-2: Die fruehere .ab-mz--solo-Regel — kollabierter Solo-Teilwert bei
   Rendite{K} == Rendite_s{K} — ist ENTFERNT. Anwender-Entscheid 2026-07-09:
   die Spalte "mit Sonderzins" zeigt bei fehlendem abweichendem Sonderzins den
   Standardwert; der Core rendert immer beide Teilwerte, 'solo' entsteht nicht
   mehr im Markup.) */

/* EUR-Ertrag: kleinere, gedaempfte Schrift in eigener Zeile UNTER dem Prozent-
   wert. Tint-neutral — erbt den Zell-/Gewinner-Hintergrund und legt KEINEN
   eigenen Hintergrund (Festgeld-Lehre: Overlays nur als background-image-Layer,
   nie als deckende background-color, sonst schlaegt eine Zell-Tinte durch bzw.
   wird durchschlagen). Nur Text, keine Flaeche. */
.einszueins-dashboard .ab-mz-eur {
    display: block;
    margin-top: 0.1em;
    font-size: 0.72em;   /* relativ zum Prozentwert (~0.85rem) */
    font-weight: 400;
    line-height: 1.2;
    /* rgba(255,255,255,0.92) = der AA-erprobte Wert der Matrix-Legende (dort
       wurde 0.55 aus genau diesem Grund auf 0.92 angehoben) — 0.8 auf den
       blauen Zell-Tinten laege unter AA 4.5:1 (Review-Befund TG-1 / E20). */
    color: rgba(255, 255, 255, 0.92);
    background: none;
}

/* Ausblenden des EUR-Ertrags bei TRIO (3 Spalten) — der EUR-Wert bleibt nur im
   Duell/Solo (2 Spalten, Desktop) sichtbar. Trio-Hook = server-gesetzte Klasse
   fg-slots-3 am Scroller (Core setzt sie bei --anzahl-anbieter:3; Review-Befund
   TG-1: ein frueherer :has()-Ansatz zaehlte eine angefragte, aber geparkte/
   unbekannte dritte IDS falsch — massgeblich ist die SPALTENZAHL, denn auch
   eine "derzeit nicht im Angebot"-Spalte macht alle Spalten schmal).
   TG-2-Hinweis: das Familien-JS schaltet fg-slots-3 beim Reserve-Reveal
   zusammen mit --anzahl-anbieter um.
   Das Markup gibt den EUR-Wert IMMER aus — nur die CSS steuert die Sichtbarkeit. */
.einszueins-dashboard .einszueins-scroller.fg-slots-3 .ab-mz-eur {
    display: none;
}

/* Ausblenden des EUR-Ertrags im Mobile-Kartenlayout (vorhandener MOBILE_MAX-
   Breakpoint 600px, Section 13): dort ist der Platz je Spalte (~45vw) zu knapp
   fuer die zweite Zeile — der Prozentwert genuegt. */
@media (max-width: 600px) {
    .einszueins-dashboard .ab-mz-eur {
        display: none;
    }
}

/* ========================================================================== *
 * === Tagesgeld: Chart-Icon-Link im 'gueltig'-Feld (TG-2, Anwender-Befund) ===
 *
 * Das DB-Feld 'gueltig' ("Standardzins gilt seit") traegt einen
 * <br><a class="iframe">-Link mit .icon-chart-area (Zinsentwicklungs-Chart im
 * Fancybox-Overlay). Die globale `.icon-chart-area` aus style.css/
 * vergleich.min.css setzt font-size:2.8em + margin-left:-1.8em (gedacht fuer
 * die <table>-Detail-Tabs) — ohne Neutralisierung verrutscht das Icon nach
 * links unter den Datumstext und die Klickflaeche liegt daneben (Anwender-
 * Befund 2026-07-09: "verrutscht, nicht klickbar"). Die Regeln spiegeln die
 * Tabellen-Schwester (tagesgeld-tabelle-core, Politur 2026-05-13/06-02/06-12)
 * im .ab-merkmal-html-Scope des 1:1-Tools; .einszueins-dashboard-Prefix als
 * Scope-Hygiene (hebt alle Paare gleichmaessig um eine Klasse). */
.einszueins-dashboard .ab-merkmal-html .icon-chart-area {
    position: relative;
    font-size: 2.8em;
    margin: 0;
    line-height: 1;
    color: var(--mint-200);
    vertical-align: middle;
}
/* Zustandsfarben wie Liste/Tabelle: focus/active/visited bleiben auf der
   Grundfarbe, NUR hover hebt mit dem Hover-Ton der Akzentfamilie hervor
   (Site-Default `a:focus>.icon, a:hover>.icon { color:#d7f71e }` wuerde das
   Glyph sonst gelb-gruen faerben, sobald der Link nach Klick fokussiert bleibt). */
.einszueins-dashboard .ab-merkmal-html .iframe .icon-chart-area {
    color: var(--mint-200);
}
.einszueins-dashboard .ab-merkmal-html a:hover > .icon-chart-area {
    color: var(--mint-100);
}
/* Site-Default `a:hover { background:#6699CC; padding:1px 0 }` faerbt sonst den
   Bereich hinter Chart-Icon-/Geschenk-Link hellblau — Neutralisierung wie in
   Liste (.merkmal-wert a:hover) und Tabelle (.ab-merkmal-html a:hover). */
.einszueins-dashboard .ab-merkmal-html a:hover,
.einszueins-dashboard .ab-merkmal-html a:focus,
.einszueins-dashboard .ab-merkmal-html a:visited {
    background: none;
    padding: 0;
}
/* === Erfahrungsberichte-Icon (icon-chat-empty) im 'Erfahrungsberichte'-Feld ===
 * Gleiche Glyph-Familie wie das Chart-Icon: die globale `.icon`/`.icon-chat-empty`
 * aus style.css setzt position:absolute + margin-left:-1.6em (gedacht fuer die
 * <table>-Detail-Tabs) — im 1:1-Tool sitzt das Icon dadurch absolut positioniert
 * und rutscht unter den Link-Text (Anwender-Befund 2026-07-13: "nach unten
 * verrutscht"). Analog zur Chart-Icon-Regel neutralisiert (position/margin/
 * vertical-align, Groesse wie Chart-Icon 2.8em). Farbe bleibt die globale
 * var(--mint-200) — nun identisch zum Chart-Icon. Betrifft die vier DE-Tools mit
 * Erfahrungsberichte-Zeile: Girokonto, Tagesgeld, Brokerage, Kreditkarte. */
.einszueins-dashboard .ab-merkmal-html .icon-chat-empty {
    position: relative;
    font-size: 2.8em;
    margin: 0;
    line-height: 1;
    vertical-align: middle;
}
/* Geschenk-Icon (Bonus-Reihe): im 1:1-Tool die Mint-Variante cardgift-m.svg
   (#1FD99B = mint-500, vormals auch Chart-Icon-Grundfarbe; Chart-Icon nun
   var(--mint-200) angeglichen, das cardgift-m.svg bleibt bewusst mint-500-
   basiert. Core ersetzt cardgift.svg->-m,
   Anwender-Entscheid 2026-07-09 — Liste/Tabelle behalten cardgift-g.svg +
   brightness(1.4) saturate(1.5)). Hover-Filter auf die Chart-Hover-Farbe
   #8FF6D5 gerechnet: saturate(0.41) brightness(1.29) auf #1FD99B ~= #93F6D5.
   Groesse wie die Schwestern (2.97em; Site-Default wuerde 2.7em rendern). */
.einszueins-dashboard .ab-merkmal-html a.cardgifta:hover img {
    filter: saturate(0.41) brightness(1.29);
}
.einszueins-dashboard .ab-merkmal-html a.cardgifta img {
    width: 2.97em;
}

/* ========================================================================== *
 * === Familie: FOUC-Schutz Auswahl-Formular (TG-2, Anwender-Befund Festgeld) ===
 *
 * Das Enhancement (.fg-enhanced) greift erst nach DOMContentLoaded (Skript am
 * Body-Ende) — bis dahin blitzten der Akzent-Button "Vergleich anzeigen" und
 * (Desktop) die native Select-Reihe auf. Ein Inline-Snippet im <head> setzt
 * html.fg-js VOR dem ersten Paint; diese Regeln verstecken beides sofort.
 * Sicherheitsnetze: init()-Fehlpfade + onerror am <script>-Tag + DCL-Check im
 * Entry-Snippet entfernen die Klasse -> Baseline tritt wieder hervor.
 * NUR Desktop (>600px): mobil bleibt der Button bis .fg-enhanced sichtbar —
 * dort ist die native Reihe der aktive Auswahl-Weg, und der Auto-Submit-
 * Listener (AP4c) bindet erst mit dem Body-Ende-Skript; ein vorab versteckter
 * Button risse auf langsamen Verbindungen ein Bedien-Totfenster auf (Review
 * TG-2, CONFIRMED). Der beanstandete Blitzer war der Desktop-Fall.
 * Select-Reihe: visibility statt display — die Reihe haelt ihren Platz, bis
 * die Combobox sie ersetzt (kein Layout-Sprung). */
@media (min-width: 601px) {
    html.fg-js .ab-auswahl-btn {
        display: none;
    }
    html.fg-js .ab-auswahl:not(.fg-enhanced) .ab-auswahl-reihe {
        visibility: hidden;
    }
}

/* Absatzwechsel innerhalb einer Fussnote (Rollout 2026-08-11, Nachtrag H1).
   cleanZusatzinfos() macht aus <p>...</p><p>...</p> ein <br><br> — eine volle
   Leerzeile, die weiter wirkt als der Abstand zwischen zwei Anbieter-Eintraegen
   (.tabelle-fussnoten li margin-bottom 0.65em = 8,84 px). Der Renderer in
   1-zu-1-vergleich-core.inc.php ersetzt das durch diesen Abstandshalter; 0.35em
   ergibt gemessene 4,75 px und bleibt klar darunter. Herkunft der Messreihe:
   Coden\Tabellendarstellung\Festgeld DE\fussnoten-absatzabstand-rollout-uebergabe.md */
.tabelle-fussnoten .fn-absatz { display: block; height: 0.35em; }

/* Fussnoten auf Mobile: dieselbe Ruecknahme wie in den Tabellenansichten
   (Rollout 2026-08-11, Anwender-Entscheid "Nachzuegler mitnehmen").
   tabelle.min.css setzt .tabelle-fussnoten auf font-size 0.85rem /
   padding 1em 1.5em; unterhalb 38em gilt 0.8rem / 0.875em 1em — gemessen
   12,8 px Schrift statt 13,6 px, Innenabstand 11,2/12,8 statt 13,6/20,4 px.
   Diese Datei wird NACH tabelle.min.css geladen (geprueft in
   1-zu-1-girokonto.php: Z. 88 vs. 89), die Regel gewinnt also bei gleicher
   Spezifitaet — kein !important, kein Spezifitaets-Trick noetig. */
@media (max-width: 38em) {
    .tabelle-fussnoten {
        padding: 0.875em 1em;
        font-size: 0.8rem;
    }
}
