
    /* === Tabellenansicht: spezifische Styles === */
    /* Filter-Section-Styles aus der Listenansicht spiegeln
       (Quelle: ..\..\Listendarstellung\Tagesgeld AT\tagesgeld-vergleich.css;
       Anpassen-Overlay etc.) */
    /* 50.01em statt 50em (Audit A-7.2 / Phase K6, Rollout Tagesgeld CT-0148 2026-08-26):
       zusammen mit dem `max-width: 50em`-Block darunter traf exakt 800px BEIDE Bloecke.
       Der Offset sitzt bewusst auf der min-width-Seite, damit 800px zur schmalen
       Variante gehoert; folgt dem Bestands-Vorbild `min-width: 72.01em`. `.01em` statt
       `.0625em`, weil letzteres exakt 801px waere und eine volle Pixel-Breite
       unversorgt liesse. Der `max-width: 50em`-Block bleibt unveraendert. */
    @media (min-width: 50.01em) {
        .filter-row-separator[style] .filter-column-separator { border-top: none; padding-top: 0; margin-top: 0; border-left: 1px solid var(--border); padding-left: var(--space-lg); margin-left: var(--space-md); }
    }
    @media (max-width: 50em) {
        .filter-row-separator[style] { grid-template-columns: 1fr !important; }
    }
    .filter-checkbox {
        display: flex; align-items: center; gap: 0.5em;
        padding: 0.375em 0; min-height: 2.25rem;
        cursor: pointer; font-size: 0.85rem;
        color: var(--text-secondary, #aab);
        transition: color 150ms ease; line-height: 1.35;
    }
    .filter-checkbox:hover { color: var(--text-primary, #fff); }
    .filter-checkbox input[type="checkbox"] {
        width: 1.25rem; height: 1.25rem; min-width: 1.25rem;
        accent-color: #00528d; cursor: pointer;
    }
    .filter-checkbox input[type="checkbox"]:checked + span {
        color: var(--text-primary, #fff); font-weight: 600;
    }
    @media (max-width: 48em) {
        /* Politur 2026-06-11d: EINZEILIGER Header auf Mobile. Der
           Treffer-Zaehler ("X Treffer · Anlagebetrag Y") ist ausgeblendet —
           Anwender-Entscheidung: Treffer-Anzahl steckt bereits im Pager
           ("von N"), der gewaehlte Anlagebetrag in den Einstellungen.
           display:none entfernt nur die Darstellung; die Trefferzahl
           bleibt fuer Crawler im separaten meta-Element daneben erhalten
           (K7 2026-08-13 - der sichtbare Zaehler traegt die Auszeichnung
           seitdem nicht mehr).
           Zeile: Pager links (kompakt — Skala-Track ausgeblendet, Platz
           reicht neben den Sort-Buttons nicht; Chevron-Paar bleibt) +
           `.sort-buttons` rechts (margin-left: auto). Site-CSS-Default
           (`flex-direction: column; align-items: stretch`) wird mit
           `row` + `flex-wrap: wrap` ueberschrieben — Spezifizitaet
           `.vergleich-dashboard.tabelle-dashboard .results-header`
           (0,3,0) schlaegt das Site-Default sauber. */
        .vergleich-dashboard.tabelle-dashboard .results-header {
            flex-direction: row;
            flex-wrap: wrap;
            align-items: center;
            row-gap: 0.4em;
        }
        .vergleich-dashboard.tabelle-dashboard .result-count {
            display: none;
        }
        .vergleich-dashboard.tabelle-dashboard .sort-buttons {
            align-self: center;
            margin-left: auto;
            /* 11h: 2.5%-Desktop-Randabstand auf Mobile opfern —
               jeder Pixel zaehlt fuer den Einzeiler. */
            margin-right: 0;
            /* Politur 2026-06-01b: das laengere Sonderzins-Sortier-Wording
               ("Jahresrendite bei beruecksichtigtem Sonderzins absteigend")
               sprengte bei 375px den Viewport (~46px Overflow), weil die Pille
               einzeilig blieb und .sort-buttons (global flex-shrink: 0) nicht
               nachgab. min-width:0 + flex-shrink:1 loesen die Sperre, der
               Button-Text bricht via white-space:normal um statt zu ueberlaufen
               — analog zum Listen-Verhalten (dort column+stretch). */
            min-width: 0;
            flex-shrink: 1;
        }
        .vergleich-dashboard.tabelle-dashboard .sort-btn {
            white-space: normal;
            min-width: 0;
            font-size: 0.75rem; /* Touch-Groesse bis 48em (Cross-View 2026-06-26b), vorher nur <=38em */
        }
        .vergleich-dashboard.tabelle-dashboard .tabelle-pager {
            flex: 0 1 auto;
            margin-inline: 0;
        }
        .tabelle-pager-track { display: none; }
        .tabelle-pager-leiste { flex: 0 0 auto; gap: 0; }
        /* 11h: Kurz-Range "X–Y / N" — "Anbieter" und "von" ausgeblendet,
           Slash an. Pfeil-Flaechen schmaler (2.25em breit, Hoehe 3em
           bleibt als Touch-Ziel), Glyph entsprechend kompakter, Gap enger. */
        .tabelle-pager { gap: 0.5em; }
        .tabelle-pager-prefix,
        .tabelle-pager-von-wort { display: none; }
        .tabelle-pager-slash { display: inline; }
        .tabelle-pager-btn { width: 2.25em; height: 3em; }
        .tabelle-pager-glyph { width: 2em; height: 0.7em; }
    }
    /* Sort-Button-Touchgroesse (Cross-View 2026-06-26b): 0.75rem (12px) statt
       var(--text-xs) (11px) ist jetzt in den 48em-Header-Block oben gewandert
       (zusammen mit white-space:normal + min-width:0) — gilt also bis 48em statt
       nur <=38em (Anwender-Entscheidung 2026-06-26: Touch-Pille bis zur kompakten
       Header-Grenze 768px ausdehnen). Auf engen Phones weiterhin Touch-Zweizeiler,
       auf Tablets bis 768px groessere Touch-Flaeche. Haelt Liste<->Tabelle und
       AT<->DE synchron; die AT-Listenansicht fuehrt die Pille im eigenen
       48em-Block ihrer tagesgeld-vergleich.css.
       Einheit `rem` von der Referenz-View (Liste). */
    /* Anlagebetrag-Pills: Layout-Overrides nur unter 52em (Tablet/Mobile-
       Scroll-Strip mit Snap, Masken-Fade, Drag-to-scroll). Auf Desktop
       (>52em) bleibt die Pille auf shared CSS aus `vergleich.min.css`
       (10px/8px-Padding) — sonst entstehen schmalere Pills als in der
       Listenansicht und ein sichtbarer Sprung beim View-Wechsel.
       Schwester-konsistent zum 52em-Block in
       ..\..\Listendarstellung\Tagesgeld AT\tagesgeld-vergleich.css
       (.laufzeit-nav, Politur 2026-05-16d). */
    @media (max-width: 52em) {
        .vergleich-dashboard .laufzeit-nav {
            flex-wrap: nowrap; overflow-x: auto;
            -webkit-overflow-scrolling: touch; scrollbar-width: none;
            scroll-snap-type: x mandatory;
            /* Fallback-Deklaration zuerst (Audit A-7.1 / Nachzug 2026-08-20, Muster aus
               festgeld-tabelle.css): Engines ohne das `safe`-Keyword (WebKit/Safari,
               Chrome < 115) verwerfen die naechste Deklaration komplett. Ohne diese Zeile
               greift dort das zentrale `center` aus vergleich.min.css — bei Overflow werden
               die linken Elemente dann unerreichbar, weil scrollLeft nicht negativ werden
               kann. In Chromium aendert die Zeile nichts: dort gewinnt weiterhin das
               gueltige `safe center` danach. Gehoert mit den Auto-Margins unten zusammen. */
            justify-content: flex-start;
            justify-content: safe center; gap: 0.25em;
            /* Strip-Metrik 1:1 aus tagesgeld-vergleich-core.inc.php uebernommen
               (Cross-View-Nachzug K1-Nachlese, 2026-08-21 — Tagesgeld war das letzte
               Produktpaar ohne diesen Nachzug). `padding` ersetzt das geerbte
               `var(--space-sm)` = 8px aus vergleich.min.css: erst dadurch hat das
               Anlagebetrag-Band im Tablet-Fenster dieselbe Hoehe wie in der Liste
               (~49px statt 59px); unterhalb 48em ersetzt es die dortigen 3px durch den
               gleichwertigen em-Wert. width/max-width geben volle Breite, damit der
               Glasmorphismus-Hintergrund rechts nicht abgeschnitten wird. Die Regel
               steht mehrzeilig wie in der Listen-CSS, damit der Cross-View-Diff der
               beiden Bloecke zeilenweise lesbar bleibt. */
            padding: 0.2em;
            width: 100%;
            max-width: 100%;
        }
        .vergleich-dashboard .laufzeit-nav::-webkit-scrollbar { display: none; }
        /* Auto-Margins als Zentrier-Fallback (Audit A-7.1b / Nachzug 2026-08-20). NICHT
           ENTFERNEN und nicht mit der Fallback-Zeile oben "aufraeumen" — die beiden gehoeren
           zusammen: wo oben flex-start gewinnt, stuende die Leiste sonst auch dann linksbuendig,
           wenn alle Pills in eine Zeile passen. Die Auto-Margins zentrieren genau diesen Fall und
           kollabieren bei Overflow auf 0, die linken Pills bleiben per scrollLeft erreichbar.
           `:first-child`/`:last-child` sind zwingend — `:first-of-type` traefe wegen des gemischten
           Markups (aktive Pill = <span>, uebrige = <a>) ZWEI Elemente und risse die Leiste auseinander. */
        .vergleich-dashboard .laufzeit-nav .laufzeit-pill:first-child { margin-inline-start: auto; }
        .vergleich-dashboard .laufzeit-nav .laufzeit-pill:last-child { margin-inline-end: auto; }
        .vergleich-dashboard .laufzeit-nav .laufzeit-pill {
            min-height: 2.75em; scroll-snap-align: center;
            flex-shrink: 0; padding-left: 0.75em; padding-right: 0.75em;
        }
        .nav-scroll-wrapper {
            -webkit-mask-image: linear-gradient(to right, transparent, black 1.5em, black calc(100% - 1.5em), transparent);
            mask-image: linear-gradient(to right, transparent, black 1.5em, black calc(100% - 1.5em), transparent);
        }
        .nav-scroll-wrapper.scroll-start {
            -webkit-mask-image: linear-gradient(to right, black, black calc(100% - 1.5em), transparent);
            mask-image: linear-gradient(to right, black, black calc(100% - 1.5em), transparent);
        }
        .nav-scroll-wrapper.scroll-end {
            -webkit-mask-image: linear-gradient(to right, transparent, black 1.5em, black);
            mask-image: linear-gradient(to right, transparent, black 1.5em, black);
        }
        .nav-scroll-wrapper.scroll-start.scroll-end { -webkit-mask-image: none; mask-image: none; }
    }
    @media (max-width: 52em) and (hover: hover) and (pointer: fine) {
        .vergleich-dashboard .laufzeit-nav { cursor: grab; }
        .vergleich-dashboard .laufzeit-nav.is-dragging { cursor: grabbing; scroll-behavior: auto; user-select: none; }
        .vergleich-dashboard .laufzeit-nav.is-dragging .laufzeit-pill { pointer-events: none; }
    }
    /* ── Focus-Visible-States fuer Tastatur-Navigation (A1-Nachzug, CT-0148
       2026-08-26) ── Muster 1:1 aus der Schwester-Liste
       (`tagesgeld-vergleich-core.inc.php`, Sammelblock expand-btn/sort-btn/
       details-tab/laufzeit-pill). Der Hell-Modus braucht KEINE eigene Regel:
       `--accent` wird zentral in vergleich.min.css von #A9F6DB auf #00528D
       umgeschrieben (`#vergleich.kontrast-hell .vergleich-dashboard`), der Ring
       wechselt also mit. Zwei verschiedene Gruende, live gemessen 2026-08-26:

       • `.sort-btn` ist ein <button> — der globale `a:focus-visible` aus
         style.css greift dort nicht, es blieb der UA-Ring. Der war NICHT
         barrierefrei kaputt (3,58:1 default / 18,04:1 hell, zweifarbig); die
         Regel ist hier Konsistenz-Politur, keine Fehlerbehebung.
       • `.laufzeit-pill` und `.anbieter-link` sind <a> und erbten deshalb den
         globalen `a:focus-visible{outline:2px solid var(--mint-400)}`. #4DE5B4
         ist eine Dunkelmodus-Farbe, und der Kontrast-Umschalter remappt nur
         `--accent`, nicht `--mint-400`. Im Hell-Modus fiel der Ring damit auf
         1,37:1 (Pill) bzw. 1,40:1 (CTA) — unter der 3:1-Schwelle von WCAG
         1.4.11, also eine echte Verletzung. Mit `--accent` sind es 6,99:1 (Pill)
         bzw. 7,10:1 (CTA).
         Gleicher Mechanismus wie Festgeld Phase A1 (dort 1,45:1). */
    .vergleich-dashboard .sort-btn:focus-visible,
    .vergleich-dashboard .laufzeit-pill:focus-visible,
    .vergleich-dashboard .anbieter-link:focus-visible {
        outline: 2px solid var(--accent, #A9F6DB);
        outline-offset: 0.125em;
    }
    .vergleich-dashboard .filter-section { position: relative; margin-top: -1.1em; margin-bottom: 5em; overflow: visible; }
    .filter-panel-titel { display: block; font-size: 0.7rem; font-weight: 600; color: rgba(255, 255, 255, 0.7); text-transform: uppercase; letter-spacing: 0.5px; padding-bottom: 0.5em; margin-bottom: 0.75em; border-bottom: 1px solid rgba(255, 255, 255, 0.1); }
    /* Kontrast-Politur 2026-06-12 (Schwester-Rollout): Die Footer-Link-Farben
       (Ruhe #1FD99B / Hover #8FF6D5) sind ZENTRAL in vergleich.min.css
       definiert (`.vergleich-dashboard .footer-line a` bzw. `a:hover`).
       Die frueheren Core-Overrides (.vergleich-footer a:link/:visited/:hover)
       sind entfernt. Bei min.css-Aenderungen den ?v=-Parameter am
       vergleich.min.css-<link> im Core bumpen (derzeit v=20). */

    /* === Eigentliches Tabellen-Layout === */
    /* Full-Bleed ab Tablet aufwaerts: Sortier-Bar, Tabelle und "mehr anzeigen"
       brechen aus dem zentrierten Site-Container aus und nutzen die volle
       Viewport-Breite. Schalterleiste und Filter-Bar bleiben oben im normalen
       Container — visuell ein klarer Datenbereich.
       Klassisches "left: 50%; margin-left: -50vw"-Pattern.
       Politur 2026-06-11 (Doc-Overflow-Fix): 100vw umfasst per CSS-Spec die
       vertikale Scrollbar — sobald die Seite vertikal scrollt, war der
       Container um die Scrollbar-Breite (6-17 px je nach Browser) zu breit
       und erzeugte horizontalen Doc-Overflow. `--viewport-w` wird per IIFE
       (tabelleViewportBreiteIIFE) auf documentElement.clientWidth gesetzt
       (= Viewport OHNE Scrollbar) und an :root vererbt; 100vw bleibt nur
       als No-JS-Fallback. */
    /* Vier-Stufen-Layout: gleichbreite Slots ueber den gesamten Nicht-Mobile-Bereich
       (analog DE-Hauptnav `#nav li { width: 11.111% }` = 100/9). Drei prozentuale
       Stufen, monoton fallende Anbieter-Anzahl ohne Spruenge zwischen den Schwellen
       (Politur 2026-05-09: untere Schwelle von 72em auf 38.0625em vorgezogen — der
       frueher dazwischenliegende Default-12em-Bereich 52-72em liess die Spaltenzahl
       beim Verkleinern wieder auf 4-5 anwachsen, weil weder min-width:72em noch
       max-width:52em griff. Folge: max-width:52em-Block setzt die Variablen nicht
       mehr, dort nur noch Font-/Padding-Politur):
         - >= 124em (4K + ueberbreit, ~1984px+):     9 Slots = 1 VP + 8 Anbieter à 11.111%
         -  76-124em (Full-HD-Standard, ~1216px):    6 Slots = 1 VP + 5 Anbieter à 16.667%
         -  38.0625-76em (Tablet-/Notebook-Bereich): 4 Slots = 1 VP + 3 Anbieter à 25%
         -  <= 38em:                                 Mobile-Block (3 Anbieter à 30vw, VP unsichtbar)
       Cascade: bei jedem Viewport greifen alle min-width-Regeln, die <= der
       Viewport-Breite sind — die letzte gewinnt (= naechstgroesserer Modus).
       Container-Innenbreite = 100vw - 1.5em links - 1.5em rechts = 100vw - 3em.
       Politur 2026-06-11 (Doc-Overflow-Fix): 100vw in den Stufen-Formeln durch
       var(--viewport-w, 100vw) ersetzt — selbe Begruendung wie am Full-Bleed-
       Block oben (100vw enthaelt die vertikale Scrollbar; die Slots haetten
       sonst weiter ueber den korrigierten Container hinausgehangen). */
    /* Politur 2026-05-11 (Sticky-Mini-Header): --slot-breite und --vp-breite
       jetzt am .tabelle-wrapper statt am .tabelle-scroller. Grund: CSS-Custom-
       Properties vererben nur an Descendants, nicht an Geschwister. Der
       Sticky-Mini-Header (.tabelle-sticky-mini) ist Sibling des Scrollers und
       konnte vorher die Variablen nicht lesen — Mini-Spalten waren auf den
       12em/14em-Fallback gefangen, Misalignment auf Desktop-mittel/breit.
       Migration auf den gemeinsamen Wrapper loest das. Der Scroller bleibt
       Descendant des Wrappers und erbt die Werte weiter. */
    .tabelle-wrapper {
        margin-top: 1em;
        position: relative;
        /* Default-Werte fuer --slot-breite/--vp-breite: greifen praktisch nur,
           wenn keine Media-Query matcht (siehe Z. ~840+). Migration vom
           .tabelle-scroller auf .tabelle-wrapper im Zuge der Sticky-Mini-
           Header-Einfuehrung (Politur 2026-05-11), damit der Mini-Track als
           Sibling des Scrollers die Variablen erbt. */
        --slot-breite: 12em;
        --vp-breite: 14em;
    }
    /* Scroll-Ende-Indikator: schmaler heller Schimmer-Gradient am rechten Rand
       der Tabelle deutet an, dass nach dem letzten sichtbaren Anbieter weitere
       folgen — der naechste Anbieter ist gerade ausserhalb des Viewports, sein
       Vorhandensein wird durch einen weichen Hell-Verlauf an der Container-Kante
       visuell signalisiert. Pseudo-Element sitzt auf dem nicht-scrollenden
       .tabelle-wrapper — bleibt beim horizontalen Scrollen am Container-Rand
       fixiert. Wird per JS-Klasse `.is-scroll-ende` ausgeblendet, sobald der
       Nutzer das Scroll-Ende erreicht (= alle Anbieter sichtbar gewesen) oder
       die Tabelle gar nicht horizontal scrollen muss (alle Anbieter passen rein).
       2026-05-07d: schmaler (3em → 2em) und in helle Farbe gewechselt
       (rgba(0,40,90,0.65) → rgba(255,255,255,0.20)) — Schimmer statt Schatten. */
    .tabelle-scroller {
        /* Politur 2026-05-11 (Folgepatch): --hdr-logo-h von 11rem auf 12rem
           erhoeht. Begruendung: mit `flex-shrink: 0` am .ab-logo-wrap (siehe
           Z. ~1244) wird das Logo bei langen Anbieter-/Produktnamen nicht mehr
           gestaucht. Damit der Stack `Logo (max 8em) + Anbieter (max 2 Zeilen
           per line-clamp) + Produkt (1 Zeile per line-clamp) + Padding/Gap`
           ohne Ueberlauf in die Badge-Reihe passt, braucht die Reihe 12rem
           statt 11rem (Rechnung: 128 + 30 + 13 + 16 = 187 px ≤ 192 px). */
        --hdr-logo-h: 12rem;
        --hdr-badge-h: 2rem;
        --hdr-zins-h: 3rem;
        --row-data-h: 2.75rem;
        /* Politur 2026-05-10e: eigene Mindesthoehe fuer Bereichstitel-Reihen
           (.ab-gruppe-spacer + button.vp-gruppentitel), getrennt von
           --row-data-h. Auf Desktop deckt 2.75rem (~44 px) den VP-Gruppentitel-
           Button (padding 1.125em + line-height 1.15) — _vpRowSync zwingt sonst
           die VP-Tracks auf einen zu kleinen Wert und der Button overflowt.
           Auf Mobile ist die VP-Spalte display:none, der gleiche 2.75rem-Wert
           gibt den Bereichsbezeichnungen Atemluft ueber dem Toggle-Overlay
           (~30 px Inhalt) und bleibt deutlich kompakter als --row-data-h: 5rem
           (= 80 px Daten-Reihen). */
        --row-titel-h: 2.75rem;
        /* Politur 2026-05-13: Eigene Mindesthoehe fuer CTA-Footer-Reihen
           (Anbieterlinks). 80% von --row-data-h — Anwender-Wunsch: Felder
           mit Anbieterlinks niedriger als die Daten-Reihen, weil sie weniger
           Inhalt tragen und ohne Mini-Label oben keinen extra Padding-Raum
           brauchen. `minmax(--row-cta-h, auto)` laesst die Reihe weiter
           auto-wachsen, falls der Linktext laenger ist als 2.2rem (35 px). */
        --row-cta-h: 2.2rem;
        /* --slot-breite/--vp-breite definiert jetzt der .tabelle-wrapper
           (Politur 2026-05-11, Sticky-Mini-Migration). Default 12em/14em
           und Media-Query-Stufen (Z. ~840+ und Z. ~1700+) wirken via
           Inheritance auf den Scroller, der weiterhin grid-template-columns
           damit baut. Die calc-Logik ist analog zur DE-Hauptnav
           `#nav li { width: 11.111% }` (= 100/9). */
    }
    /* Vergleichspunkt-Spalte: Flex-Item mit Sticky-Left, eigenes Grid (nicht mehr Subgrid) */
    .vp-spalte {
        flex-shrink: 0;
        width: var(--vp-breite, 14em);
        position: sticky;
        left: 0;
        z-index: 4;
        background: rgba(9, 87, 143, 0.92);
        border-right: 1px solid rgba(255,255,255,0.18);
        box-shadow: 0.25em 0 0.5em rgba(0,0,0,0.2);
        display: grid;
        /* Single-Track-Spalte, die der Outer-Width folgt. Ohne explizite Track-
           Definition fällt der Track auf grid-auto-columns: auto (= max-content)
           zurück — lange Labels weiten den Inner-Track dann über die Outer-
           Width aus. Mobile-Overrides setzen nur `width`, nicht den Track —
           Folge wäre VP-Zellen-Schimmer in die erste Anbieter-Spalte. minmax(0, 1fr)
           bindet den Track an den verfügbaren Platz und cappt min-content. */
        grid-template-columns: minmax(0, 1fr);
        /* Politur 2026-05-10e: --tabelle-data-rows enthaelt die explizite
           Daten-Track-Liste pro sichtbarer Reihe (Server: PHP-Loop ueber $reihen,
           JS-Toggle: updateGridTracks). Fallback ist die alte uniforme repeat()-
           Definition, falls die Variable mal nicht gesetzt ist. */
        grid-template-rows:
            var(--hdr-logo-h)
            var(--hdr-badge-h)
            var(--hdr-zins-h)
            var(--tabelle-data-rows, repeat(var(--anzahl-reihen-rest, 30), minmax(var(--row-data-h), auto)));
    }
    .tabelle-grid {
        flex-shrink: 0;
        display: grid;
        grid-template-columns: repeat(var(--anzahl-anbieter, 8), var(--slot-breite, 12em));
        grid-template-rows:
            var(--hdr-logo-h)
            var(--hdr-badge-h)
            var(--hdr-zins-h)
            var(--tabelle-data-rows, repeat(var(--anzahl-reihen-rest, 30), minmax(var(--row-data-h), auto)));
        align-items: stretch;
    }
    /* Header-Stapel-Reihen — sticky oben, opaker Hintergrund.
       Logo-Reihe hat seit 2026-05-07 einen einfarbigen Hintergrund #0070C0
       (Anwender-Wunsch: Logo-Raender sollen nicht mehr sichtbar sein) —
       siehe eigene Regel weiter unten. badge/zins/balken behalten den
       semitransparenten Block-Background. */
    .vp-zelle.vp-header,
    .ab-zelle[class*="ab-badge"], .ab-zelle[class*="ab-zins"] {
        background: rgba(9, 87, 143, 0.92);
    }
    /* === Phase 8: Sticky-Header oben ===
       position: sticky stand urspruenglich fuer Vertikal-Scrolling im
       Scroll-Container (max-height + overflow-y: auto). Seit Politur
       2026-05-04 / 08l ist der Container ohne eigenen Vertikal-Scrollport
       (overflow-y: visible) — die top-Werte sind also funktional inaktiv.
       position: sticky bleibt trotzdem stehen, weil das ::after-Tooltip an
       .ab-zelle.ab-zins darauf als Containing-Block-Anker angewiesen ist
       (siehe Tooltip-Block weiter unten in dieser Datei,
       .ab-merkmal-html .icon-chart-area / .ab-info-tooltip).
       Stolperstein-Pflege fuer kuenftige
       top-Werte: rem-Variablen, niemals em (Phase-2-Stolperstein 3). */
    .ab-zelle.ab-logo,
    .ab-zelle.ab-badge,
    .ab-zelle.ab-zins,
    .vp-zelle.vp-header {
        position: sticky;
        z-index: 3;
    }
    .ab-zelle.ab-badge,
    .vp-zelle.vp-header.vp-badge  { top: var(--hdr-logo-h); }
    .ab-zelle.ab-zins,
    .vp-zelle.vp-header.vp-zins   { top: calc(var(--hdr-logo-h) + var(--hdr-badge-h)); }

    /* Phase 8 / 14e Sticky-Mini-Header (.tabelle-scroller.is-mini) wurde
       am 2026-05-11 durch den externen, fixed-positionierten Sticky-Mini-
       Header (siehe .tabelle-sticky-mini-track weiter unten in dieser Datei)
       abgeloest. Die alte Mechanik war auf einen vertikal scrollenden
       .tabelle-scroller angewiesen (max-height + overflow-y: auto), die
       seit Politur 2026-05-04 / 08l aus dem Container raus sind. Dadurch
       triggerte die is-mini-Klasse nie mehr. Die zugehoerigen CSS-Bloecke
       sind entfernt, ebenso die IIFE stickyHeaderSetup und die race.js-
       Hooks tabelleStickyHeaderReset/Setup. */
    /* Politur 2026-05-20: Mobile Meta-Strip (#NN + Flagge) — auf Desktop
       per Default unsichtbar. Vollstaendige Mobile-Regeln im
       @media-Block (max-width: 38em). */
    .ab-meta-strip { display: none; }
    .ab-zelle.ab-badge { padding-top: 0.25em; padding-bottom: 0.25em; }
    /* Politur 2026-05-07h: Trennlinie zwischen Badge-Reihe und Zins-Reihe
       entfaellt — Inland-/Auslandsanlage-Pille und Zinszahl fliessen optisch
       ineinander. Generelle `.vp-zelle, .ab-zelle { border-bottom: 1px ... }`
       (Z. ~750) bleibt fuer alle anderen Reihen aktiv. */
    .ab-zelle.ab-badge,
    .vp-zelle.vp-header.vp-badge {
        border-bottom: 0;
    }
    /* Vergleichspunkt-Spalte: spezifische Header-Zellen */
    .vp-zelle.vp-header.vp-logo, .vp-zelle.vp-header.vp-badge { font-size: 0.62rem; }
    /* Gruppen-Titel-Reihen.
       Politur 2026-05-07g: vertikales Padding erhoeht (0.75/0.5em → 1.125/1em)
       und line-height: 1.15 — bei zweizeiligen Titeln wie "Ausschuettung/
       Auszahlung" stehen die zwei Worte enger zusammen, der Block hat dafuer
       mehr Luft nach oben und unten. Bleibt visuell bei einzeiligen Titeln
       unauffaellig (line-height greift nur, wenn Text umbricht). */
    /* Spacer-Zellen in Anbieter-Spalten an Stelle des VP-Gruppentitels.
       Redesign 2026-06-19 (Expander-Band "Feine Koernung", Handoff Variante 02):
       Das Band ist jetzt eine eigene, ruhige Flaeche mit feiner Koernung statt
       der frueheren flachen var(--bg-card)-Zelle. Diese Spacer setzen die
       Koernungs-Flaeche des VP-Gruppentitel-Buttons (siehe button.vp-gruppentitel
       weiter unten) ueber alle Anbieter-Spalten fort, sodass das Band als eine
       durchgehende texturierte Oberflaeche ueber die volle Tabellenbreite laeuft.
       Basis-Toenung rgba(0,82,141,0.40) (Anwender-Wahl 2026-06-19 "ruhig
       integriert" statt solidem #0070C0). Die Koernung ist bewusst in px statt
       em — eine Material-Textur hat eine feste physische Rasterweite und darf
       NICHT mit der Schriftgroesse skalieren (zulaessige Ausnahme zur em-Regel,
       analog box-shadow). Koernung/Borders/Sheen sind byte-gleich zum
       button.vp-gruppentitel, damit Label-Zelle und Fortsetzung nahtlos sind. */
    /* Chart-Icon-Override fuer 'gueltig'-Feld (Standardzins gilt seit) und
       Geschenk-Hover-Override fuer Bonus-Reihe.

       Globale `.icon-chart-area` aus style.css/vergleich.min.css setzt
       font-size: 2.8em + margin-left: -1.8em (gedacht fuer <table>-Detail-
       Tabs). Listenansicht-Schwester nutzt diese Default-Groesse (visuell
       36 px hoch) im `<span class="merkmal-wert">`-Detail-Tab — der
       `margin-left:-1.8em` wird dort durch `.merkmal-wert .icon-chart-area`
       neutralisiert. Politur 2026-05-13: Tabellenansicht uebernimmt
       dieselbe visuelle Groesse und Hover-Farb-/Hintergrund-Logik fuer
       Schwester-Konsistenz. */
    .ab-merkmal-html .icon-chart-area {
        position: relative;
        font-size: 2.8em;
        margin: 0;
        line-height: 1;
        color: #A9F6DB; /* Kontrast-Politur 2026-06-12 (Schwester-Rollout): Akzent-Text #4cb5a0 -> #1FD99B */
        vertical-align: middle;
    }
    /* Politur 2026-06-02: Chart-Glyph-Zustandsfarben an die Listenansicht
       angeglichen (Liste = Master). Site-Default `a:focus>.icon, a:hover>.icon
       { color:#d7f71e }` (style.css Z. 238, Spez. 0,2,1) faerbt das Glyph sonst
       gelb-gruen, sobald der Link nach einem Klick den Fokus behaelt —
       `target="portrait"` oeffnet ein zweites Fenster, der Link im Hauptfenster
       bleibt fokussiert. Die Listenansicht neutralisiert das ueber
       `.merkmal-wert .iframe .icon` (0,3,0); wir spiegeln das mit
       `.ab-merkmal-html .iframe .icon-chart-area` (0,3,0): focus/active/visited
       bleiben auf der Grundfarbe #4cb5a0, NUR hover hebt mit accent-light hervor
       (hover-Regel 0,3,1 schlaegt die Schutzregel 0,3,0 source-order-unabhaengig).
       :visited braucht keine eigene Regel — kein `a:visited>.icon` in der
       Site-CSS (per Screenshot 2026-06-02 verifiziert, Glyph bleibt #4cb5a0). */
    .ab-merkmal-html .iframe .icon-chart-area {
        color: #A9F6DB; /* Kontrast-Politur 2026-06-12 (Schwester-Rollout) */
    }
    .ab-merkmal-html a:hover > .icon-chart-area {
        color: #DFFDF2; /* Kontrast-Politur 2026-06-12 (Schwester-Rollout): Hover-Ton der Akzentfamilie */
    }
    /* Site-Default `a:hover { background: #6699CC; padding: 1px 0 }` aus
       style.css/vergleich.min.css greift sonst und faerbt den Bereich
       hinter Chart-Icon/Geschenk-Link hellblau. Listenansicht-Schwester
       neutralisiert das ueber `.merkmal-wert a:hover { background: none;
       padding: 0 }`; wir reproduzieren es im `.ab-merkmal-html`-Scope. */
    .ab-merkmal-html a:hover,
    .ab-merkmal-html a:focus,
    .ab-merkmal-html a:visited {
        background: none;
        padding: 0;
    }
    /* Geschenk-IMG-Hover (Bonus-Reihe, cardgift-g.svg in `<a class="cardgifta">`):
       Site-Default `a.cardgifta:hover img { filter: brightness(120%) sepia(100%)
       saturate(300%) hue-rotate(15deg) }` schiebt das gruene Icon ins Gelbe.
       Listenansicht-Schwester ueberschreibt mit `brightness(1.4) saturate(1.5)`
       (nur Aufhellung, Tuerkis bleibt). Wir uebernehmen denselben Override. */
    .ab-merkmal-html a.cardgifta:hover img {
        filter: brightness(1.12);
    }
    /* Geschenk-Icon-Vergroesserung (Bonus-Reihe): Site-Default
       `a.cardgifta img { width: 2.7em }` aus style.css um 10 % anheben,
       Politur 2026-05-20. Greift nur fuer Inline-Geschenke in der Bonus-
       Reihe; der Tooltip-Action-Variant `a.ab-info-tooltip-action.cardgifta
       img` (fixe 1.5em) bleibt unberuehrt. */
    .ab-merkmal-html a.cardgifta:not(.ab-info-tooltip-action) img {
        width: 2.97em;
    }
    /* Phase 14 (A7): Truncate-Spans und Info-Icon — Default Desktop sichtbar
       der Volltext, Kurz-Variante und Info-Icon ausgeblendet. Mobile-Switch
       weiter unten im 38em-Block. */
    .ab-merkmal-voll { display: inline; }
    .ab-merkmal-kurz { display: none; }
    /* Tooltip fuer Info-Icon (Mobile-Truncate). Wird per JS-IIFE
       `infoTooltipSetup()` an document.body angehaengt. */
    .ab-info-tooltip {
        display: none;
        position: absolute;
        z-index: 200;
        max-width: 18em;
        padding: 0.5em 0.75em;
        background: rgba(15, 20, 30, 0.95);
        color: #fff;
        font-size: 0.75rem;
        font-weight: 400;
        line-height: 1.4;
        border-radius: 0.4em;
        box-shadow: 0 0.25em 0.75em rgba(0, 0, 0, 0.35);
        pointer-events: auto;
        /* Politur 2026-05-20 (AT-Spiegelung von DE-20b): Tooltip-Inhalt
           rechtsbuendig — konsistent zur Anwender-Konvention "alle
           Vergleichsangaben rechtsbuendig" in der Tabellenansicht. Plain-
           Text-Span erbt text-align, Action-Zeile staut per
           `justify-content: flex-end`. */
        text-align: right;
    }
    .ab-info-tooltip.is-visible { display: block; }
    /* Politur 2026-05-20 (AT-Spiegelung von DE-20a Bonus-Tooltip-Action +
       DE-20b Tooltip-Layout):
       Action-Zeile mit Geschenk-Icon + Linktext unter dem Plain-Text-
       Volltext, durch border-top getrennt. Nur fuer Bonus-Felder mit
       DB-Geschenk-Link gerendert. Selektor-Verlaengerung auf
       `a.ab-info-tooltip-action.cardgifta` (Spez. 0,2,1 fuer Base,
       0,3,2 fuer Hover-Img) schuetzt gegen drei Site-Default-Regeln:
       (a) `a.cardgifta:hover img { filter: brightness(120%) sepia(100%)
       saturate(300%) hue-rotate(15deg) }` (0,2,2) wuerde das Icon im
       Hover gelb-orange faerben; (b) `a:hover { padding: 1px 0 }` (0,1,1)
       wuerde Base-Padding ueberschreiben; (c) `a:visited` (0,1,1) koennte
       `color: #fff` aushebeln. */
    .ab-info-tooltip-text { display: block; }
    a.ab-info-tooltip-action.cardgifta {
        display: flex;
        align-items: center;
        /* Inhalt rechtsbuendig stauen — Reihenfolge bleibt Icon-Label-
           Pfeil, alles ruckt nach rechts (konsistent zur text-align: right
           des Containers). Label-Span verliert flex:1 und schrumpft auf
           natuerliche Breite mit Umbruch-Erlaubnis. */
        justify-content: flex-end;
        gap: 0.5em;
        margin-top: 0.5em;
        padding-top: 0.5em;
        padding-bottom: 0.25em;
        border-top: 1px solid rgba(255, 255, 255, 0.18);
        color: #fff;
        text-decoration: none;
        /* WCAG-Fix 2026-05-20c: rem statt em — der Tooltip-Container traegt
           `font-size: 0.75rem` (= 12 px), `2.75em` waere damit nur ~33 px.
           `2.75rem` ist unabhaengig vom Container-font-size und liefert
           stabile 44 px = WCAG-2.5.5-Tap-Target. */
        min-height: 2.75rem;
        font-weight: 500;
    }
    a.ab-info-tooltip-action.cardgifta img {
        width: 1.5em;
        height: 1.5em;
        flex-shrink: 0;
    }
    a.ab-info-tooltip-action.cardgifta span:not(.ab-info-tooltip-arrow) { flex: 0 1 auto; }
    .ab-info-tooltip-arrow { margin-left: 0.25em; opacity: 0.85; }
    a.ab-info-tooltip-action.cardgifta:hover,
    a.ab-info-tooltip-action.cardgifta:focus-visible {
        background: rgba(255, 255, 255, 0.08);
        border-radius: 0.25em;
    }
    a.ab-info-tooltip-action.cardgifta:hover img,
    a.ab-info-tooltip-action.cardgifta:focus-visible img {
        filter: brightness(1.12);
    }
    /* Footer-CTA */
    /* CTA-Footer-Zellen mit dem Anbieter-Button.
       Politur 2026-05-07j: Hintergrund von dunkelblau-gesaettigt
       (rgba(9,87,143,0.96)) auf var(--bg-card) umgestellt — selbe Farbe
       wie .vergleich-dashboard .filter-section und seit 2026-05-07e auch
       die .ab-gruppe-spacer. Wirkt heller und konsistent zum Filter-Bereich. */
    /* CTA-Link selbst (`.anbieter-link` + `.link-arrow`) erbt vollstaendig
       aus vergleich.min.css (`.vergleich-dashboard .anbieter-link…`).
       Dort ist auch `::after { content:none !important }` definiert, das
       das vom globalen Theme injizierte Linksymbol fuer externe Links unterdrueckt.
       Phase 14 (A6): Externer-Link-Icon Default unsichtbar, Mobile-Switch
       weiter unten im 38em-Block. Spezifizitaet `.vergleich-dashboard …`
       schlaegt das Listen-globale `.anbieter-link`-Styling. */
    /* Mobile: schmaler padden, kleinere Schrift. */
    @media (max-width: 38em) {
        .tabelle-fussnoten {
            padding: 0.875em 1em;
            font-size: 0.8rem;
        }
    }
    /* Responsive */
    @media (max-width: 52em) {
        /* Politur 2026-05-09: --slot-breite und --vp-breite werden ab dem
           38.0625em-Block (oben) per calc((100vw - 3em) / 4) gesetzt — hier
           nur Font-Size/Padding-Politur fuer Tablet/kleinere Notebooks.
           Vorher: --slot-breite: 10em und --vp-breite: 12em fix; das fuehrte
           zu 2-4 sichtbaren Anbietern je nach Bruchteil und nicht zur klaren
           3-Anbieter-Stufung. */
        .vp-zelle, .ab-zelle { font-size: 0.78rem; padding: 0.4375em 0.5em; }
        .ab-zelle.ab-zins { font-size: 1.25rem; }
    }
    /* Mobile-Hauptblock (Politur 2026-05-08, Phase 14, weiter angepasst in
       Folgepatch 14c):
       Drei Anbieter-Spalten mit je 1/3 Viewport. VP-Spalte ist auf Mobile
       komplett unsichtbar (`display: none`) — die Reihen-Labels uebernehmen
       die Mini-Labels, die Bereichsbezeichnungen rendern in der ersten
       Anbieter-Spalte (siehe Mini-Label-Block plus mb-gruppentitel-Block
       weiter unten). `--vp-breite: 0px` bleibt fuer die Variable, weil
       `.tabelle-scroller { scroll-padding-left: var(--vp-breite, 14em); }`
       sie verwendet — `0px` vermeidet ein vp-Breite-grosses Snap-Padding,
       das sonst die linkste Spalte zu weit nach rechts wegschneiden wuerde
       (Stolperstein 13). --hdr-logo-h auf 8rem statt 11rem reduziert die
       Logo-Reihe. font-size/padding-Werte aus dem alten 38em-Block uebernommen.
       Die alte 29em-Stufe (3-Slot-Layout fuer Smartphones im Hochkant) entfaellt,
       weil dieses Mobile-Layout ohnehin durchgaengig 3 Spalten zeigt.

       Vertikal-Scroll-Port (Phase 14, A2) entfaellt im Folgepatch 08l
       (2026-05-08): Auf Anwender-Wunsch hat die Tabelle auf Mobile keinen
       eigenen Y-Scrollbalken mehr — `max-height`, `overflow-y: auto` und
       `overscroll-behavior-y` wurden entfernt. Die Tabelle wird in voller
       Hoehe sichtbar und ueber den Page-Scrollbar erreicht.
       Politur 2026-05-11: Der frueher hier verankerte Mini-Sticky-Header
       (`.tabelle-scroller.is-mini`) ist durch den externen, fixed-positio-
       nierten Sticky-Mini-Header (.tabelle-sticky-mini) ersetzt — siehe
       eigener CSS-Block weiter unten in dieser Datei. */
    @media (max-width: 38em) {
        .tabelle-wrapper {
            /* Politur 2026-05-08h (B1): Anbieter-Spalten auf 30vw reduziert
               (vorher calc((100vw - 0.5em) / 3) ≈ 33.3vw). Bei 375 px
               Viewport ergibt 30vw = 112.5 px je Spalte; 3 Spalten = 337.5 px.
               Plus Site-Container-Offset (~21 px) plus rechte Schimmer-Gradient/
               Scrollbar (~12 px) bleiben rund 5 px Atemluft — drei Anbieter-
               Spalten passen jetzt vollstaendig in den Viewport, das vorherige
               Anschneiden der dritten Spalte am rechten Rand entfaellt.
               Politur 2026-05-11 (P1): von Viewport-vw auf Scroller-clientWidth
               umgestellt. 30vw rechnete gegen den Viewport, der Scroller-
               Container ist wegen Site-Section-Padding aber schmaler als
               100vw — auf einem Samsung S25 (~393 px Viewport, ~343 px
               Scroller-clientWidth) ueberhing die 3. Anbieter-Spalte um
               ~10-15 px nach rechts (Logos, Flaggen-Pille, "AG"-Suffix
               und Texte sichtbar abgeschnitten). `--scroller-w` wird per
               IIFE auf scroller.clientWidth gesetzt UND zusaetzlich am
               Wrapper gespiegelt (tabelleMiniLabelSetupIIFE/syncBreite),
               damit auch der .tabelle-sticky-mini-track als Wrapper-
               Descendant denselben Wert erbt.
               Politur 2026-05-11 (Sticky-Mini-Migration): Selektor vom
               .tabelle-scroller auf .tabelle-wrapper umgestellt (CSS-Custom-
               Properties vererben nur an Descendants, der Sticky-Mini-Track
               als Sibling des Scrollers brauchte den gemeinsamen Vorfahren). */
            --slot-breite: calc((var(--scroller-w, 100vw) - 1.5em) / 3);
            --vp-breite: 0px;
        }
        .tabelle-scroller {
            /* Politur 2026-05-08e (P1): --hdr-logo-h von 8rem auf 10rem
               erhoeht — bei der bisherigen 8rem-Reihe wurde das Logo
               (max-height 8em ≈ 5.76rem bei 0.72rem font-size) plus
               Anbietername (0.78rem * 1.2 line-height) plus Produktname
               (0.7rem * 1.15 line-height) am oberen Rand abgeschnitten,
               weil der Stack flex-flex-start arbeitet und keine Atemluft
               oben hatte. 10rem (~160 px) gibt dem Logo + 2 Textzeilen
               sauberen Platz, das Logo wird nicht mehr beschnitten.
               Politur 2026-05-11 (Folgepatch): von 10rem auf 11rem
               erhoeht. Logo-Wrap ist jetzt flex-shrink: 0 (siehe
               Z. ~1244), das Logo wird nicht mehr gestaucht — bei
               Mobile-30vw-Spalten gerendert mit ~100 px Hoehe. Stack:
               100 + 30 (Anbieter 2-Zeilen-Clamp) + 13 (Produkt
               1-Zeile-Clamp) + 16 (Padding/Gap) = 159 px, passt in
               11rem (176 px) ohne Ueberlauf in die Badge-Reihe. */
            --hdr-logo-h: 11rem;
            /* Politur 2026-05-20c: Badge-Reihe (Inland/Auslandsanlage-Pille)
               auf Mobile komplett aus dem Layout nehmen. Die alte Pille wandert
               als Flagge in den .ab-meta-strip in der linken oberen Ecke der
               Logo-Zelle (Positionsnummer + Landesflagge). Track-Hoehe auf 0px
               setzt die Subgrid-Reihe inaktiv; .ab-zelle.ab-badge wird im
               Mobile-Block weiter unten zusaetzlich auf padding/min-height/
               overflow kollabiert. */
            --hdr-badge-h: 0px;
            /* Folgepatch 14d: --row-data-h auf Mobile von 2.75rem auf 5rem
               erhoeht. Mehrzeilige Werte (Einlagensicherung, Hoechsteinlage,
               PostIdent/VideoIdent, Zinsausschuettungs-Sonderfaelle) brauchen
               bei 122-px-Spaltenbreite und 12.8-px-Mini-Label-Reservierung
               (padding-top: 1.7em) mehr Platz, sonst ueberragen sie die
               44-px-Cell-Box visuell. 5rem = 80 px abzueglich padding ergibt
               etwa 54 px Inhaltsraum (~3-3.5 Textzeilen); `minmax(min, auto)`
               im Subgrid laesst die Reihe bei laengeren Inhalten weiter
               auto-wachsen. */
            --row-data-h: 5rem;
            /* Politur 2026-05-10e: Spacer-Reihen auf Mobile etwas hoeher als
               Desktop (Toggle-Overlay 30 px + Atemluft). Default 2.75rem
               (~44 px) wirkte noch knapp, 3rem (~48 px) gibt dem Banner sicht-
               bare Luft und bleibt deutlich kompakter als --row-data-h: 5rem
               (~80 px Daten-Reihen). VP-Spalte ist auf Mobile display:none —
               der VP-Gruppentitel-Button spielt keine Rolle. */
            --row-titel-h: 3rem;
            /* Politur 2026-05-13: CTA-Footer-Reihe auf Mobile von 5rem
               (--row-data-h) auf 4rem reduziert — 80% (Anwender-Wunsch).
               Inner-Link (font-size 0.7rem, padding 0.4375em) plus Zellen-
               padding 0.625em ergibt ca. 37-40 px Inhaltshoehe — passt
               bequem in 64 px (4rem). minmax laesst auch hier auto-Wachstum
               zu, wenn der CTA mehr Hoehe braucht. */
            --row-cta-h: 4rem;
            /* Politur 2026-05-11 (M2): Scroll-Snap auf Mobile abschalten. Der
               x-proximity-Snap des Default-Blocks cappte das echte
               scrollLeft-Maximum um ~14 px, sodass die letzte Anbieter-Spalte
               rechts angeschnitten blieb. Auf Touch ist Snap ohnehin eher
               hinderlich (schwungvolles Drag-Scrolling springt zurueck).
               scroll-padding-right schiebt zusaetzlich den Atemraum zum
               Schimmer-Gradient ein. */
            scroll-snap-type: none;
            scroll-padding-right: 0.5em;
        }
        /* Politur 2026-05-11 (P3): column-gap zwischen Anbieter-Spalten auf
           Mobile. Auf Smartphones (Samsung S25-Screenshots) stiessen die
           Spalten ohne sichtbaren Abstand aneinander, Texte (z.B.
           "Einlagensicherung AUSTRIA Ges.m.b.H.") wirkten ineinander
           uebergehend. Subgrid uebernimmt nur Tracks, nicht Gaps — die
           Reihen-Sync zwischen VP-Spalte und Anbieter-Spalten bleibt
           intakt. --slot-breite (P1) kompensiert die 2 × 0.5em-Gaps via
           1.5em-Reserve. */
        .tabelle-grid { column-gap: 0.5em; }
        /* Politur 2026-05-11 (P2): Schimmer-Gradient auf Mobile schmaler und
           halbtransparent. Default 2em × opacity 1 wirkte auf 30vw-Spalten
           als heller Streifen ueber fast einem Drittel der letzten Spalte —
           im Samsung-Screenshot als "Schattierung am rechten Rand der
           Bereiche-Banner" beanstandet. Auf Touch ist Drag-Scrolling auch
           ohne visuellen Scroll-Hinweis intuitiv, der Schimmer kann dezenter
           bleiben. ::before bleibt am Default-opacity-0 (linker Schimmer
           wird erst per .is-scroll-anfang aktiv), nur der dann sichtbare
           Wert wird angepasst. */
        .tabelle-wrapper::after,
        .tabelle-wrapper::before { width: 0.75em; }
        .tabelle-wrapper::after { opacity: 0.5; }
        .tabelle-wrapper.is-scroll-anfang::before { opacity: 0.5; }
        .vp-zelle, .ab-zelle { font-size: 0.72rem; padding: 0.375em 0.4375em; }
        .ab-zelle.ab-zins { font-size: 1.05rem; }
        /* Politur 2026-05-10f: 0.2em Abstand zwischen Zins-Header-Reihe und
           erstem Bereich (MERKMALE-Bezeichnung). Grid-Default `align-self:
           stretch` macht die Zinszelle 0.2em kuerzer als ihre fixe Track-Hoehe
           (--hdr-zins-h: 3rem), die Differenz wirkt als Luecke direkt unter
           dem Zinszahl-Block. Nur auf Mobile — auf Desktop kleben Header und
           Bereichstitel weiter direkt aneinander. */
        .ab-zelle.ab-zins,
        .vp-zelle.vp-header.vp-zins {
            margin-bottom: 0.2em;
        }
        .ab-cta-link { font-size: 0.7rem; padding: 0.4375em 0.625em; }
        /* Politur 2026-05-08e (P1): Logo-Stack vertikal zentrieren, damit
           das Logo nicht oben am Rand klebt. justify-content: center auf
           der flex-direction:column-Zelle zentriert vertikal Logo + Anbieter-
           name + Produktname als Block in der 10rem-Reihe — das Logo bekommt
           damit oben automatisch Atemluft. */
        .ab-zelle.ab-logo {
            justify-content: center;
        }
        /* Sticky-Header-Reaktivierung: Background der Sticky-Zellen muss
           solid sein, sonst scheint die scrollende Datenreihe darunter durch.
           Site-Site-Variable `--bg-card` wird hier wegen Subgrid-Hintergrund-
           Vererbung explizit als solid `#0a3a5c`-Aequivalent ausgedrueckt. */
        .ab-zelle.ab-badge,
        .ab-zelle.ab-zins,
        .vp-zelle.vp-header.vp-badge,
        .vp-zelle.vp-header.vp-zins {
            background: rgb(9, 87, 143);
        }
        /* Phase 14 (A3): Mini-Label als Banner ueber jeder Wert-Reihe.
           padding-top reserviert Platz, der Inhalt darunter bleibt zentriert.
           Mini-Label ist position: absolute — keine zusaetzliche Grid-Reihe,
           daher bleiben _vpRowSync und Track-Hoehen unangetastet
           (Stolperstein 12 vermieden). gruppe-zu wirkt durch das Eltern-
           opacity automatisch auch auf das Label.
           Folgepatch 14a-5: font-size von 0.6rem auf 0.7rem (~11.2 px),
           padding-top der Eltern-Zelle von 1.55em auf 1.7em entsprechend
           nachgezogen. Sekundaerer Text traegt damit ueber dem WCAG-
           Mindestwert von 11 px.
           Politur 2026-05-14 (Pass 1+2, Schwester-Sync zu Festgeld AT):
           padding-top um 0.3em auf 2em erhoeht — Pass 1 brachte 1.7em →
           1.9em, Pass 2 nach Live-Verifikation 1.9em → 2em. Der :has()-
           Override fuer truncated Labels wandert parallel auf 2.8em
           (Pass 1: 2.5em → 2.7em, Pass 2: 2.7em → 2.8em). */
        .ab-zelle.ab-merkmal {
            padding-top: 2em;
            /* Politur 2026-05-13: Trennlinie nach jedem Paar aus Mini-Label
               und Datenzeile (Anwender-Wunsch). Default
               `.vp-zelle, .ab-zelle { border-bottom: 1px solid rgba(255,255,255,0.06) }`
               (Z. ~1082) ist zu zart — auf 0.14 verstaerkt (gleiche Staerke
               wie die Trennlinie zur Vorgruppe am .ab-gruppe-spacer border-top).
               Subgrid-Reihen-Subgrid: die Border fluchtet horizontal ueber
               alle drei Anbieter-Spalten zu einer durchgehenden Linie. */
            border-bottom: 1px solid rgba(255, 255, 255, 0.14);
        }
        /* Politur 2026-05-11 (Mini-Label-Truncate, Visual-Pass): bei Reihen
           mit sichtbarem Volltext-Button (`.is-truncated`) waechst das
           Mini-Label-Banner von ~20 auf ~30 px durch den groesseren Button.
           padding-top adaptiv per :has() von 1.7em auf 2.5em hochziehen,
           damit der Banner-Bereich kollisionsfrei zum Wert-Bereich endet.
           Reihen ohne Truncate-Button (kurze Labels, Banner bleibt schmal)
           behalten die schmale Reservierung — verhindert ueberfluessigen
           Leerraum bei kurzen Bezeichnungen. :has() ist seit Chrome 105 /
           Safari 15.4 / Firefox 121 stabil verfuegbar.
           Politur 2026-05-14 (Pass 1+2, Schwester-Sync zu Festgeld AT):
           +0.3em parallel zur Basis-Regel (oben). Pass 1: 2.5em → 2.7em,
           Pass 2 nach Live-Verifikation: 2.7em → 2.8em. */
        .ab-zelle.ab-merkmal:has(.ab-info-icon-mini-label.is-truncated) {
            padding-top: 2.8em;
        }
        /* Politur 2026-05-13: border-bottom der letzten merkmal-Zelle einer
           Gruppe unterdruecken, weil der direkt nachfolgende .ab-gruppe-spacer
           selbst eine border-top: 1px solid rgba(255,255,255,0.14) traegt
           (Default-Regel Z. ~1462). Ohne dieses Override summieren sich
           beide Linien zu einer optischen 2 px-Doppellinie am Gruppen-
           Uebergang. `:has(+ .ab-gruppe-spacer)` greift nur dann, wenn der
           DIREKTE DOM-Sibling ein gruppe-spacer ist — also genau bei der
           letzten merkmal-Zelle vor jedem Bereichstitel-Wechsel.
           Browser-Support analog zur Truncate-:has()-Regel oben. */
        .ab-zelle.ab-merkmal:has(+ .ab-gruppe-spacer) {
            border-bottom: none;
        }
        /* Folgepatch 14b: Pro Wert-Reihe nur EIN Mini-Label, mittig ueber die
           drei sichtbaren Anbieter-Spalten. Verankert in der ersten Anbieter-
           Spalte (DOM-first-child), absolut positioniert mit Viewport-Breite,
           horizontal per JS sticky am linken Viewport-Rand (siehe IIFE
           tabelleMiniLabelSetup, Variable --mini-label-x). Andere Anbieter-
           Spalten rendern weiter ein <span class="ab-mini-label"> im HTML
           (Render-Symmetrie, kein PHP-Index-Param noetig), das aber per
           Default-Mobile-Display:none unsichtbar bleibt. */
        .ab-mini-label { display: none; }
        .tabelle-grid > .anbieter-spalte:first-child .ab-mini-label {
            /* Politur 2026-05-11 (Mini-Label-Truncate): display: flex statt
               block. Damit Text-Span und Volltext-i-Button als Flex-Children
               nebeneinander zentriert sitzen koennen. Ellipsis-Eigenschaften
               (white-space/overflow/text-overflow) wandern auf .ab-mini-
               label-text — der Container kuemmert sich nur um Breite,
               Position und Sticky-Sync. */
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.25em;
            position: absolute;
            /* Politur 2026-05-13: 0.2em Abstand zur Top-Kante der Datenzelle
               (Anwender-Wunsch) — Label klebt nicht mehr direkt an der
               Trennlinie der Vorgaenger-Zeile. em bezieht sich auf die
               eigene Schriftgroesse 0.8rem ≈ 12.8 px, ergibt ca. 2.6 px
               Abstand. */
            top: 0.2em;
            left: 0;
            /* Politur 2026-05-10e: Breite an die tatsaechlich sichtbare
               Tabellen-Breite gebunden (`--mini-label-w`, gesetzt von der
               IIFE `tabelleMiniLabelSetupIIFE` als `min(scroller.clientWidth,
               grid.offsetWidth)`). Der Scroller ist wegen Section-Padding
               schmaler als 100vw — vorher ragte das Mini-Label rechts ueber
               die letzte Anbieter-Spalte hinaus. Fallback auf den alten
               100vw-Wert, falls die IIFE nicht laeuft. */
            width: var(--mini-label-w, calc(100vw - 0.5em));
            box-sizing: border-box;
            padding: 0.15em 0.5em;
            font-size: 0.8rem;
            line-height: 1.25;
            /* Politur 2026-05-11 (Label-Hierarchie): Label-Schrift von
               0.78 → 0.55 Deckkraft gedimmt. Damit die Werte in den
               Daten-Zellen die dominantere Schriftfarbe sind und die
               Mini-Labels als sekundaere Tonstufe zuruecktreten
               (Anwender-Wunsch 2026-05-11). Gleiche Farb-Familie wie die
               Werte (reines Weiss), nur Helligkeit reduziert — keine
               eigene Toenung. */
            color: rgba(255, 255, 255, 0.55);
            /* Politur 2026-05-13: Hintergrund von var(--bg-card) auf transparent
               umgestellt (Anwender-Wunsch) — Mini-Label teilt jetzt den Page-
               Hintergrund mit der Datenzelle darunter, beide wirken als eine
               durchgehende Flaeche. Vorher (08e/P2) war hier var(--bg-card) als
               einheitliche Header-System-Optik gemeinsam mit .ab-gruppe-spacer
               und .ab-cta gesetzt. Trennung zur naechsten Reihe sitzt jetzt
               an .ab-zelle.ab-merkmal border-bottom (1 px, 0.14 Opacity). */
            background: transparent;
            text-transform: uppercase;
            letter-spacing: 0.04em;
            text-align: center;
            /* Politur 2026-05-11 (Mini-Label-Truncate): white-space, overflow
               und text-overflow wandern auf das innere .ab-mini-label-text.
               Der Container ist jetzt Flex — Ellipsis greift am Inner-Span,
               der per `min-width: 0` schrumpfen darf.
               Politur 2026-05-13: border-bottom entfernt — die Linie zwischen
               Label und Wert ist nicht mehr gewuenscht (Anwender-Wunsch:
               Label und Wert als zusammengehoeriges Paar). Trennung zur
               naechsten Reihe sitzt jetzt an .ab-zelle.ab-merkmal border-
               bottom. */
            border-bottom: none;
            /* Politur 2026-05-11 (Mini-Label-Truncate): `pointer-events: none`
               entfernt. Mini-Label traegt selbst keinen Click-Handler — die
               Eigenschaft war eine Vorbeugung ohne sichtbares Verhalten,
               blockierte aber Click-Events des Inline-i-Buttons in manchen
               Browser-/Touch-Konstellationen (Anwender-Meldung: Hand-Cursor
               sichtbar, Klick reagierte nicht). Ohne diese Eigenschaft
               faengt der Button seine eigenen Klicks regulaer ueber die
               Event-Delegation in `infoTooltipSetup()`. */
            /* Politur 2026-05-11 (A): translateX → translate3d zwingt den
               Browser, das Element auf eine eigene GPU-Compositor-Layer zu
               promoten. Touch-Scrolling laeuft auf dem Compositor-Thread; ohne
               eigenen Layer wird der translateX-Update vom Main-Thread
               (CSS-Custom-Property setzen → Style-Recalc → Paint) 1-2 Frames
               verzoegert sichtbar — der User berichtete ein "Springen" der
               Legende beim horizontalen Daumen-Scroll. backface-visibility
               ist ein zusaetzlicher Compositor-Hint, der das Layer-Promote
               noch deterministischer macht. */
            transform: translate3d(var(--mini-label-x, 0px), 0, 0);
            backface-visibility: hidden;
            will-change: transform;
            /* Politur 2026-05-11 (Mini-Label-Truncate, Hit-Test-Fix):
               z-index: 2 ueber den nachfolgenden Anbieter-Spalten-Geschwistern
               (die per DOM-Order ohne explizites z-index stapeln). Hintergrund:
               das Mini-Label-Banner sitzt absolute in der first-child-Anbieter-
               Spalte und wird per `transform: translate3d(--mini-label-x)`
               visuell ueber alle drei Spalten gezogen. Ohne z-index lag das
               Banner im Stacking-Kontext der first-child-Spalte und wurde von
               second/third-child `.ab-zelle.ab-merkmal` (jeweils
               position: relative, z-auto) im Hit-Test ueberlagert — Klicks
               auf den Inline-i-Button landeten in der jeweils darunter-
               liegenden Wert-Zelle statt am Button. Unter dem Sticky-Header
               (z-index: 3) und ueber den Geschwistern (z-auto) ist `2` die
               richtige Stufe. Analog am `.mb-gruppentitel`-Bereichstitel-
               Toggle (gleiche transformierte Banner-Mechanik). */
            z-index: 2;
        }
        /* Politur 2026-05-11 (Mini-Label-Truncate): Inner-Span traegt die
           Ellipsis-Eigenschaften, die zuvor am Container lagen. min-width: 0
           ist Pflicht, damit der Flex-Child wirklich schrumpfen kann
           (Default min-width: auto an Flex-Items = min-content) — sonst
           greift text-overflow: ellipsis nicht. flex: 0 1 auto erlaubt das
           Schrumpfen, behaelt aber die Content-Breite als Bevorzugung,
           damit kurze Labels nicht den Platz fuellen. */
        .ab-mini-label-text {
            min-width: 0;
            flex: 0 1 auto;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        /* Folgepatch 14c: VP-Spalte auf Mobile komplett unsichtbar.
           Reihen-Labels uebernehmen die Mini-Labels in der ersten Anbieter-
           Spalte (siehe oben), Bereichsbezeichnungen mit Toggle rendern
           als zweite Form/Button-Pair in der .ab-gruppe-spacer (siehe
           weiter unten). VP-Drawer-Mechanik ist komplett rueckgebaut. */
        .vp-spalte { display: none; }

        /* Phase 14 (A6): CTA Icon-only auf Mobile.
           SVG sichtbar, Text ausgeblendet, 48-px-Tap-Target via min-w/h.
           Spezifizitaet `.vergleich-dashboard .anbieter-link` schlaegt
           das Listen-globale Styling aus vergleich.min.css. */
        /* Politur 2026-05-10d: Rechteckiger Button mit zwei Fontello-Icons
           (Bank + Externer-Link-Pfeil) — exakt wie die alte Tabellenansicht.
           Override gegen `.icon`-Defaults aus style.css (font-size: 3em;
           position: absolute; margin-left: -1.6em) und `.icon-bank`-Mobile-
           Override (position: absolute) per hoeherer Spezifizitaet
           (`.vergleich-dashboard .anbieter-link i.icon-bank` = 3 Klassen + 1 Tag). */
        .vergleich-dashboard .anbieter-link {
            display: flex;
            align-items: center;
            justify-content: center;
            min-width: 4rem;
            min-height: 2rem;
            padding: 0.25rem 0.5rem;
            gap: 0.25rem;
        }
        .vergleich-dashboard .anbieter-link i.icon-bank,
        .vergleich-dashboard .anbieter-link i.icon-link-ext {
            display: inline-block;
            position: relative;
            top: 0;
            font-size: 1.25rem;
            margin: 0;
            line-height: 1;
            color: inherit;
            width: auto;
            height: auto;
        }
        .vergleich-dashboard .anbieter-link-text {
            display: none;
        }
        /* Phase 14 (A7): Mobile-Switch fuer Truncate. Volltext aus, Kurzform
           plus Info-Icon ein. Info-Icon mit ausreichend grosser Hitbox. */
        .ab-merkmal-voll { display: none; }
        .ab-merkmal-kurz { display: inline; }
        /* Politur 2026-05-20 (AT-Spiegelung von DE-19a Bonus-Mobile-Truncate
           + DE-20b Markenblau-Spot): Bonus-Reihe auf Mobile auf 6 Zeilen
           kappen (line-height 1.5 × 6 = 9em max-height + overflow: hidden).
           `.ab-bonus { position: relative }` als Anker fuer den rechts-unten
           platzierten Info-Icon. JS-IIFE `tabelleBonusTruncateSetup` setzt
           `.is-truncated` am Icon UND am Container, wenn scrollHeight >
           clientHeight; `infoTooltipSetup` zeigt den Plain-Text-Volltext +
           optional die Action-Zeile zur Aktionsbeschreibung. Spezifizitaet
           `.ab-zelle.ab-bonus .ab-info-icon-bonus` (0,3,0) schlaegt das
           generische `.ab-info-icon` (0,1,0) und positioniert den Button
           neu ohne `!important`.

           `padding-bottom: 1.8em` am inneren Span bei `.is-truncated`-
           Container reserviert Platz fuer den absolut-positionierten
           Info-Icon.

           Markenblau-Spot (20b, Anwender-Werte): Button im Truncate-
           Zustand bekommt `background-color: rgba(0, 112, 192, 0.85)`
           (Markenton #0070C0 + 85% Opacity), Backdrop-Blur 0.05em
           symmetrisch (Cross-Browser, faktisch Sub-Pixel-Hauch),
           `right: 0` (klebt an Zellen-Kante), `border-radius: 0%`
           (rechteckig), `color: #fff` fuer besseren Kontrast. Hoehere
           Spezifizitaet (0,4,0) als Default `.ab-info-icon` (0,1,0)
           schlaegt dessen `background: transparent` ohne `!important`. */
        .ab-zelle.ab-bonus { position: relative; }
        .ab-zelle.ab-bonus .ab-merkmal-html {
            display: block;
            max-height: 9em;
            line-height: 1.5;
            overflow: hidden;
        }
        .ab-zelle.ab-bonus.is-truncated .ab-merkmal-html {
            padding-bottom: 1.8em;
        }
        .ab-zelle.ab-bonus .ab-info-icon-bonus { display: none; }
        .ab-zelle.ab-bonus .ab-info-icon-bonus.is-truncated {
            display: inline-flex;
            position: absolute;
            right: 0;
            bottom: 0.2em;
            margin-left: 0;
            background-color: rgba(0, 112, 192, 0.85);
            -webkit-backdrop-filter: blur(0.05em);
            backdrop-filter: blur(0.05em);
            border-radius: 0%;
            color: #fff;
        }
        .ab-info-icon {
            position: relative;
            /* Politur 2026-05-11 (M1b): eigener Stacking-Kontext, damit der
               unsichtbare `::before`-Slop im Hit-Test ueber dem textfuehrenden
               Eltern-DIV `.ab-zelle.ab-merkmal` liegt. Ohne diesen Kontext
               lieferte `elementFromPoint(iconCx, iconY ± 5)` die Elternzelle
               statt des Icons — die vertikale Slop-Region war faktisch
               wirkungslos (VRT-Befund 2026-05-11 C2). */
            isolation: isolate;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 1.4em;
            height: 1.4em;
            margin-left: 0.35em;
            padding: 0;
            /* Politur 2026-05-11 (i-Buttons transparent): Anwender-Wunsch —
               i-Buttons generell ohne eigenen Hintergrund. Glyph + Hand-
               Cursor tragen das visuelle Feedback. */
            background: transparent;
            color: rgba(255, 255, 255, 0.85);
            border: none;
            border-radius: 50%;
            /* Politur 2026-05-11 (M1b): Icon visuell verdoppelt — 0.85em → 1.7em
               Schrift, width/height von 1.4em skaliert mit auf ~27 px Visual
               (vorher ~14 px). Anwender meldete, dass das Icon zu klein zum
               Erkennen sei. Doppelte Schrift macht das ⓘ-Glyph deutlich
               sichtbar; bei `--row-data-h: 5rem` (80 px) und 30vw-Spalten
               (~112 px) bleibt im Layout genug Platz fuer Text + Icon. */
            font-size: 1.7em;
            line-height: 1;
            cursor: pointer;
            vertical-align: baseline;
        }
        /* Folgepatch 14a-1: Pseudoelement-Slop fuer 44-px-Tap-Target.
           Politur 2026-05-11 (M1b): Slop in max(em, rem)-Mix umgestellt, damit
           er bei Icon-font-size-Aenderungen nicht ueberproportional waechst —
           der absolute rem-Boden deckelt die em-Berechnung. Hitbox bleibt
           damit unabhaengig vom Icon-Visual-Faktor in einem stabilen Korridor
           (Visual + 2 × Slop): bei 1.7em-Icon ≈ 27 + 28 = 55 px vertikal,
           27 + 25 = 52 px horizontal — sicher ueber dem 44-px-AAA-Wert.
           Plus z-index: 1 im neuen Stacking-Kontext des Icons (siehe
           `isolation: isolate` oben) — Slop liegt im Hit-Test ueber der
           Eltern-Zelle, der vertikale Tap-Lift wirkt jetzt auch praktisch. */
        .ab-info-icon::before {
            content: '';
            position: absolute;
            top: max(-1.4em, -0.875rem);
            bottom: max(-1.4em, -0.875rem);
            left: max(-1.25em, -0.78125rem);
            right: max(-1.25em, -0.78125rem);
            z-index: 1;
        }
        .ab-info-icon:hover,
        .ab-info-icon:focus-visible {
            color: #fff;
        }
        .ab-info-icon:focus-visible {
            outline: 2px solid var(--accent, #A9F6DB);
            outline-offset: 2px;
        }
        /* Politur 2026-05-11 (Mini-Label-Truncate): Volltext-Button im Mini-
           Label. Spezifizitaet `.ab-info-icon.ab-info-icon-mini-label` (0,2,0)
           schlaegt die generische `.ab-info-icon`-Regel (0,1,0) im Mobile-
           Block. Default unsichtbar — JS-IIFE `tabelleMiniLabelTruncateSetup`
           setzt `.is-truncated`, sobald die Text-Span-Ellipsis gegriffen hat
           (`text.scrollWidth > text.clientWidth`). font-size kleiner als der
           generische 1.7em-Icon, weil das Mini-Label nur 0.8rem traegt —
           ein 1.7em-Button waere zu hoch fuer das schmale Banner. Hitbox-
           Slop entsprechend reduziert. background: transparent — Anwender-
           Wunsch 2026-05-11 (i-Buttons generell ohne eigenen Hintergrund);
           der ⓘ-Glyph plus Hand-Cursor traegt das visuelle Feedback. */
        .ab-info-icon.ab-info-icon-mini-label {
            display: none;
            /* Politur 2026-05-11 (Mini-Label-Truncate, Visual-Pass):
               font-size: 2em statt 1em — Anwender-Wunsch: i-Button im
               Mini-Label-Banner doppelt so gross, damit er in etwa die
               Groesse der Merkmal-Truncate-Buttons (`.ab-info-icon` Mobile,
               font-size: 1.7em an 0.85rem-Schrift) erreicht. width/height
               von 1.2em auf 1em reduziert — kompakterer Quad (25.6 × 25.6 px
               statt 30.7 × 30.7 px), Glyph fuellt die Box. Damit die Banner-
               Hoehe nur moderat (~30 px statt ~35 px) waechst und nicht zu
               sehr in den Werte-Bereich der Zelle ragt. */
            font-size: 2em;
            width: 1em;
            height: 1em;
            margin-left: 0;
            background: transparent;
            /* Politur 2026-05-11 (Mini-Label-Truncate, Visual-Pass): Idle-Color
               an die Mini-Label-Schriftfarbe `rgba(255,255,255,0.55)`
               (Regel .ab-mini-label weiter oben in dieser Datei)
               angeglichen — Anwender-Wunsch: der Button soll farblich nicht
               heller als der Label-Text wirken. Hover/Focus boostet weiter
               auf #fff als Feedback. */
            color: rgba(255, 255, 255, 0.55);
        }
        .ab-info-icon.ab-info-icon-mini-label.is-truncated {
            display: inline-flex;
        }
        .ab-info-icon.ab-info-icon-mini-label::before {
            /* Slop kleiner als generisches Icon — ~28 px Hitbox bei
               ~12 px Visual. Wert in max(em, rem) analog zu generischem
               Icon, aber etwa halbiert. Slop reicht weiter als die
               Banner-Hoehe, was OK ist: nur der Klick zaehlt, nicht das
               visuelle Pseudoelement. */
            top: max(-0.8em, -0.5rem);
            bottom: max(-0.8em, -0.5rem);
            left: max(-0.6em, -0.4rem);
            right: max(-0.6em, -0.4rem);
        }
        .ab-info-icon.ab-info-icon-mini-label:hover,
        .ab-info-icon.ab-info-icon-mini-label:focus-visible {
            color: #fff;
        }
        /* Politur 2026-05-20c: Mobile-Erscheinungsbild der oberen linken Ecke
           wird vom Meta-Strip uebernommen. Runder Desktop-Pos-Badge
           (.ab-pos-badge) und die Inland/Auslands-Pille (.ab-badge-pill)
           werden mobile ausgeblendet — der Strip vereint beide Aussagen
           (#NN-Nummer + Landesflagge) am Logo-Kopf. Vorher (Phase 14 A8 +
           Politur 2026-05-08f N3) war die Pille hier zu einer reinen
           Flag-Pille umformatiert; diese Doppelinformation entfaellt jetzt.
           Die Subgrid-Track-Hoehe der Badge-Reihe ist parallel ueber
           `--hdr-badge-h: 0px` (oben im Mobile-Variablen-Block) hoehenfrei;
           die Zelle selbst kollabiert hier zusaetzlich (padding 0,
           min-height 0, overflow hidden), damit kein blaues Restband
           zwischen Logo- und Zins-Reihe stehen bleibt. Inhalt der Pille
           per display: none inaktiv — die Inland/Ausland-Information
           wandert in den Strip.
           Containing-Block fuer den absoluten Strip ist .ab-zelle.ab-logo
           (position: sticky → bildet Containing-Block).
           pointer-events: none verhindert, dass der Strip Klicks auf den
           darunterliegenden .ab-logo-link blockiert. */
        .ab-zelle.ab-badge {
            padding: 0;
            min-height: 0;
            overflow: hidden;
        }
        .ab-pos-badge { display: none; }
        .ab-badge-pill { display: none; }

        .ab-meta-strip {
            display: flex;
            align-items: center;
            gap: 0.35em;
            position: absolute;
            top: 0.4em;
            left: 0.4em;
            z-index: 2;
            pointer-events: none;
            line-height: 1;
        }
        .ab-meta-pos {
            font-size: 0.7rem;
            font-weight: 600;
            color: rgba(255, 255, 255, 0.92); /* Kontrast-Politur 2026-06-12 (Schwester-Rollout): 0.6 -> 0.92 */
            letter-spacing: 0.02em;
            line-height: 1;
            font-variant-numeric: tabular-nums;
            /* Platz fuer "#NN" reservieren — bleibt auch bei Sport-Ranking-Tie
               (gleicher Zins wie Vorgaenger, $rang leer) erhalten, damit die
               Flagge in allen Spalten an derselben x-Position startet. Wert
               so gewaehlt, dass zweistellige Nummern sicher passen
               (`#99` ≈ 1.55em). */
            min-width: 1.7em;
            display: inline-block;
        }
        .ab-meta-flag {
            display: inline-flex;
            align-items: center;
            line-height: 1;
        }
        .ab-meta-flag .flag-img-variant {
            width: auto;
            height: 0.85rem;
        }
        .ab-meta-flag .flag-emoji-variant {
            font-size: 1.05rem;
            line-height: 1;
        }
        /* Folgepatch 14c: Bereichsbezeichnung mit Toggle in der ersten
           Anbieter-Spalte. Der Button wird in der .ab-gruppe-spacer-Reihe
           absolut positioniert (volle Viewport-Breite), nutzt dieselbe
           --mini-label-x-Variable wie das Mini-Label fuer den Sticky-Sync
           am linken Viewport-Rand. min-height an allen .ab-gruppe-spacer,
           damit die Subgrid-Reihe Platz fuer den Button reserviert (Subgrid
           uebernimmt die maximale Reihen-Hoehe ueber alle Anbieter-Spalten,
           also wirkt das min-height ueber alle drei sichtbaren Spalten). */
        .tabelle-grid .ab-gruppe-spacer {
            min-height: 2.5em;
        }
        .tabelle-grid > .anbieter-spalte:first-child .ab-gruppe-spacer {
            position: relative;
        }
        .tabelle-grid > .anbieter-spalte:first-child .mb-gruppentitel {
            display: flex;
            position: absolute;
            top: 0;
            left: 0;
            /* Politur 2026-05-10e: Breite an die tatsaechlich sichtbare
               Tabellen-Breite gebunden (siehe Kommentar an .ab-mini-label
               weiter oben). */
            width: var(--mini-label-w, calc(100vw - 0.5em));
            box-sizing: border-box;
            /* Politur 2026-05-11 (A): translate3d + backface-visibility analog
               zum .ab-mini-label-Block (siehe oben). Erzwingt eigene
               GPU-Compositor-Layer, sodass der Bereichsbezeichnungs-Toggle
               nicht hinter dem Touch-Scroll herhinkt. */
            transform: translate3d(var(--mini-label-x, 0px), 0, 0);
            backface-visibility: hidden;
            will-change: transform;
            /* Politur 2026-05-11 (Mini-Label-Truncate, Hit-Test-Fix):
               analog zum .ab-mini-label-Block — z-index 2 ueber den
               nachfolgenden Spalten-Geschwistern, damit der Bereichstitel-
               Toggle-Button im transformierten Banner-Bereich klickbar
               bleibt (Vorbeugung gegen den Stacking-Konflikt, den Anwender
               am Mini-Label-Volltext-Button gemeldet hat). */
            z-index: 2;
            /* z-index/translate3d sind die Sticky-Sync-Mechanik (Banner folgt
               dem Horizontal-Scroll). Padding und Chevron-Position liegen in
               der .mb-gruppentitel-Regel unten (space-between, padding-right
               5% — Chevron am rechten Banner-Rand). */
        }
        /* Politur 2026-05-13: Bereichstitel-Optik (Verzinsung/Merkmale)
           aus Screenshot uebernommen — Hintergrund auf transparent (der
           Default-Block oben liefert die Koernungs-Flaeche; transparent
           laesst sie durchscheinen). Redesign 2026-06-19: der fruehere
           gepunktete Fueller + Plus/Minus-Glyph ist durch den SVG-Chevron
           ersetzt (Markup + Default-Caret-Regel). Trennlinie zur vorigen
           Gruppe liefert jetzt die .ab-gruppe-spacer-Koernung (border-top);
           die Button-eigene Border bleibt hier ausgeschaltet, damit auf
           Mobile nur eine durchgehende Bandflaeche liest. */
        .tabelle-grid > .anbieter-spalte:first-child .mb-gruppentitel {
            background: transparent;
            border-top: none;
            border-bottom: none;
            /* Politur 2026-05-14 (Pass 1+2, Schwester-Sync zu Festgeld AT):
               Inneres Padding asymmetrisch — Pass 1 setzte 2.5%/2.5%
               (konsistent zur 2.5%-Site-Konvention `.result-count
               { padding-left: 2.5% }`, `.sort-buttons { margin-right:
               2.5% }`). Pass 2 nach Live-Verifikation: Anwender hat
               `padding-right: 5%` nachverlangt. `padding-left: 2.5%` bleibt
               — die Beschriftung sass schon richtig. Die Asymmetrie 2.5%/5%
               wirkt jetzt ueber den per space-between rechtsbuendigen Chevron
               (Default-Caret-Regel): der grosszuegigere Rechtsabstand haelt
               den Chevron etwas vom Banner-Rand weg. Prozentwerte beziehen
               sich auf die Banner-Breite (`--mini-label-w` =
               `min(scroller.clientWidth, grid.offsetWidth)`). */
            padding-left: 2.5%;
            padding-right: 5%;
        }
        /* Hover (2026-06-19b): Koernung bleibt unveraendert; der Chevron hellt
           auf (wie Desktop). Touch-Geraete zeigen kaum Hover. */
        .tabelle-grid > .anbieter-spalte:first-child .mb-gruppentitel:hover .vp-gruppentitel-caret {
            color: #BFDBEF;
        }
        /* Redesign 2026-06-19: Der fruehere Mobile-Transparent-Reset der
           .ab-gruppe-spacer ist entfallen — auf Mobile gilt jetzt dieselbe
           Koernungs-Flaeche wie auf Desktop (Default-Block oben), sodass das
           Band auch auf kleinen Displays als eigene Struktur liest. */
        /* Mobile-Chevron etwas groesser fuer bessere Tap-Sichtbarkeit auf
           kleinen Displays (Desktop nutzt die 15px aus dem SVG-Attribut). */
        .tabelle-grid > .anbieter-spalte:first-child .mb-gruppentitel .vp-gruppentitel-caret svg {
            width: 18px;
            height: 18px;
        }
    }
    /* Hover (Anwender-Wunsch 2026-06-19b/c): Die Koernungs-Flaeche bleibt
       UNVERAENDERT — kein Aufhellen, kein Schleier, keine Struktur-Aenderung.
       Den Hover-Zustand signalisiert allein der Chevron durch eine hellere
       Farbe (#6699CC -> #BFDBEF, weich ueber die color-Transition am Caret).
       Greift beim direkten VP-Button-Hover (:hover) UND wenn die ganze
       Bereichs-Zeile gehovert wird (.is-row-hover, von JS gesetzt — die
       Spacer-Zellen liegen in einem anderen DOM-Teilbaum als der Chevron). */
    /* Label: nimmt nur seine intrinsische Breite (flex: 0 1 auto); space-between
       am Button schiebt den Chevron an den rechten Rand.
       `min-width: 0` + `overflow-wrap: break-word` als Sicherheitsnetz: Edge/
       Chromium brechen Labels ohne interne Bruchstelle (z.B. "KONTOEROEFFNUNG")
       sonst nicht um — der Flex-Item-min-width-Default `auto` (= min-content)
       sperrt den Shrink unter die Wort-Breite, das Label wuerde den Chevron aus
       der Spalte druecken. Firefox bricht "AUSSCHUETTUNG/AUSZAHLUNG" bereits
       ueber `<wbr>` (Politur 19e); break-word greift dort nur als Last-Resort. */
    /* Chevron-Toggle (Redesign 2026-06-19, Handoff Variante 02): ein einzelner
       SVG-Chevron statt +/--Glyph und gepunktetem Leader (beide entfernt). Zeigt
       nach UNTEN wenn zugeklappt, rotiert um 180 Grad (zeigt nach OBEN) wenn
       offen. Gedaempftes Blau #6699CC statt Akzentgruen — bewusst zurueckhaltend
       ("weniger ins Auge fallen"). currentColor faerbt den SVG-Stroke. */
    /* Folgepatch 14c: Default Desktop — der Mobile-Toggle-Button (zweite
       Form/Button-Pair pro Gruppe in der ersten Anbieter-Spalte) ist
       unsichtbar. Mobile-Block schaltet ihn sichtbar. */
    /* Hoehen-Animation beim Auf-/Zuklappen (2026-06-19c): Akkordeon-Geste, damit
       erlebbar wird, WELCHER Bereich sich oeffnet/schliesst. Die Trigger-Klasse
       .gruppe-anim setzt toggleGruppe NUR fuer die Dauer des px-Tweens an
       .tabelle-grid UND .vp-spalte (beide tweenen synchron per CSS). Permanent
       darf die Transition nicht stehen, weil die Default-Track-Liste
       var(--tabelle-data-rows) `auto` enthaelt und `auto` nicht interpolierbar ist
       (sie wuerde springen). Laeuft parallel zum opacity-Soft-Fade (180 ms). */
    /* Hoehere Spezifitaet (0,3,0) als race.js' `.tabelle-scroller .tabelle-grid`
       (0,2,0): race injiziert sein `transition: opacity 180ms` per appendChild
       ans Kopf-Ende, also NACH dieser Datei, und gewaenne sonst den
       Spezifitaets-Gleichstand — da `transition` ein Shorthand ist, wuerde es
       die grid-template-rows-Transition KOMPLETT ersetzen (Hoehe spraenge statt
       zu tweenen, transitionend feuerte nie). opacity 180ms (= race FADE_MS)
       wird mitgefuehrt, damit ein Cross-Fade-Overlap die Opazitaets-Transition
       nicht verliert. */
    /* Band-Puls beim Klick (2026-06-19c): kurzer heller Inset-Schein auf dem
       geklickten Band (VP-Button + Spacer-Fortsetzung derselben Gruppe), damit
       sofort sichtbar ist, WELCHES Band reagiert hat. Bewusst als box-shadow
       UEBER der Koernungs-Textur statt background-Wechsel (der wuerde mit den
       radial-gradients konkurrieren). Die erste box-shadow-Komponente repliziert
       den bestehenden Inset-Sheen, damit er waehrend der Animation nicht
       wegblitzt. Feste rgba (Akzent #5fd4b8 @ 0.10) statt var() — der Live-Wert
       von --accent-light (#00ffcc) waere greller als gewuenscht. JS setzt
       .band-puls in toggleGruppe und entfernt sie per animationend/Timeout. */
    /* === Phase 4: Drag-to-Scroll, Snap, Mini-Scrollbar === */
    /* Mini-Scrollbar-Indikator (Frage 20 = C) */
    .tabelle-scrollbar-indikator {
        position: relative;
        height: 0.25em;
        margin: 0.5em 0.25em 0;
        background: rgba(255,255,255,0.08);
        border-radius: 999px;
        overflow: hidden;
        transition: opacity 150ms ease;
    }
    .tabelle-scrollbar-thumb {
        position: absolute;
        top: 0;
        left: var(--thumb-x, 0%);
        height: 100%;
        width: var(--thumb-width, 100%);
        background: rgba(255,255,255,0.6); /* Kontrast-Politur 2026-06-12 (Schwester-Rollout): 0.4 -> 0.6 */
        border-radius: inherit;
    }
    @media (hover: hover) and (pointer: fine) {
        .tabelle-scrollbar-thumb { transition: background 125ms ease; }
        .tabelle-scroller:hover ~ .tabelle-scrollbar-indikator .tabelle-scrollbar-thumb,
        .tabelle-scroller.is-dragging ~ .tabelle-scrollbar-indikator .tabelle-scrollbar-thumb {
            background: rgba(255,255,255,0.75); /* Kontrast-Politur 2026-06-12 (Schwester-Rollout): Hover mit angehoben */
        }
    }
    /* Politur 2026-05-11 (F): Scroll-Driven CSS Animations als Compositor-
       native Loesung fuer Mini-Label-/mb-gruppentitel-Sync auf Mobile.
       Wenn der Browser `animation-timeline: scroll()` unterstuetzt (Chromium
       115+, Firefox 130+, Samsung Internet 22+; iOS Safari noch nicht),
       uebernimmt eine scroll-driven Animation den horizontalen Sync. Die
       Animation laeuft auf dem Compositor-Thread und ist damit frame-genau,
       im Gegensatz zur JS-rAF-Loop, die auf dem Main-Thread laeuft und
       gegen Touch-Compositor um 1 Frame verzoegert ist. Browser ohne
       Support fallen auf die rAF-Loop (B) zurueck — JS-Feature-Detection
       (hasScrollTimeline) deaktiviert die Loop, wenn die Animation greift.

       Mathematik: scroll-timeline gibt einen Progress 0..1. Bei progress=0
       ist `from` (translate3d(0,0,0)), bei progress=1 ist `to`
       (translate3d(--scroll-max-x, 0, 0)). Progress = scrollLeft /
       scroll-max-x, daher Translation = scrollLeft — identisch zur
       rAF-Mechanik, aber Compositor-native.

       `--scroll-max-x` wird per IIFE (tabelleMiniLabelSetupIIFE/syncBreite)
       auf getEchtesMax(scroller) gesetzt; ResizeObserver haengt schon. */
    /* ============================================================
       Sticky-Mini-Header — extern, fixed-positioniert.
       Faedet beim Page-Scroll oben ein, sobald die echten Header-
       Reihen (Logo + Badge + Zins) oben aus dem Viewport scrollen,
       und faedet wieder aus, wenn der .tabelle-wrapper-Bottom unter
       den Viewport-Top kommt. JS-IIFE tabelleStickyMiniSetup setzt
       .is-active auf Basis getBoundingClientRect-Pruefungen.
       ScrollLeft-Sync: --mini-label-x wird vom Mini-Label-IIFE im
       .tabelle-scroller gesetzt und am .tabelle-wrapper gespiegelt,
       der Mini-Track erbt sie und uebernimmt sie als translate3d.
       Stolperstein 10 (Bounding-Box-Aufblaeh) ist hier irrelevant,
       weil der Mini-Header AUSSERHALB des .tabelle-scroller lebt und
       dessen scrollWidth nicht beeinflusst.
       ============================================================ */
    /* Politur 2026-05-12: Sticky-Mini-Header zeigt nur noch das Anbieterlogo —
       Zinssatz raus (Spalten-Identifikation reicht). Logo wird gedanklich
       rechtsbuendig in der Spalte ausgerichtet (align-items: flex-end an der
       Spalte + justify-content: flex-end im Logo-Wrap) — spiegelt die Position
       des Originallogos in .ab-zelle.ab-logo (flex-direction: column;
       align-items: flex-end). Logo-Hoehe (max-height: 6em) = 75 % der normalen
       Header-Logos (.ab-logo-wrap max-height 8em, Z. ~1197) — der Anwender
       wollte die Sticky-Logos kompakter, damit der Mini-Header beim Page-
       Scroll weniger Viewport blockiert. */
    .ab-mini-logo {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        max-height: 6em;
        max-width: 100%;
    }
    @media (max-width: 38em) {
        /* Mobile: VP-Spalte ist display:none — kein Container-Offset noetig
           (JS liefert vpBreitePx = 0). Mini-Spalten in der Breite des
           3-Anbieter-Mobile-Grids; column-gap muss zum Original-Grid passen
           (Z. ~1770) — sonst driften Mini-Spalten gegen Original-Spalten
           beim Horizontal-Scroll (~5.75 px/Spalte Versatz, vom visuellen
           Regressionstest 2026-05-11 detektiert).
           Politur 2026-05-12: font-size der Mini-Spalte auf 0.72rem (analog
           Mobile-`.ab-zelle`, Z. ~1785). Damit ergibt `max-height: 6em` am
           .ab-mini-logo die gleiche relativen Skalierung wie auf Desktop —
           ~69 px Logo-Hoehe (6 * 0.72rem). */
        .tabelle-sticky-mini-track {
            column-gap: 0.5em;
        }
        .anbieter-spalte-mini {
            font-size: 0.72rem;
            padding: 0.375em 0.4375em;
        }
    }


    /* Sonderzinsen — Balken-Indikator: Hoehe waechst (8px -> 13px) */
    .vergleich-dashboard .balken-toggle-bars-grow { align-items: flex-end; height: 0.8125em; margin-bottom: 0.0625em; }
    .vergleich-dashboard .balken-toggle-bars-grow .balken-toggle-bar {
        flex: none; width: 0.3125em; height: 0.5em; border-radius: 0.0625em;
        background: rgba(4,36,64,0.42); transition: height 0.2s ease, background 0.2s ease;
    }
    .vergleich-dashboard .balken-toggle[data-state="on"] .balken-toggle-bars-grow .balken-toggle-bar { height: 0.8125em; background: #DCEBF8; }


    @media (prefers-reduced-motion: reduce) {
        .vergleich-dashboard .balken-toggle-bar,
        .vergleich-dashboard .balken-toggle-arrow { transition: none; }
    }

    /* Touch-Geraete (kein Hover): Umschalt-Hinweis nicht einblenden, damit die
       Sprechblase nach dem Antippen nicht stehen bleibt. Maus-Hover und Tastatur-
       Fokus (:focus-visible) zeigen den Hinweis weiterhin. */
    @media (hover: none) {
        .vergleich-dashboard .balken-toggle[data-tooltip]:hover::after { opacity: 0; }
    }

    /* Mobile (gestapelt): groesserer Abstand ueber den Toggle-Baendern, optisch wie
       der Abstand zwischen Laufzeit- und Anlagebetrag-Band (ca. --space-lg). */
    @media (max-width: 48em) {
        .vergleich-dashboard .filter-section .sonderzins-filter-group,
        .vergleich-dashboard .filter-section .ausland-filter-group { margin-top: var(--space-sm); }
    }
    /* ── Europakarte (Länderfilter) ── */
    /* display:flex (column) ueberschreibt das auto-fit-Grid der zentralen .filter-row —
       sonst laegen .ek-kopf und .ek-spalten als Grid-Items nebeneinander. */
    /* Buehne: eine Nuance dunkler als das mittelblaue Panel (rgba(9,87,143)),
       aber bewusst NICHT navy-dunkel — der urspruengliche Handelsblatt-Ton war
       fuer die Seite zu dunkel (Anwender-Feedback 2026-07-07). min-height
       gibt der Karte (meet, zentriert) Raum, damit sie als Buehne wirkt.
       Full-Bleed (2026-07-09): margin -1.5em = horizontales Padding der
       .anpassen-panel — die Buehne laeuft bis an die Panelkante, nur der
       hell→dunkel→hell-Uebergang bleibt sichtbar; deshalb keine Rundung und
       keine Seiten-Border. Das horizontale Padding gleicht die 1.5em wieder
       aus, damit die Inhalte buendig zu den uebrigen Panel-Zeilen stehen. */
    .vergleich-dashboard .ek-sektion { position: relative; overflow: hidden; margin-left: -1.5em; margin-right: -1.5em; padding: var(--space-md) calc(var(--space-md) + 1.5em); background: linear-gradient(160deg, rgba(10,48,82,0.88), rgba(14,64,108,0.78)); border: 1px solid var(--border); border-left: 0; border-right: 0; min-height: 27em; display: flex; flex-direction: column; justify-content: center; }
    .ek-kopf { flex: 0 0 auto; }
    /* Karte liegt hinter den Spalten; Wrapper faengt keine Klicks, aber die
       Landflaechen/Marker schon — so klicken freie Flaechen zu den Checkboxen durch. */
    .ek-karte-wrap { position: absolute; inset: 0; z-index: 0; pointer-events: none; display: flex; align-items: center; justify-content: center; }
    .ek-karte-wrap svg { width: 100%; height: 100%; }
    .ek-karte-wrap .ek-land, .ek-karte-wrap .ek-marker { pointer-events: auto; }
    .ek-kopf, .ek-spalten { position: relative; z-index: 1; }
    /* Die vollbreiten Container fangen sonst Klicks im freien Korridor ab —
       durchlassen, nur ihre Inhalte (Pills, Zaehler, Glas-Spalten) fangen. */
    .ek-kopf, .ek-spalten { pointer-events: none; }
    .ek-kopf > *, .ek-spalten .filter-column { pointer-events: auto; }
    /* Karten-Zustaende (Land-Stroke = Buehnenfarbe, wirkt als Laendergrenze) */
    .ek-silhouette path { fill: rgba(255,255,255,0.07); }
    .ek-land { fill: rgba(255,255,255,0.2); stroke: rgba(10,48,82,0.9); stroke-width: .5; cursor: pointer; transition: fill var(--transition-base), filter var(--transition-base); }
    .ek-land.ek-gewaehlt { fill: var(--primary); filter: drop-shadow(0 0 6px rgba(0,112,192,0.55)); }
    .ek-land:not(.ek-gesperrt):not(.ek-gewaehlt):hover { fill: rgba(0,112,192,0.45); }
    .ek-land.ek-gesperrt { fill: rgba(255,255,255,0.02); cursor: default; }
    .ek-marker { fill: rgba(255,255,255,0.14); stroke: rgba(255,255,255,0.55); stroke-width: .5; cursor: pointer; transition: fill var(--transition-base), filter var(--transition-base); }
    .ek-marker.ek-gewaehlt { fill: var(--primary); filter: drop-shadow(0 0 6px rgba(0,112,192,0.55)); }
    .ek-marker:not(.ek-gesperrt):not(.ek-gewaehlt):hover { fill: rgba(0,112,192,0.45); }
    .ek-marker.ek-gesperrt { fill: rgba(255,255,255,0.05); cursor: default; }
    /* Sanfter Puls beim Zustandswechsel (JS setzt .ek-pop kurz) */
    @keyframes ekPop { 0% { opacity: .55; } 100% { opacity: 1; } }
    .ek-pop { animation: ekPop 250ms ease; }
    /* Kopf: nur noch Schnellauswahl + Zaehler. Der Gruppen-Umschalter liegt
       nicht mehr hier, sondern auf den Glas-Karten selbst (.ek-spalte) —
       die aktive Karte zeigt, was die Karte gerade darstellt. */
    .ek-kopf { display: flex; flex-wrap: wrap; gap: .5em .75em; margin-bottom: .75em; align-items: center; }
    .ek-presets { display: inline-flex; flex-wrap: wrap; gap: .3em; align-items: center; }
    .ek-presets-label { color: var(--text-secondary); font-size: .75em; margin-right: .2em; }
    .ek-preset-btn {
        cursor: pointer; font: inherit; font-size: .75em;
        padding: .3em .85em; border-radius: 1.4em; color: rgba(255,255,255,0.85);
        background: transparent; border: 1px solid rgba(255,255,255,0.3);
        transition: background var(--transition-base), border-color var(--transition-base);
    }
    .ek-preset-btn:hover { background: rgba(169,246,219,0.25); border-color: rgba(169,246,219,0.5); }
    .ek-zaehler { color: var(--text-secondary); font-size: .85em; margin-left: auto; align-self: center; }
    /* Checkbox-Spalten als Glas ueber der Karte */
    /* Mittel-Korridor zwischen den Spalten: die Karte (meet, zentriert) wird
       dort sichtbar — Kerneuropa liegt genau in der Mitte. */
    .ek-spalten { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: clamp(2em, 24%, 16em); row-gap: var(--space-md); }
    /* Bewusst duenn (Alpha .26, blur 1px), damit die Karte durchscheint. */
    .ek-spalten .filter-column { background: rgba(10,48,82,0.26); backdrop-filter: blur(1px); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: .75em; }
    /* Die Karten SIND der Gruppen-Umschalter: ganze Flaeche aktivierbar.
       Aktiv-Markierung = dasselbe Muster wie die gewaehlte Laufzeit im
       "alle Zinsen"-Tab (.zins-item.highlight): Akzent-Border + transparente
       Akzentflaeche. */
    .ek-spalte { cursor: pointer; transition: background var(--transition-base), border-color var(--transition-base); }
    .ek-spalte:not(.ek-spalte-aktiv):hover { border-color: rgba(255,255,255,0.35); }
    .ek-spalten .ek-spalte-aktiv { background: rgba(169,246,219,0.15); border-color: var(--accent); }
    /* Karten-Titel als echter Button (Tastatur-Zugang zum Umschalten),
       optisch unveraendert — der .filter-label-Span behaelt den zentralen Stil. */
    .ek-spalte-kopf { display: block; width: 100%; background: none; border: none; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }
    /* Glas-Karten trennen sich selbst — zentrale Separator-Raender/-Margins neutralisieren
       (die frueheren .filter-row-separator[style]-Regeln greifen ohne Inline-style nicht mehr). */
    .ek-spalten .filter-column-separator { margin: 0; }
    /* Tooltip */
    .ek-tooltip { position: absolute; z-index: 2; pointer-events: none; background: rgba(10,37,64,0.92); color: #fff; padding: .3em .6em; border-radius: .4em; font-size: .8em; white-space: nowrap; opacity: 0; transition: opacity 150ms ease; }
    .ek-tooltip.ek-sichtbar { opacity: 1; }
    /* Tablet-Zwischenbereich (50–64em): die Tafeln sind wegen des Karten-
       Korridors schmal — Checkboxen einspaltig, sonst laeuft das zentrale
       repeat(2,1fr)-Grid ueber den Tafelrand (VRT-Befund 2026-07-07). */
    /* Untere Kante 50.01em statt 50em (Audit A-7.2 / Phase K6, Rollout Tagesgeld
       CT-0148 2026-08-26): exakt 800px traf sonst diesen Block UND den
       `max-width: 50em`-Block darunter gleichzeitig. */
    @media (min-width: 50.01em) and (max-width: 64em) {
        .ek-spalten .checkbox-group-wrap { grid-template-columns: 1fr; }
    }
    /* Schmale Viewports: Spalten untereinander, Karte wird dezente Textur.
       Gleicher Breakpoint wie die alte Sitz-Zeile (50em). */
    @media (max-width: 50em) {
        .ek-spalten { grid-template-columns: 1fr; }
        .ek-karte-wrap { opacity: .18; }
    }

    /* === Hochkontrast-Hell-Modus ============================================
       Aktiv nur bei #vergleich.kontrast-hell. ALLE Overrides per Spezifitaet ueber den
       ID+Klasse-Praefix (schlaegt vergleich.min.css/tabelle.min.css) — NIE !important,
       em-Konvention (px nur border-width/box-shadow/outline/gradient/@media), keine
       Geometrie-/transform-Aenderung (FLIP unberuehrt), G1-Heatmap-Logik unveraendert
       (nur Farben). Akzente konsequent Blau statt Tuerkis/Gruen. Bewusste Ausnahmen:
       (1) die drei Kopf-Baender (Logo / Inland-Ausland-Badge / Zins) bleiben Marken-Blau
       (rgba(9,87,143,0.92)) wie im Dunkelmodus, damit die hellen Anbieterlogos/Pillen/
       Zinsbalken lesbar bleiben; Schrift dort weiss. (2) Die Europakarte-Buehne im
       Filter-Panel bleibt bewusst dunkel (Anwender-Entscheidung 2026-07-09) — Overrides
       am Ende dieses Blocks setzen die durchschlagenden Hell-Werte dort lokal zurueck.

       --- Toggle-Button (in BEIDEN Modi sichtbar; Basis = Dunkel-Standardansicht).
       .kontrast-zeile = hoehenloser Anker (Markup AUSSERHALB der Partial-Swap-Zone
       zwischen #hilfe und Dashboard), kostet keine Zeilenhoehe.
       Rollout 2026-08-18 (Phase 2, Muster aus der Listenansicht): Kontrast-Toggle und
       "weitere Filter"-Button bilden EINE Zeile auf der "Anlagebetrag"-Label-Zeile.
       Desktop (>72em): beide in Kachelgroesse der View-Switcher-Icons
       (2.51em x 2.09em = 34x28px) und buendig darunter — Kontrast unter der
       Seitenhilfe (rechtestes #hilfe-Icon), Filter unter der kreativen Ansicht
       (zweitrechtes). Bezugsgroesse der Kalibrierung ist die Icon-MITTE; die
       calc()-%-Anteile sind gegen die Live-Geometrie gemessen (1200/1366/1500/1920,
       Abweichung < 0.10px). Anker-Geometrie ist in Liste, Tabelle und kreativer
       Ansicht identisch — die Konstanten sind produktweit dieselben.
       z-index 1: ueber statischem Label, unter den Sticky-Baendern. --- */
    #vergleich .kontrast-zeile {
        display: block; position: relative;
        height: 0; margin: 0; overflow: visible;
        z-index: 1;
    }
    #vergleich .kontrast-toggle {
        position: absolute; right: calc(0.405% + 1.43em); top: 0.98em;
        width: 2.51em; height: 2.09em; padding: 0;
        display: inline-flex; align-items: center; justify-content: center;
        font-size: 0.85rem; font-weight: 600; line-height: 1.2;
        letter-spacing: 0.02em; color: #e8f2fb;
        background: rgba(9,87,143,0.62); box-shadow: 0 0.125em 0.5em rgba(0,0,0,0.25);
        border: 0; border-radius: 0; cursor: pointer;
        white-space: nowrap; -webkit-tap-highlight-color: transparent;
        transition: background 150ms ease, color 150ms ease;
    }
    #vergleich .kontrast-toggle:hover { background: rgba(13,110,175,0.96); color: #fff; }
    #vergleich .kontrast-toggle:focus-visible { outline: 2px solid #DFFDF2; outline-offset: 0.125em; }
    #vergleich .kontrast-toggle[aria-pressed="true"] { background: rgba(9,87,143,0.62); color: #fff; }
    #vergleich .kontrast-toggle .kontrast-icon { font-size: 1.05em; line-height: 1; }
    /* Eck-Winkel (Markup-Spans) — Form/Hintergrund/Schatten/Ecken wie der anpassen-filter-btn. */
    #vergleich .kontrast-toggle .ecke { position: absolute; width: 0.7em; height: 0.7em; pointer-events: none; }
    #vergleich .kontrast-toggle .ecke-tl { top: 0.22em; left: 0.22em; border-top: 2px solid #A9F6DB; border-left: 2px solid #A9F6DB; }
    #vergleich .kontrast-toggle .ecke-tr { top: 0.22em; right: 0.22em; border-top: 2px solid #A9F6DB; border-right: 2px solid #A9F6DB; }
    #vergleich .kontrast-toggle .ecke-bl { bottom: 0.22em; left: 0.22em; border-bottom: 2px solid #A9F6DB; border-left: 2px solid #A9F6DB; }
    #vergleich .kontrast-toggle .ecke-br { bottom: 0.22em; right: 0.22em; border-bottom: 2px solid #A9F6DB; border-right: 2px solid #A9F6DB; }

    /* "weitere Filter"-Button: aus der .filter-section auf die Kontrast-Zeile
       umgezogen (DOM: erstes Dashboard-Kind, bleibt in der Partial-Swap-Zone,
       damit der Badge serverseitig aktuell mitgerendert wird). Overrides
       schlagen die zentrale vergleich.min.css per #vergleich-Praefix —
       die min.css selbst bleibt unveraendert (gilt fuer alle Produkte). */
    #vergleich .vergleich-dashboard { position: relative; }
    /* top koppelt an den Toggle-top (gleicher em-Wert) und kompensiert den
       Dashboard-margin-top per var(--space-md/-sm) — so bleibt die Zeile
       auch bei Text-Zoom und einer Aenderung der Space-Token deckungsgleich.
       Der Abstand .kontrast-zeile -> Dashboard-Oberkante ist live als exakt
       var(--space-md) (16px) bzw. var(--space-sm) (8px) gemessen. */
    #vergleich .anpassen-filter-btn {
        bottom: auto; top: calc(0.98em - var(--space-md)); right: calc(7.19em - 0.583%);
        width: 2.51em; height: 2.09em; font-size: 0.85rem;
    }
    #vergleich .anpassen-filter-btn .icon-wrap .icon-sliders { font-size: 1.05em; }
    #vergleich .anpassen-filter-btn .ecke { width: 0.7em; height: 0.7em; }
    #vergleich .anpassen-filter-btn .ecke-tl { top: 0.22em; left: 0.22em; }
    #vergleich .anpassen-filter-btn .ecke-tr { top: 0.22em; right: 0.22em; }
    #vergleich .anpassen-filter-btn .ecke-bl { bottom: 0.22em; left: 0.22em; }
    #vergleich .anpassen-filter-btn .ecke-br { bottom: 0.22em; right: 0.22em; }
    /* <=72em: #hilfe-Leiste sitzt im Seitenkopf, keine Icon-Buendigkeit
       moeglich — Zeile rechtsbuendig auf Label-Mitte wie die fruehere
       Toggle-Position, Filter-Button mit Luecke links daneben (right so
       bemessen, dass auch der Aktiv-Badge samt 2px-Ring nicht an den
       Kontrast-Toggle stoesst). */
    @media (max-width: 72em) {
        #vergleich .kontrast-toggle { top: 0.97em; right: 0.85em; }
        #vergleich .anpassen-filter-btn { top: calc(0.97em - var(--space-md)); right: 3.92em; }
    }
    /* Mobil (h1 via style.css ab 38em ausgeblendet -> Anker rutscht an den Kartenanfang).
       Nach oben ist kein Raum (Kartenkante), deshalb entsteht die Luft zur Pill-Reihe
       im Fluss: mehr padding-top schiebt Label+Pills nach unten, die absolut
       verankerten Buttons bleiben oben stehen. */
    @media (max-width: 38em) {
        #vergleich .kontrast-toggle { top: 0.4em; right: 0.6em; }
        #vergleich .anpassen-filter-btn { top: calc(0.4em - var(--space-sm)); right: 4.13em; }
        #vergleich .vergleich-dashboard { padding-top: calc(var(--space-sm) + 0.5rem); }
    }

    /* ===== Ebene A — Flaeche (weisse Karte auf blauem Seitenhintergrund) =====
       Geometrie exakt wie die Dunkel-Basis (style.css #vergleich padding:0 0 .9em, kein
       umlaufender Rahmen) — Umschalten darf NICHTS verschieben; Karten-Rahmen als
       layout-neutraler box-shadow-Ring statt border. KEINE transition (Rundung faedete). */
    #vergleich.kontrast-hell {
        background: #F7F9FC; color: #111;
        padding: 0 0 0.9em; border-radius: 0.5em;
        box-shadow: 0 0 0 1px rgba(0,82,141,0.20), 0 0.5em 2em rgba(0,0,0,0.12);
    }
    #vergleich.kontrast-hell h1 { color: #00385f; border-top-color: transparent; }
    /* Diagrammansicht-Icon (SVG statt Icon-Font) — modus-UNABHAENGIGER Reset gegen
       die unscopten .icon-Regeln aus style.css (font-size:3em, position:absolute).
       Steht hier bei den uebrigen #hilfe-Regeln; die Farbe kommt per currentColor
       aus den #hilfe .icon-Regeln, also auch im Hochkontrast-Hell-Modus korrekt.
       position MUSS relative sein, nicht static: style.css vergroessert die
       Tap-Targets mit "a > .icon::after { position:absolute; inset:-5px }".
       Bei static faellt der Bezugsrahmen dieses ::after auf einen Vorfahren
       zurueck — die unsichtbare Trefferflaeche wird ~330px breit und verdeckt
       die Nachbar-Icons (live gemessen 18.07.2026: Tabellen- und Listen-Icon
       oberhalb 72em nicht mehr klickbar). relative behaelt die Position im
       Fluss und stellt den Bezugsrahmen wieder her. */
    #hilfe .zg-view-icon { display: block; position: relative; margin: 0 auto; width: 1.3em; line-height: 1; font-size: 1.85em; }
    #hilfe .zg-view-icon svg { width: 1.3em; height: 0.91em; vertical-align: -0.08em; display: inline-block; }
    /* AT hat NUR EINE Stufe (Umschaltpunkt exakt 72em, live gemessen 18.07.2026):
       vergleich.min.css v16 schaltet die #hilfe-Icons dort von 28.416px auf 18.432px.
       Die DE-Fassung (v18) hat zusaetzlich eine 88em-Stufe — die ist hier bewusst
       NICHT portiert: sie wuerde im Band 1153-1408px feuern, wo die Fontello-Nachbarn
       noch gross sind, und unser Icon dort sichtbar zu klein machen. Nicht ergaenzen. */
    @media only screen and (max-width: 72em) { #hilfe .zg-view-icon { font-size: 1.2em; position: relative; margin: 0; } }

    /* Ansichts-Icons der Kopfleiste (Listen-/Tabellen-/Diagramm-/Hilfe-Icon):
       dunkles Blau NUR oberhalb 72em, wo #hilfe auf der weissen Karte liegt.
       Ab 72em abwaerts zieht style.css #hilfe ins blaue Kopf-Band (#09578f) —
       dort waren die Icons blau auf blau und praktisch unsichtbar (live gemessen
       11.08.2026: #00528D auf #09578f). Unterhalb 72em gelten deshalb wieder die
       Basis-Mintfarben; der 38em-Block weiter unten haelt sie zusaetzlich fest. */
    @media only screen and (min-width: 72.01em) {
        #vergleich.kontrast-hell #hilfe .icon { color: #00528D; }
        #vergleich.kontrast-hell #hilfe .current .icon { color: #003A66; }
        #vergleich.kontrast-hell #hilfe a:hover .icon, #vergleich.kontrast-hell #hilfe a:focus .icon { color: #0070C0; }
    }

    /* Toggle-Button im Hell-Modus — weisser Grund, blauer Schatten, blaue Eck-Winkel */
    #vergleich.kontrast-hell .kontrast-toggle { color: #00528D; background: #F7F9FC; box-shadow: 0 0.125em 0.5em rgba(0,82,141,0.25); }
    #vergleich.kontrast-hell .kontrast-toggle:hover { background: rgba(0,112,192,0.14); color: #003A66; }
    #vergleich.kontrast-hell .kontrast-toggle:focus-visible { outline-color: #0070C0; }
    #vergleich.kontrast-hell .kontrast-toggle[aria-pressed="true"] { background: #F7F9FC; color: #003A66; }
    #vergleich.kontrast-hell .kontrast-toggle .ecke-tl { border-top-color: #0070C0; border-left-color: #0070C0; }
    #vergleich.kontrast-hell .kontrast-toggle .ecke-tr { border-top-color: #0070C0; border-right-color: #0070C0; }
    #vergleich.kontrast-hell .kontrast-toggle .ecke-bl { border-bottom-color: #0070C0; border-left-color: #0070C0; }
    #vergleich.kontrast-hell .kontrast-toggle .ecke-br { border-bottom-color: #0070C0; border-right-color: #0070C0; }

    /* ===== Ebene B — Variablen-Override (.vergleich-dashboard); AAA >= 7:1 Fliesstext.
       secondary rgba(0,0,0,0.88) ~15:1, muted #404040 ~10,4:1. ===== */
    #vergleich.kontrast-hell .vergleich-dashboard {
        --primary: #0070C0; --primary-dark: #00528D; --primary-darker: #003A66;
        --accent: #00528D; --accent-light: #0070C0;
        --bg-card: rgba(0,82,141,0.05); --bg-card-hover: rgba(0,82,141,0.10);
        --border: rgba(0,82,141,0.30); --border-light: rgba(0,82,141,0.14);
        --text-primary: #111; --text-secondary: rgba(0,0,0,0.88); --text-muted: #404040;
        background: #F7F9FC;
    }

    /* ===== Ebene C — hartkodierte Farben uebersteuern ===== */

    /* -- Sticky-VP-Spalte (Merkmal-Labels) hell, blaue Trennkante -- */
    #vergleich.kontrast-hell .vp-spalte { background: #F7F9FC; border-right-color: rgba(0,82,141,0.28); box-shadow: 0.25em 0 0.5em rgba(0,82,141,0.10); }
    #vergleich.kontrast-hell .vp-zelle { color: #003A66; background: #F7F9FC; }
    #vergleich.kontrast-hell .vp-zelle, #vergleich.kontrast-hell .ab-zelle { border-bottom-color: rgba(0,82,141,0.12); }
    #vergleich.kontrast-hell .ab-merkmal.ab-leer { color: rgba(0,0,0,0.65); }

    /* -- Kopf-Baender (Logo / Inland-Ausland-Badge / Zins): bewusste Marken-Blau-Ausnahme.
          Die drei Header-Reihen behalten ihren rgba(9,87,143,0.92)-Grund (deckt die weisse
          Karte, bleibt ein blaues Band). Schrift, die sonst per Ebene-B auf #111 kippen
          wuerde (Anbietername, Zinszahl), explizit weiss halten. Badge-Pille + Zins-Balken-
          Fuellung tragen eigene min.css-Farben (fuer das blaue Band gebaut) -> unveraendert. -- */
    #vergleich.kontrast-hell .ab-anbieter { color: #fff; }
    #vergleich.kontrast-hell .ab-zelle.ab-zins { color: #fff; }

    /* -- Chart-Glyph (icon-chart-area, 'gueltig'-Feld): Tuerkis -> Blau (Ruhe/Fokus #00528D,
          Hover #0070C0), analog zur Listen-Schwester. -- */
    #vergleich.kontrast-hell .ab-merkmal-html .icon-chart-area,
    #vergleich.kontrast-hell .ab-merkmal-html .iframe .icon-chart-area { color: #00528D; }
    #vergleich.kontrast-hell .ab-merkmal-html a:hover > .icon-chart-area { color: #0070C0; }

    /* -- Geschenk-Icon (cardgift-g.svg, Bonus-Reihe): Tuerkis -> Marken-Hellblau via
          Filterkette (brightness(0) macht sie quellfarben-unabhaengig). Eigener Hover, weil
          der Basis-Hover (brightness/saturate) den Filter sonst ersetzt. -- */
    #vergleich.kontrast-hell .ab-merkmal-html a.cardgifta img {
        filter: brightness(0) saturate(100%) invert(26%) sepia(98%) saturate(946%) hue-rotate(176deg) brightness(110%) contrast(113%);
    }
    #vergleich.kontrast-hell .ab-merkmal-html a.cardgifta:hover img {
        filter: brightness(0) saturate(100%) invert(26%) sepia(98%) saturate(946%) hue-rotate(176deg) brightness(110%) contrast(113%) brightness(125%);
    }

    /* -- Sonderzins-/Ausland-Balken-Toggles (Einstellungsleiste): State-Text (#F1F6FC) und
          Pfeil (#DCEBF8) sind near-white -> auf der weissen Karte unlesbar. Text/Pfeil blau;
          leere Balken (rgba(4,36,64,0.42), dunkel) bleiben lesbar, gefuellte Balken
          (#DCEBF8, near-white) -> Blau. -- */
    #vergleich.kontrast-hell .vergleich-dashboard .balken-toggle-state { color: #003A66; }
    #vergleich.kontrast-hell .vergleich-dashboard .balken-toggle-arrow { color: #00528D; }
    #vergleich.kontrast-hell .vergleich-dashboard .balken-toggle[data-state="on"] .balken-toggle-bars-grow .balken-toggle-bar,
    #vergleich.kontrast-hell .vergleich-dashboard .balken-toggle[data-state="on"] .balken-toggle-bars-dash .balken-toggle-bar,
    #vergleich.kontrast-hell .vergleich-dashboard .balken-toggle[data-state="off"] .balken-toggle-bars-dash .balken-toggle-bar:nth-child(-n+8) { background: #0070C0; }

    /* -- Heatmap (Top-3 Rendite): Tuerkis -> Blau-Tints; G1-Logik unveraendert -- */
    #vergleich.kontrast-hell .vergleich-dashboard .ab-zelle.ab-merkmal.heatmap-1 { background: rgba(0,112,192,0.16); }
    #vergleich.kontrast-hell .vergleich-dashboard .ab-zelle.ab-merkmal.heatmap-2 { background: rgba(0,112,192,0.10); }
    #vergleich.kontrast-hell .vergleich-dashboard .ab-zelle.ab-merkmal.heatmap-3 { background: rgba(0,112,192,0.05); }

    /* -- Footer-CTA-Reihe / Disclaimer / Empty-State -- */
    #vergleich.kontrast-hell .vp-zelle.vp-footer { background: #F7F9FC; border-top-color: rgba(0,82,141,0.15); color: #003A66; }
    #vergleich.kontrast-hell .ab-zelle.ab-cta { border-top-color: rgba(0,82,141,0.15); }
    #vergleich.kontrast-hell .tabelle-disclaimer { color: #404040; }
    #vergleich.kontrast-hell .tabelle-empty-state, #vergleich.kontrast-hell .tabelle-keine-ergebnisse { color: #111; }
    #vergleich.kontrast-hell .vergleich-dashboard .footer-line a { color: #00528D; }
    #vergleich.kontrast-hell .vergleich-dashboard .footer-line a:hover { color: #0070C0; }

    /* -- CTA-Button "Zum Anbieter": Basis background:var(--accent)+color:var(--primary-darker)
          -> mit Ebene-B-Remap dunkelblau-auf-dunkelblau. Explizit: blaue Fuellung, weisse
          Schrift; Pfeil-Chip invertiert. -- */
    #vergleich.kontrast-hell .vergleich-dashboard .anbieter-link { background: #0070C0; color: #fff; }
    #vergleich.kontrast-hell .vergleich-dashboard .anbieter-link:hover { background: #00528D; }
    #vergleich.kontrast-hell .vergleich-dashboard .anbieter-link .link-arrow { background: #F7F9FC; color: #00528D; }

    /* -- Fussnoten (tabelle.min.css: hartkodiert Weiss-Text + Tuerkis-Links) -- */
    #vergleich.kontrast-hell .tabelle-fussnoten { background: rgba(0,82,141,0.05); color: #333; }
    #vergleich.kontrast-hell .tabelle-fussnoten li strong { color: #111; }
    #vergleich.kontrast-hell .tabelle-fussnoten a { color: #00528D; }
    #vergleich.kontrast-hell .tabelle-fussnoten a:hover { color: #0070C0; }

    /* -- Gruppen-Titel-Baender (Koernung) hell-blau statt Schwarz/Weiss-Transparenz -- */
    #vergleich.kontrast-hell .ab-gruppe-spacer, #vergleich.kontrast-hell button.vp-gruppentitel {
        background-color: rgba(0,82,141,0.06);
        background-image: radial-gradient(circle, rgba(0,82,141,0.10) 0 0.7px, transparent 1.1px);
        border-top-color: rgba(0,82,141,0.16); border-bottom-color: rgba(0,82,141,0.10);
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.6);
    }
    #vergleich.kontrast-hell button.vp-gruppentitel { color: #00528D; }
    #vergleich.kontrast-hell .vp-gruppentitel-caret { color: #00528D; }
    #vergleich.kontrast-hell button.vp-gruppentitel:hover .vp-gruppentitel-caret,
    #vergleich.kontrast-hell button.vp-gruppentitel.is-row-hover .vp-gruppentitel-caret { color: #0070C0; }

    /* -- Einstellungsleiste: Anlagebetrag-Pills + Beschriftungen (aktive Pill nutzt
          background:var(--text-primary) -> im Hell-Modus #111; darum explizit blau/weiss). -- */
    #vergleich.kontrast-hell .vergleich-dashboard .laufzeit-nav { background: rgba(0,82,141,0.06); }
    #vergleich.kontrast-hell .vergleich-dashboard .laufzeit-pill { color: #003A66; }
    #vergleich.kontrast-hell .vergleich-dashboard .laufzeit-pill:hover { background: rgba(0,82,141,0.08); color: #003A66; }
    #vergleich.kontrast-hell .vergleich-dashboard .laufzeit-pill.active { background: #0070C0; color: #fff; }
    #vergleich.kontrast-hell .vergleich-dashboard .filter-label,
    #vergleich.kontrast-hell .vergleich-dashboard .filter-column-title { color: #003A66; }

    /* -- "weitere Filter"-Button (Floating): dunkelblau/tuerkis -> Weiss + Blau -- */
    #vergleich.kontrast-hell .anpassen-filter-btn { background: #F7F9FC; box-shadow: 0 0.125em 0.5em rgba(0,82,141,0.25); }
    #vergleich.kontrast-hell .anpassen-filter-btn:hover, #vergleich.kontrast-hell .anpassen-filter-btn.open { background: rgba(0,112,192,0.14); }
    #vergleich.kontrast-hell .anpassen-filter-btn:focus-visible { outline-color: #0070C0; }
    #vergleich.kontrast-hell .anpassen-filter-btn .ecke-tl { border-top-color: #0070C0; border-left-color: #0070C0; }
    #vergleich.kontrast-hell .anpassen-filter-btn .ecke-tr { border-top-color: #0070C0; border-right-color: #0070C0; }
    #vergleich.kontrast-hell .anpassen-filter-btn .ecke-bl { border-bottom-color: #0070C0; border-left-color: #0070C0; }
    #vergleich.kontrast-hell .anpassen-filter-btn .ecke-br { border-bottom-color: #0070C0; border-right-color: #0070C0; }
    #vergleich.kontrast-hell .anpassen-filter-btn .icon-wrap .icon-sliders { color: #00528D; }
    #vergleich.kontrast-hell .anpassen-badge { background: #0070C0; color: #fff; }

    /* -- Filter-Overlay-Panel: dunkelblau -> weisses Panel, blauer Rahmen; Backdrop bleibt -- */
    #vergleich.kontrast-hell .anpassen-panel {
        background: #F7F9FC; border-color: rgba(0,82,141,0.35);
        box-shadow: 0 0.5em 2.5em rgba(0,0,0,0.25), 0 0.125em 0.5em rgba(0,0,0,0.15);
    }
    #vergleich.kontrast-hell .filter-panel-titel { color: #00528D; border-bottom-color: rgba(0,82,141,0.18); }
    #vergleich.kontrast-hell .anpassen-panel .filter-gruppe { border-top-color: rgba(0,82,141,0.12); }
    #vergleich.kontrast-hell .anpassen-panel .eingrenzungsfilter { border-top-color: rgba(0,82,141,0.12); }
    #vergleich.kontrast-hell .filter-checkbox { color: #333; }
    #vergleich.kontrast-hell .filter-checkbox:hover { color: #003A66; }
    #vergleich.kontrast-hell .vergleich-dashboard .filter-checkbox input[type="checkbox"] { border-color: rgba(0,82,141,0.5); background: #F7F9FC; }
    #vergleich.kontrast-hell .vergleich-dashboard .filter-checkbox input[type="checkbox"]:hover { border-color: #0070C0; }
    #vergleich.kontrast-hell .vergleich-dashboard .filter-checkbox input[type="checkbox"]:checked { background: #0070C0; border-color: #0070C0; }
    #vergleich.kontrast-hell .filter-checkbox input[type="checkbox"]:focus-visible { outline-color: #0070C0; }
    #vergleich.kontrast-hell .panel-close-btn { background: rgba(0,82,141,0.10); color: #00528D; }
    #vergleich.kontrast-hell .panel-close-btn:hover, #vergleich.kontrast-hell .panel-close-btn:focus { background: rgba(0,82,141,0.18); color: #003A66; }

    /* -- Pager (Skala/Chevrons): Tuerkis -> Blau -- */
    #vergleich.kontrast-hell .tabelle-pager-range { color: #111; }
    #vergleich.kontrast-hell .tabelle-pager-bereich, #vergleich.kontrast-hell .tabelle-pager-bereich strong { color: #00528D; }
    #vergleich.kontrast-hell .tabelle-pager-rest { color: #333; }
    #vergleich.kontrast-hell .tabelle-pager-btn { color: #0070C0; }
    #vergleich.kontrast-hell .tabelle-pager-btn:not(:disabled):hover, #vergleich.kontrast-hell .tabelle-pager-btn:focus-visible { color: #00528D; }
    #vergleich.kontrast-hell .tabelle-pager-btn:focus-visible { outline-color: #0070C0; }
    #vergleich.kontrast-hell .tabelle-pager-track::before { background: repeating-linear-gradient(90deg, rgba(0,82,141,0.20) 0 1px, transparent 1px 11px), rgba(0,82,141,0.08); }
    #vergleich.kontrast-hell .tabelle-pager-track:focus-visible { outline-color: #0070C0; }
    #vergleich.kontrast-hell .tabelle-pager-fenster { background: rgba(0,112,192,0.18); border-color: #0070C0; }

    /* -- Scroll-Indikator / native Scrollbar / Scroll-Fade-Kanten: Weiss -> Blau -- */
    #vergleich.kontrast-hell .tabelle-scrollbar-indikator { background: rgba(0,82,141,0.10); }
    #vergleich.kontrast-hell .tabelle-scrollbar-thumb { background: rgba(0,82,141,0.55); }
    #vergleich.kontrast-hell .tabelle-scroller.is-dragging ~ .tabelle-scrollbar-indikator .tabelle-scrollbar-thumb { background: rgba(0,82,141,0.75); }
    #vergleich.kontrast-hell .tabelle-scroller { scrollbar-color: rgba(0,82,141,0.55) rgba(0,82,141,0.10); }
    #vergleich.kontrast-hell .tabelle-scroller::-webkit-scrollbar-track { background: rgba(0,82,141,0.10); }
    #vergleich.kontrast-hell .tabelle-scroller::-webkit-scrollbar-thumb { background: rgba(0,82,141,0.55); }
    #vergleich.kontrast-hell .tabelle-scroller::-webkit-scrollbar-thumb:hover { background: rgba(0,82,141,0.75); }
    #vergleich.kontrast-hell .tabelle-wrapper::after { background: linear-gradient(to right, transparent 0%, rgba(0,82,141,0.14) 100%); }
    #vergleich.kontrast-hell .tabelle-wrapper::before { background: linear-gradient(to left, transparent 0%, rgba(0,82,141,0.14) 100%); }

    /* -- Europakarte-Buehne (Laenderfilter): bewusste dunkle Marken-Ausnahme
          (Anwender-Entscheidung 2026-07-09 — nicht umfaerben). Die Buehne ist ein
          dunkles Navy-Gradient-Panel; Ebene-B-Variablen + generische Hell-Overrides
          (filter-label/-column-title) wuerden die hellen Karten-Beschriftungen darauf ins
          Dunkle kippen. Darum die Schrift-Variablen lokal auf Dunkelmodus-Werte
          zuruecksetzen und die Beschriftungen wieder aufhellen. Land-/Marker-/Preset-/
          Spalten-Farben bleiben komplett unveraendert (eigene rgba(255,...)/var-Werte). -- */
    #vergleich.kontrast-hell .ek-sektion {
        --text-primary: #fff; --text-secondary: rgba(255,255,255,0.85); --text-muted: rgba(255,255,255,0.6);
        --accent: #00d4aa; --accent-light: #00d4aa;
    }
    #vergleich.kontrast-hell .ek-sektion .filter-label,
    #vergleich.kontrast-hell .ek-sektion .filter-column-title { color: rgba(255,255,255,0.85); }

    /* -- Mobile (<=38em): Vollbreites weisses Band, #hilfe-Basisfarben, Mini-Label/Info-Icons -- */
    @media (max-width: 38em) {
        /* Seitliche Blau-Streifen neben #vergleich per box-shadow-Kopien (50vw versetzt,
           layout-neutral) weiss uebermalen: vertikal Blau -> Weiss (Vergleich) -> Blau. */
        #vergleich.kontrast-hell { border-radius: 0; box-shadow: 50vw 0 0 #F7F9FC, -50vw 0 0 #F7F9FC; }
        /* #hilfe zieht style.css mobil ins blaue Kopf-Band (#09578f) -> Basis-Akzentfarben halten. */
        #vergleich.kontrast-hell #hilfe .icon { color: var(--mint-500); }
        #vergleich.kontrast-hell #hilfe .current .icon { color: #104266; }
        #vergleich.kontrast-hell #hilfe a:hover .icon, #vergleich.kontrast-hell #hilfe a:focus .icon { color: var(--mint-100); }
        #vergleich.kontrast-hell .ab-zelle.ab-merkmal { border-bottom-color: rgba(0,82,141,0.14); }
        #vergleich.kontrast-hell .ab-mini-label { color: #00528D; }
        #vergleich.kontrast-hell .ab-info-icon { color: #00528D; }
        #vergleich.kontrast-hell .ab-info-icon:hover, #vergleich.kontrast-hell .ab-info-icon:focus-visible { color: #003A66; }
        #vergleich.kontrast-hell .ab-info-icon.ab-info-icon-mini-label { color: #00528D; }
        #vergleich.kontrast-hell .ab-info-icon.ab-info-icon-mini-label:hover, #vergleich.kontrast-hell .ab-info-icon.ab-info-icon-mini-label:focus-visible { color: #003A66; }
    }
    /* === Ende Hochkontrast-Hell-Modus === */

    /* Absatzwechsel innerhalb einer Fussnote (siehe .fn-absatz im PHP-Block):
       definierter Abstandshalter statt der vollen Leerzeile aus <br><br>.
       0.35em ergibt gemessene 7,4 px — unterhalb der 8,8 px zwischen zwei
       Anbieter-Eintraegen, damit die Absaetze sichtbar zum selben Eintrag
       gehoeren. Herkunft der Messreihe: fussnoten-absatzabstand-rollout-
       uebergabe.md (Tabellendarstellung/Festgeld DE). */
    .tabelle-fussnoten .fn-absatz { display: block; height: 0.35em; }
