/* =====================================================================
   Put-Scanner — Gestaltung

   Vorlage ist die lokale Scanner-Oberfläche (~/trading/web/static). Die
   arbeitet mit Tailwind vom CDN; hier geht das nicht, weil die CSP nur
   'self' erlaubt. Übernommen sind deshalb nicht die Klassen, sondern die
   Werte: Slate-Palette als Grundton, Blau 600 als einziger
   Interaktionston, weiße Flächen mit Haarrand, dichte Tabelle,
   Signal-Badges in kräftigem Vollton.

   Warum nachgebaut statt eingebunden: die Seite soll auch dann stehen,
   wenn ein fremder Host klemmt. Ein Stylesheet aus dem eigenen
   Verzeichnis kann das, ein CDN-Skript nicht.

   Schrift: Systemstapel. Webfonts scheiden aus, weil font-src 'self'
   gilt. Wenn du eine eigene Schrift möchtest: Datei nach /static/fonts/
   legen und hier ein @font-face ergänzen — die Rollen unten sind dafür
   getrennt.
   ===================================================================== */

:root {
    /* Slate, wie in der lokalen Oberfläche. */
    --ground:     #f8fafc;   /* slate-50  */
    --field:      #ffffff;
    --field-sunk: #f1f5f9;   /* slate-100 — Tabellenkopf, ruhige Streifen */
    --ink:        #0f172a;   /* slate-900 */
    --ink-soft:   #475569;   /* slate-600 */
    --ink-faint:  #94a3b8;   /* slate-400 */
    --rule:       #e2e8f0;   /* slate-200 */
    --rule-firm:  #cbd5e1;   /* slate-300 */
    --scroll-schatten: rgba(15, 23, 42, .22);
    --stoch-gruen:      #166534;
    --stoch-gruen-wash: #dcfce7;
    --stoch-rot:        #b91c1c;
    --stoch-rot-wash:   #fee2e2;

    /* Ein einziger Interaktionston: Blau 600. */
    --signal:     #2563eb;
    --signal-lit: #1d4ed8;
    --signal-wash:#eff6ff;
    --on-signal:  #ffffff;   /* Text auf gefülltem Blau */

    /* Signalstufen des Scanners — exakt die Töne der lokalen App. */
    --sig-favorit: #166534;
    --sig-stark:   #15803d;
    --sig-moderat: #ca8a04;
    --sig-schwach: #6b7280;

    /* Puffer-Skala: von knapp nach komfortabel, in derselben Familie. */
    --thin:       #b91c1c;
    --tight:      #ca8a04;
    --fair:       #65a30d;
    --wide:       #15803d;

    --taken:      #15803d;
    --rejected:   #6b7280;

    /* Gelb ist der Problemton: yellow-600 mit weißer Schrift kommt auf
       2,94:1 und ist damit unter der Schwelle für Text dieser Größe.
       Die Fläche bleibt, die Schrift darauf wird dunkel; für Text auf
       hellem Grund gibt es den dunkleren Ton. */
    --nomargin:      #a16207;   /* Schrift und Rand auf hellem Grund */
    --nomargin-fill: #ca8a04;   /* Fläche */
    --on-warm:       #1f1600;   /* Schrift auf gelber Fläche */
    --fav:           #a16207;

    /* Grün 700 auf Weiß: 5,02:1 — derselbe Ton wie lokal. */
    --yield-hi:   #15803d;

    /* Zeilenfärbung nach Entscheidung. Eigene Variablen, weil die hellen
       Töne im Dunkelmodus blenden würden. */
    --tint-taken:    #f0fdf4;
    --tint-nomargin: #fffbeb;

    --focus:      #2563eb;

    --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
    --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;

    --radius: 4px;

    --ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
            monospace;
}

@media (prefers-color-scheme: dark) {
    :root {
        --ground:     #0f172a;
        --field:      #1e293b;
        --field-sunk: #172033;
        --ink:        #e2e8f0;
        --ink-soft:   #94a3b8;
        --ink-faint:  #64748b;
        --rule:       #334155;
        --rule-firm:  #475569;
        --scroll-schatten: rgba(0, 0, 0, .65);
        --stoch-gruen:      #4ade80;
        --stoch-gruen-wash: #14321f;
        --stoch-rot:        #f87171;
        --stoch-rot-wash:   #3b1414;

        --signal:     #60a5fa;
        --signal-lit: #93c5fd;
        --signal-wash:#1e3a5f;
        --on-signal:  #0f172a;

        --sig-favorit: #15803d;
        --sig-stark:   #16a34a;
        --sig-moderat: #a16207;
        --sig-schwach: #4b5563;

        --thin:       #ef4444;
        --tight:      #eab308;
        --fair:       #84cc16;
        --wide:       #22c55e;

        --taken:      #4ade80;
        --rejected:   #9ca3af;
        --nomargin:      #fbbf24;
        --nomargin-fill: #a16207;
        --on-warm:       #ffffff;
        --fav:           #eab308;

        --yield-hi:   #4ade80;

        --tint-taken:    #15291f;
        --tint-nomargin: #2a2213;

        --focus:      #60a5fa;
    }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--ground);
    color: var(--ink);
    font-family: var(--ui);
    font-size: 14px;
    line-height: 1.5;
    /* Ziffern müssen untereinander stehen. In einer Tabelle mit dreißig
       Strikes ist das kein Detail, sondern die halbe Lesbarkeit. Die
       lokale App verzichtet darauf; hier bleibt es, weil es nichts
       kostet und nur die Spaltenkanten betrifft. */
    font-variant-numeric: tabular-nums;
}

a { color: var(--signal); text-decoration-thickness: 1px;
    text-underline-offset: 2px; }

:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* ---------------------------------------------------------------
   Typografische Rollen
   --------------------------------------------------------------- */

.eyebrow {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-soft);
}

/* Kein eigener Zeichensatz mehr: die lokale App setzt Zahlen in der
   Grundschrift und hebt nur den Ticker monospaced hervor. */
.num { font-variant-numeric: tabular-nums; }

h1 { font-size: 20px; font-weight: 700; margin: 0; }
h2 { font-size: 16px; font-weight: 700; margin: 0 0 var(--sp-3); }
h3 { font-size: 14px; font-weight: 700; margin: 0 0 var(--sp-2); }

.muted { color: var(--ink-soft); }
.faint { color: var(--ink-faint); }

/* Gerenderter Hinweistext (md.js): Fließtext statt der harten
   72-Zeichen-Umbrüche der Markdown-Quelle. */
.mdtext p { margin: 0 0 var(--sp-3); line-height: 1.55; }
.mdtext h3, .mdtext h4, .mdtext h5 {
    color: var(--ink);
    margin: var(--sp-4) 0 var(--sp-2);
}
.mdtext h4 { font-size: 13px; font-weight: 700; }
.mdtext h5 { font-size: 12.5px; font-weight: 700; }
.mdtext > :first-child { margin-top: 0; }
.mdtext > :last-child { margin-bottom: 0; }
.mdtext hr { border: 0; border-top: 1px solid var(--rule); margin: var(--sp-4) 0; }
.mdtext ul { margin: 0 0 var(--sp-3); padding-left: 20px; }
.mdtext li { margin-bottom: var(--sp-1); line-height: 1.55; }

/* Hinweise-Box (Registrierung/Einladung): begrenzter, scrollbarer Bereich.
   Der Schatten an der Unterkante erscheint nur, solange dort noch Text
   folgt, und verschwindet am Ende — das ist die Scroll-Erkennbarkeit.
   (Abdeck-Gradienten scrollen mit dem Inhalt, Schatten stehen fest.) */
.scrollbox {
    max-height: 340px;
    overflow: auto;
    border: 1px solid var(--rule);
    border-radius: 8px;
    padding: var(--sp-3) var(--sp-4);
    scrollbar-width: thin;
    background:
        linear-gradient(var(--field) 33%, transparent) center top / 100% 36px,
        linear-gradient(transparent, var(--field) 66%) center bottom / 100% 36px,
        radial-gradient(farthest-side at 50% 0, var(--scroll-schatten), transparent) center top / 100% 14px,
        radial-gradient(farthest-side at 50% 100%, var(--scroll-schatten), transparent) center bottom / 100% 14px;
    background-color: var(--field);
    background-repeat: no-repeat;
    background-attachment: local, local, scroll, scroll;
}

/* Hinweis, wenn statt eines leeren Laufs der letzte Treffer-Stand gezeigt
   wird. Auffaellig genug, um nicht als aktueller Stand durchzugehen. */
.stale-note {
    margin-top: 4px;
    padding: 4px 8px;
    border-left: 3px solid var(--sig-moderat);
    background: var(--field-sunk);
    color: var(--ink-soft);
}

/* Einzelansicht: Ticker in Bestand/Rolluebersicht/Offene sind klickbar,
   Aktienzeilen leicht abgesetzt. */
#dep-bestand .ticker, #dep-rollen .ticker, #dep-offen .ticker { cursor: pointer; }
#dep-bestand .ticker:hover, #dep-rollen .ticker:hover, #dep-offen .ticker:hover {
    color: var(--signal); text-decoration: underline; }

/* Offene Options-Kontrakte als Badges: Put gelb, Call blau, long umrandet. */
.opt-badge {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 10px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    margin: 1px 0;
}
.opt-p { background: #fef3c7; color: #92400e; }
.opt-c { background: #dbeafe; color: #1e40af; }
.opt-long { background: transparent; border: 1px solid currentColor; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .opt-p { background: #3b2f0b; color: #fcd34d; }
    :root:not([data-theme="light"]) .opt-c { background: #172554; color: #93c5fd; }
}
tr.sym-aktie td { background: var(--field-sunk); }

/* Der IBKR-Abruf-Knopf in der Kopfzeile: kompakter als die Formular-Knoepfe. */
.btn-klein { padding: 3px 10px; font-size: 12px; }

/* Depot-Tab: Kennzahlen, NAV-Linie, Kreisdiagramme. */
.kennzahlen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: var(--sp-3);
}
.kennzahl { display: flex; flex-direction: column; gap: 2px; }
.kennzahl-label { font-size: 11px; color: var(--ink-faint);
                  text-transform: uppercase; letter-spacing: .04em; }
.kennzahl-wert { font-size: 18px; font-weight: 700;
                 font-variant-numeric: tabular-nums; }
.kennzahl-wert.warn { color: var(--sig-moderat); }

.dep-chart { margin-top: var(--sp-2); }
.nav-svg { width: 100%; height: 190px; display: block; }
.nav-linie { stroke: var(--sig-stark); stroke-width: 2; }
.nav-linie.faellt { stroke: var(--thin); }
.nav-achse { display: flex; justify-content: space-between;
             font-size: 11px; color: var(--ink-faint); margin-top: 4px; }
.nav-gitter { stroke: var(--rule); stroke-width: 1; }
.nav-skala { fill: var(--ink-faint); font-size: 10px; }
#nav-cursor { stroke: var(--ink-faint); stroke-width: 1;
              stroke-dasharray: 3 3; }
#nav-punkt { fill: var(--signal); }
.dep-chart { position: relative; }
.nav-tip {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    background: var(--field);
    border: 1px solid var(--rule-firm);
    border-radius: 4px;
    padding: 2px 8px;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
    white-space: nowrap;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .25);
}

.plus  { color: var(--sig-stark); }
.minus { color: var(--thin); }
tr.summe td { border-top: 2px solid var(--rule-firm); font-weight: 700; }

.dep-pies { display: flex; gap: var(--sp-5); flex-wrap: wrap; }
.dep-pies figure { margin: 0; }
.dep-pies figcaption { text-align: center; font-size: 12px;
                       color: var(--ink-soft); margin-top: var(--sp-2); }
.pie-svg { width: 160px; height: 160px; display: block; margin: 0 auto; }
.pie-legende { display: flex; flex-direction: column; gap: 2px;
               margin-top: var(--sp-2); font-size: 12px; max-width: 220px; }
.pie-eintrag { display: flex; align-items: center; gap: 6px;
               color: var(--ink-soft); }
.pie-punkt { width: 10px; height: 10px; border-radius: 2px;
             flex: none; display: inline-block; }

/* Sandbox-Modus: Banner unter der Kopfzeile und Badge im Verlauf. */
.sandbox-banner {
    padding: 6px 24px;
    font-size: 12px;
    font-weight: 600;
    background: var(--stoch-rot-wash);
    color: var(--stoch-rot);
    border-top: 1px solid var(--rule);
}
.badge.sandbox { color: var(--stoch-rot); }

/* Stochastik-Flag: grün = überverkauft (günstig für Put-Verkauf),
   rot = überkauft (meiden), grau = neutral. */
.stoch-flag {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}
.stoch-ueberverkauft { background: var(--stoch-gruen-wash); color: var(--stoch-gruen); }
.stoch-ueberkauft    { background: var(--stoch-rot-wash);   color: var(--stoch-rot); }
.stoch-neutral       { background: var(--field-sunk);       color: var(--ink-faint); font-weight: 400; }

/* Verlauf: Kommentar in der Zeile bearbeiten */
td.hist-comment { cursor: pointer; white-space: normal; }
.hist-comment-stift { color: var(--ink-faint); font-size: 11px; }
td.hist-comment:hover .hist-comment-stift { color: var(--signal); }
.hist-comment-feld {
    width: 100%;
    min-width: 180px;
    font: inherit;
    color: var(--ink);
    background: var(--field);
    border: 1px solid var(--signal);
    border-radius: var(--radius);
    padding: 4px 6px;
}

/* ---------------------------------------------------------------
   Kopfleiste — zwei Zeilen wie lokal: Marke oben, Reiter darunter
   --------------------------------------------------------------- */

.rail {
    background: var(--field);
    border-bottom: 1px solid var(--rule);
    position: sticky;
    top: 0;
    z-index: 20;
}

.rail-top {
    display: flex;
    align-items: center;
    gap: var(--sp-5);
    padding: 0 var(--sp-5);
    height: 52px;
}

.brand {
    font-weight: 700;
    font-size: 18px;
    white-space: nowrap;
}

.rail-end { display: flex; align-items: center; gap: var(--sp-4);
            margin-left: auto; }

.tabs {
    display: flex;
    gap: 2px;
    padding: 0 var(--sp-5);
    border-top: 1px solid var(--rule);
}

.tab {
    appearance: none;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: 9px 16px;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    color: var(--ink-soft);
    cursor: pointer;
    white-space: nowrap;
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] {
    color: var(--signal);
    border-bottom-color: var(--signal);
}

/* ---------------------------------------------------------------
   Seitengerüst
   --------------------------------------------------------------- */

.wrap { padding: var(--sp-5); max-width: 1600px; margin: 0 auto; }
.narrow { max-width: 620px; margin: 0 auto; padding: var(--sp-6) var(--sp-4); }

.panel {
    background: var(--field);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    overflow: hidden;
}
.panel + .panel { margin-top: var(--sp-4); }
.panel-body { padding: var(--sp-5); }

/* Kontextstreifen über der Tabelle: woher stammen diese Zeilen,
   und wie weit bin ich damit. */
.context {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--sp-2) var(--sp-5);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--rule);
    background: var(--field);
}
.context .headline { font-weight: 700; font-size: 16px; }

.tally { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
         margin-left: auto; }
.tally-item { display: flex; align-items: baseline; gap: 6px; }
.tally-item .count { font-size: 15px; font-weight: 700; }

/* ---------------------------------------------------------------
   Filterleiste — direkt aus der lokalen Oberfläche
   --------------------------------------------------------------- */

.filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--rule);
    background: var(--field-sunk);
}
.filters input[type=search], .filters select {
    width: auto;
    padding: 5px 9px;
    font-size: 13px;
}
.filters input[type=search] { min-width: 140px; }
.filters input[type=search]::-webkit-search-cancel-button { appearance: none; }
.filters label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 13px;
    font-weight: 400;
    color: var(--ink);
}
.filters input[type=checkbox] { width: auto; }
.filters .spacer { margin-left: auto; }

/* ---------------------------------------------------------------
   Tabelle
   --------------------------------------------------------------- */

.scroll { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; }

/* Kein position:sticky. Der Scrollbereich der Tabelle hat overflow-x,
   und das macht ihn auch vertikal zum Scrollcontainer — ein klebender
   Kopf bezieht sich dann auf diese Box statt auf das Fenster und landet
   um den top-Wert versetzt mitten in den Zeilen. Die lokale Oberfläche
   hat ohnehin keinen. */
thead th {
    background: var(--field-sunk);
    border-bottom: 1px solid var(--rule);
    padding: var(--sp-2) var(--sp-2);
    text-align: right;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-soft);
    white-space: nowrap;
    z-index: 10;
}
thead th:first-child, thead th.left { text-align: left; }

thead th[data-term] { cursor: help; text-decoration: underline dotted
                      var(--rule-firm); text-underline-offset: 3px; }

tbody td {
    padding: 6px var(--sp-2);
    border-bottom: 1px solid var(--rule);
    text-align: right;
    white-space: nowrap;
}
tbody td:first-child, tbody td.left { text-align: left; }

/* Fließtext in Tabellen. Die Regel oben verbietet Umbrüche, weil eine
   Kandidatenzeile aus kurzen Zahlen besteht — in einer Erklärspalte ist
   sie falsch und schneidet den Satz am Rand ab. */
table.prosa td, table.prosa th { white-space: normal; }

tbody tr:hover { background: var(--ground); }

/* Nach dem Hover definiert, damit die Entscheidung sichtbar bleibt,
   wenn die Maus über der Zeile steht. Gleiche Spezifität, spätere
   Regel gewinnt. */
tbody tr.d-taken     { background: var(--tint-taken); }
tbody tr.d-no_margin { background: var(--tint-nomargin); }
tbody tr.d-rejected  { opacity: .55; }

tbody tr[aria-current="true"] {
    background: var(--signal-wash);
    box-shadow: inset 2px 0 0 var(--signal);
}

.ticker { font-family: var(--mono); font-weight: 700; }
tbody tr.is-fav td:first-child { border-left: 3px solid var(--fav); }
.fav::before { content: "★ "; color: var(--fav); }

/* Rendite ist die Zahl, auf die zuerst geschaut wird. */
.yield { font-weight: 700; }
.yield.hi { color: var(--yield-hi); }

/* ---------------------------------------------------------------
   Signalstufe des Scanners
   --------------------------------------------------------------- */

.sig {
    display: inline-block;
    padding: 2px 7px;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 600;
    color: #fff;
    white-space: nowrap;
}
.sig-favorit { background: var(--sig-favorit); }
.sig-stark   { background: var(--sig-stark); }
.sig-moderat { background: var(--sig-moderat); color: var(--on-warm); }
.sig-schwach { background: var(--sig-schwach); }

/* ---------------------------------------------------------------
   Puffer-Balken

   Der Puffer ist die Zahl, an der die Zuteilung hängt. Als Ziffer in
   einer Spalte muss man dreißigmal rechnen; als Skala sieht man es.
   Bezugsgröße sind 30 % — darüber ist der Unterschied für die
   Entscheidung ohnehin akademisch.
   --------------------------------------------------------------- */

.buffer { display: flex; align-items: center; gap: var(--sp-2);
          justify-content: flex-end; }

.buffer-track {
    position: relative;
    width: 72px;
    height: 8px;
    background: var(--ground);
    border: 1px solid var(--rule-firm);
    border-radius: 2px;
    overflow: hidden;
    flex: none;
}
.buffer-fill { position: absolute; inset: 0 auto 0 0; }
.buffer-track::after {          /* Marke bei 10 % — die enge Grenze */
    content: "";
    position: absolute;
    left: 33.3%;
    top: 0; bottom: 0;
    width: 1px;
    background: var(--rule-firm);
}
.buffer-value { font-size: 13px; min-width: 40px; }

.b-thin  { background: var(--thin); }
.b-tight { background: var(--tight); }
.b-fair  { background: var(--fair); }
.b-wide  { background: var(--wide); }

/* Score mit stiller Marke, sobald die Schwelle überschritten ist */
.score { display: inline-flex; align-items: center; gap: 6px;
         justify-content: flex-end; }
.score-dot {
    width: 6px; height: 6px; border-radius: 50%;
    background: var(--rule-firm); flex: none;
}
.score-dot.above { background: var(--signal); }

/* ---------------------------------------------------------------
   Entscheidung — direkt in der Zeile, kein Dialog für den Regelfall
   --------------------------------------------------------------- */

.choice { display: inline-flex; gap: var(--sp-1); }

.choice button {
    appearance: none;
    border: 1px solid var(--rule-firm);
    border-radius: var(--radius);
    background: var(--field);
    color: var(--ink-soft);
    font: inherit;
    font-size: 11px;
    padding: 3px 9px;
    cursor: pointer;
    white-space: nowrap;
}
.choice button[data-d="taken"]     { border-color: var(--taken);    color: var(--taken); }
.choice button[data-d="no_margin"] { border-color: var(--nomargin); color: var(--nomargin); }
.choice button[data-d="rejected"]  { border-color: var(--rejected); color: var(--rejected); }

.choice button:hover { filter: brightness(.94); }

.choice button[aria-pressed="true"] { color: #fff; font-weight: 600; }
.choice button[data-d="taken"][aria-pressed="true"]     { background: var(--taken);
                                                          border-color: var(--taken); }
.choice button[data-d="no_margin"][aria-pressed="true"] { background: var(--nomargin-fill);
                                                          border-color: var(--nomargin-fill);
                                                          color: var(--on-warm); }
.choice button[data-d="rejected"][aria-pressed="true"]  { background: var(--rejected);
                                                          border-color: var(--rejected); }

/* Weg zum Dialog: unauffällig, aber vorhanden. Der Punkt markiert Zeilen,
   bei denen Abschluss oder Kommentar vom Vorschlag abweichen. */
.detail-btn {
    appearance: none;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: none;
    color: var(--signal);
    font: inherit;
    font-size: 11px;
    padding: 3px 8px;
    cursor: pointer;
    white-space: nowrap;
}
.detail-btn:hover { border-color: var(--rule-firm); background: var(--field-sunk); }
.detail-btn.angepasst::after {
    content: "";
    display: inline-block;
    width: 5px; height: 5px;
    margin-left: 5px;
    border-radius: 50%;
    background: var(--signal);
    vertical-align: 1px;
}

.badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 3px;
    border: 1px solid currentColor;
}
.badge.taken     { color: var(--taken); }
.badge.rejected  { color: var(--rejected); }
.badge.no_margin { color: var(--nomargin); }
.badge.manual    { color: var(--ink-faint); }
.badge.warn      { color: var(--thin); }

/* ---------------------------------------------------------------
   Formulare und Knöpfe
   --------------------------------------------------------------- */

label { display: block; font-size: 13px; font-weight: 600;
        margin-bottom: var(--sp-1); color: var(--ink-soft); }

input[type=text], input[type=email], input[type=password],
input[type=number], input[type=date], input[type=search], select, textarea {
    /* appearance: none — sonst bringt type=search in WebKit eigene
       Rundungen und Innenabstände mit und fällt aus der Reihe. */
    appearance: none;
    -webkit-appearance: none;
    width: 100%;
    padding: 8px 10px;
    font: inherit;
    font-size: 14px;
    color: var(--ink);
    background: var(--field);
    border: 1px solid var(--rule-firm);
    border-radius: var(--radius);
}
input:focus, select:focus, textarea:focus { border-color: var(--signal); }

.field { margin-bottom: var(--sp-4); }
.hint { font-size: 13px; color: var(--ink-soft); margin-top: var(--sp-1); }

.btn {
    appearance: none;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    padding: 7px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--signal);
    background: var(--signal);
    color: var(--on-signal);
    cursor: pointer;
}
.btn:hover { background: var(--signal-lit); border-color: var(--signal-lit); }
.btn[disabled] { opacity: .4; cursor: default; }

.btn-quiet {
    background: var(--field-sunk);
    color: var(--ink);
    border-color: var(--rule-firm);
}
.btn-quiet:hover { background: var(--rule); border-color: var(--rule-firm); }

.btn-danger { background: var(--field); color: var(--thin);
              border-color: var(--thin); }
.btn-danger:hover { background: var(--thin); color: #fff; }

.row { display: flex; gap: var(--sp-3); align-items: center; }
.row-end { justify-content: flex-end; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }

/* ---------------------------------------------------------------
   Hinweise, Leerzustände, Dialog
   --------------------------------------------------------------- */

.note {
    padding: var(--sp-3) var(--sp-4);
    border-left: 3px solid var(--rule-firm);
    border-radius: 0 var(--radius) var(--radius) 0;
    background: var(--field-sunk);
    font-size: 13px;
    color: var(--ink-soft);
}
.note.caution { border-left-color: var(--tight); }

.empty {
    padding: var(--sp-7) var(--sp-4);
    text-align: center;
    color: var(--ink-faint);
}

dialog {
    border: 1px solid var(--rule-firm);
    border-radius: var(--radius);
    background: var(--field);
    color: var(--ink);
    padding: 0;
    width: min(480px, calc(100vw - 32px));
}
dialog::backdrop { background: rgba(15, 23, 42, .45); }
.dialog-head { padding: var(--sp-4) var(--sp-5);
               border-bottom: 1px solid var(--rule); }
.dialog-body { padding: var(--sp-5); }
.dialog-foot { padding: var(--sp-4) var(--sp-5);
               border-top: 1px solid var(--rule);
               display: flex; gap: var(--sp-3); justify-content: flex-end; }

/* Kurzer, unaufdringlicher Vollzug — die Entscheidung ist gespeichert,
   mehr muss die Meldung nicht sagen. */
.toast {
    position: fixed;
    bottom: var(--sp-5);
    left: 50%;
    transform: translateX(-50%);
    background: var(--ink);
    color: var(--field);
    padding: 9px 18px;
    border-radius: var(--radius);
    font-size: 13px;
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s;
}
.toast.on { opacity: 1; }
.toast.bad { background: var(--thin); color: #fff; }

/* ---------------------------------------------------------------
   Glossar
   --------------------------------------------------------------- */

.terms { display: grid; gap: 1px; background: var(--rule); }
.term { background: var(--field); padding: var(--sp-4) var(--sp-5); }
.term dt { font-weight: 700; margin-bottom: var(--sp-1); }
.term dd { margin: 0; color: var(--ink-soft); }
.term .short { color: var(--ink); margin-bottom: var(--sp-2); }

.tip {
    position: fixed;
    max-width: 300px;
    padding: var(--sp-2) var(--sp-3);
    background: var(--ink);
    color: var(--field);
    font-size: 12px;
    line-height: 1.45;
    border-radius: var(--radius);
    z-index: 60;
    pointer-events: none;
}

/* ---------------------------------------------------------------
   Schmale Fenster: Tabelle wird zur Kartenliste
   --------------------------------------------------------------- */

@media (max-width: 860px) {
    .wrap { padding: var(--sp-3); }
    .rail { position: static; }
    .rail-top { gap: var(--sp-3); padding: 0 var(--sp-3); }
    .tabs { overflow-x: auto; padding: 0 var(--sp-3); }
    .filters { padding: var(--sp-3); }

    table, thead, tbody, td { display: block; }
    thead { display: none; }

    /* Zwei Spalten je Karte. Bei sechzehn Feldern wäre eine Liste
       untereinander eine Bildschirmhöhe pro Kandidat — so bleibt der
       Vergleich zwischen zwei Zeilen möglich, ohne Felder wegzulassen. */
    .scroll { overflow-x: visible; }

    tbody tr {
        display: grid;
        /* minmax(0, …), sonst wächst die Spalte auf die Inhaltsbreite und
           die Karte wird breiter als das Fenster. */
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 0 var(--sp-3);
        border: 1px solid var(--rule);
        border-radius: var(--radius);
        margin-bottom: var(--sp-3);
        padding: var(--sp-3);
        background: var(--field);
    }
    /* Ticker und Entscheidung über die volle Breite. */
    tbody td:first-child, tbody td:last-child { grid-column: 1 / -1; }

    tbody tr.is-fav td:first-child { border-left: 0; }
    tbody tr.is-fav { border-left: 3px solid var(--fav); }

    tbody td {
        border: 0;
        padding: 3px 0;
        text-align: right;
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: var(--sp-2);
        min-width: 0;
        white-space: normal;
    }
    /* Zahlen dürfen nicht umbrechen — das schmale Leerzeichen vor dem
       Prozentzeichen ist eine Umbruchstelle. */
    tbody td.num, .buffer-value { white-space: nowrap; }
    .buffer-track { width: 44px; }

    .choice { flex-wrap: wrap; justify-content: flex-end; }
    tbody td::before {
        content: attr(data-label);
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--ink-faint);
    }
    tbody td.left { text-align: right; }
}

.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
