/*
 * Dipsy Portfolio - die Gestalt der veroeffentlichten Seite
 *
 * EINMAL fuer alle Portfolios: diese Datei liegt in portfolio/assets/ und wird
 * von jeder Seite als assets/dipsy.css eingebunden. Eine Kopie je Seite waere
 * die zweite Stelle, und beim naechsten Umbau die aeltere (DESIGN.md §0).
 *
 * Die Farben und Masse sind die der App - sie stehen im VERTRAG und hier als
 * Variablen, nicht als Literal im Markup: sonst behaelt eine Karte ihr eigenes
 * Gruen, und es faellt erst auf dem Geraet auf (DESIGN.md §5).
 *
 * Jede Farbe hat EINE Bedeutung: rot ist Fehler und Verlust, gruen Gewinn,
 * blau die neutrale Reihe, violett die zweite, und das Akzentrot gehoert den
 * Kartentiteln.
 *
 * Handybreite zuerst. Ab 720px eine Spalte in der Mitte, hoechstens 680px -
 * nichts scrollt dabei waagerecht.
 */

/*
 * DIE SCHRIFT DER PRODUKTSEITE - und zwar als Datei, nicht als Bitte.
 *
 * Bis zum 08.10.2026 bat die Seite um die Schrift des Geraets. Was das ist,
 * entscheidet der Rechner des Lesers, und auf einem war es eine
 * SCHREIBMASCHINENSCHRIFT: die ganze Seite in Monospace, jede Ueberschrift zu
 * breit fuer ihre Spalte. Eine veroeffentlichte Seite wird weitergegeben - sie
 * soll bei jedem gleich aussehen, und das geht nur mit einer mitgelieferten
 * Schrift (DESIGN.md §3: was von draussen kommt, stimmt nicht, nur weil es
 * stimmen sollte).
 *
 * ZWEI SCHNITTE, NICHT FUENF. Die Produktseite laedt fuenf; hier reichen die
 * zwei des Fliesstextes - 63 KB, einmal fuer alle Seiten eines Lesers. Der
 * halbfette traegt auch die 700er und 800er (`font-weight: 600 800`), damit der
 * Browser keinen falschen Fettdruck dazurechnet.
 *
 * `swap`: bis die Datei da ist, steht die Seite in der Schrift des Geraets und
 * nicht in gar keiner. Fira Sans, SIL Open Font License - OFL.txt liegt daneben.
 */
@font-face {
    font-family: "Fira Text";
    src: url("fira-text-book.woff2") format("woff2");
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "Fira Text";
    src: url("fira-text-semibold.woff2") format("woff2");
    font-weight: 600 800;
    font-display: swap;
}

:root {
    --window: #060913;
    --page: #0A0A0E;
    --surface: #111319;
    --line: #1E2330;
    --border: #2A3040;
    --text: #FFFFFF;
    --heading: #F3F4F6;
    --second: #9CA3AF;
    --muted: #6B7280;
    --accent: #E53E3E;
    --gain: #10B981;
    --loss: #F87171;
    --blue: #38BDF8;
    --green: #34D399;
    --violet: #A855F7;
    /* Die Breite der Seite - EINE Zahl fuer Kopfzeile, Inhalt und Fusszeile.
       Stand sie an jedem der drei Kaesten, haette die naechste Aenderung zwei
       Kanten verschoben und eine stehen gelassen (DESIGN.md §0). Mit zwei
       Bloecken wird sie breiter: siehe body.two am Ende der Datei. */
    --page-max: 680px;
    --radius: 14px;
    --badge: 8px;
    --pad: 16px;
    --gap: 6px;
}

* {
    box-sizing: border-box;
}

html,
body {
    margin: 0;
    padding: 0;
    background: var(--window);
}

body {
    /*
     * Die Schrift des Geraets, keine geladene Datei: eine Webfont-Datei waere
     * ein zweiter Abruf fuer eine Seite, die sonst aus einer Datei besteht.
     *
     * ABER NICHT `system-ui` ZUERST. Was dahintersteckt, entscheidet der
     * Rechner des Lesers - und auf einem von ihnen war es eine SCHREIBMASCHINEN-
     * SCHRIFT: die ganze Seite in Monospace, und die Spaltenueberschriften
     * brachen mitten im Wort um, der Sortierpfeil stand allein in einer dritten
     * Zeile (gemeldet und nachgestellt am 08.10.2026). Was von draussen kommt,
     * stimmt nicht, nur weil es stimmen sollte (DESIGN.md §3).
     *
     * Deshalb zuerst die Schriften, die es WIRKLICH gibt - Apple, Windows,
     * Android, dann die ueblichen Linux-Namen -, und `system-ui` erst dahinter,
     * wo es nur noch einspringt, wenn keine davon da ist.
     */
    font-family: "Fira Text", -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, system-ui, sans-serif;
    color: var(--text);
    font-size: 14px;
    line-height: 1.45;
    -webkit-text-size-adjust: 100%;
}

.wrap {
    /* 16px Seitenrand, auf jeder Breite - und nichts, was darueber hinausragt. */
    padding: var(--pad);
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: var(--page-max);
    margin: 0 auto;
    overflow-x: hidden;
}

.card {
    background: var(--surface);
    border-radius: var(--radius);
    padding: var(--pad);
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.card-head-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.card-title {
    margin: 0;
    color: var(--accent);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 1.1px;
}

.card-intro {
    margin: 0;
    color: var(--muted);
    font-size: 12px;
    line-height: 16px;
}

/* Ein Satz, der die Zahlen unter ihm einschraenkt - leise, aber vor ihnen. */
.hint {
    margin: 0;
    color: var(--muted);
    font-size: 11px;
    line-height: 15px;
}

/* Womit umgerechnet wurde: der Kurs steht neben der umgerechneten Zahl
   (DESIGN.md §9). */
.rates {
    margin-top: 2px;
}

.rate-line {
    margin: 0;
    color: var(--muted);
    font-size: 11px;
    line-height: 16px;
}

.rule {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 4px 0;
    width: 100%;
}

.note {
    margin: 0;
    color: var(--second);
    font-size: 13px;
    line-height: 18px;
}

/*
 * Die Nettozeile unter der grossen Zahl - kleiner als der Rest, weil sie eine
 * Ergaenzung ist und nicht die Aussage: brutto steht oben.
 */
.note-small {
    font-size: 12px;
    line-height: 17px;
    color: var(--muted);
}

.dot {
    color: var(--muted);
}

.gap {
    margin-left: 10px;
}

.pos {
    color: var(--gain);
}

.neg {
    color: var(--loss);
}

/* --- Kopf ------------------------------------------------------------- */

.pf-name {
    margin: 0;
    color: var(--heading);
    font-size: 22px;
    font-weight: 800;
    letter-spacing: -0.3px;
    overflow-wrap: break-word;
}

.pf-sub {
    margin: 0;
    color: var(--second);
    font-size: 13px;
}

/* --- GESAMT ----------------------------------------------------------- */

.total-value {
    /*
     * DER ABSTAND GEHOERT ZUR KLASSE, NICHT ZUM ELEMENT.
     *
     * Die grosse Zahl stand links in einem <div> und rechts in einem <p>, und
     * ein <p> behaelt den Vorgabeabstand des Browsers - bei 30 px Schrift ein
     * ganzes em oben und unten. Die zwei Karten standen damit auf
     * verschiedener Hoehe, nebeneinander, und es sah nach einem Fehler im
     * Inhalt aus (gemessen am Geraet, 04.10.2026).
     */
    margin: 0;
    font-size: 30px;
    font-weight: 800;
    letter-spacing: -0.5px;
    line-height: 1.15;
    overflow-wrap: break-word;
}

.total-change {
    font-size: 14px;
    font-weight: 600;
}

.figure {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.figure-label {
    color: var(--second);
    font-size: 13px;
}

.figure-value {
    font-size: 14px;
    font-weight: 700;
    text-align: right;
}

/* --- VERLAUF ---------------------------------------------------------- */

.curve-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    min-height: 28px;
}

.curve-value {
    font-size: 20px;
    font-weight: 800;
}

.curve-date {
    color: var(--second);
    font-size: 12px;
}

.curve-invested {
    /* In der Farbe ihrer Linie: der Hinweis gehoert zu dem, was er beschreibt. */
    color: var(--violet);
    font-size: 12px;
    font-weight: 600;
    min-height: 18px;
}

.curve {
    display: block;
    width: 100%;
    height: 200px;
    touch-action: pan-y;
}

.curve-area {
    fill: url(#dipsy-area);
    stroke: none;
}

.curve-line,
.curve-invested-line {
    fill: none;
    /* Gleich dick, obwohl das Rechteck gezogen wird (preserveAspectRatio="none"). */
    vector-effect: non-scaling-stroke;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.curve-line {
    stroke: var(--blue);
    stroke-width: 2;
}

.curve-invested-line {
    stroke: var(--violet);
    stroke-width: 1.5;
    stroke-dasharray: 5 4;
}

.curve-cursor {
    stroke: var(--border);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.curve-dot {
    fill: var(--blue);
    stroke: var(--surface);
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
}

.ranges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.ranges:empty {
    display: none;
}

.range {
    flex: 1 1 auto;
    min-width: 54px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: var(--badge);
    background: transparent;
    color: var(--second);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}

.range[aria-pressed="true"] {
    border-color: var(--accent);
    color: var(--text);
    background: var(--line);
}

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

.bar {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 5px 0;
}

.bar-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.bar-label {
    color: var(--second);
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bar-share {
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.track {
    height: 8px;
    border-radius: var(--badge);
    background: var(--line);
    overflow: hidden;
}

.fill {
    height: 8px;
    border-radius: var(--badge);
    background: var(--blue);
}

.bars-violet .fill {
    background: var(--violet);
}

.bar-rest .fill {
    /* Der Rest ist kein Posten, sondern das, was uebrig ist - leise. */
    background: var(--muted);
}

/* --- HEUTE ------------------------------------------------------------ */

.group-label {
    margin: 2px 0 0;
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
}

.mover {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0;
}

.mover-name {
    color: var(--second);
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mover-value {
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

/* --- Zeilenlisten ----------------------------------------------------- */

.row {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px 0;
}

.row-main {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.row-name {
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.row-value {
    font-size: 14px;
    font-weight: 700;
    white-space: nowrap;
}

.row-foot {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.row-count {
    color: var(--muted);
    font-size: 12px;
    line-height: 16px;
}

.row-gain {
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

/* --- Die Positionstabelle --------------------------------------------- */
/*
 * Eine echte Tabelle: Daten in Zeilen und Spalten, damit eine Vorlesesoftware
 * sie als solche liest. table-layout: fixed, weil die Spaltenbreiten sonst vom
 * laengsten Namen abhingen - und ein Depot mit "iShares Core MSCI World UCITS
 * ETF" schoebe die Zahlen aus dem Bild.
 *
 * Die Zahlenspalten sind in Prozent breit und zusammen 68 %; der Name bekommt
 * den Rest und wird bei Bedarf mit … gekuerzt. Gemessen bei 390 px: nichts
 * scrollt waagerecht, keine Zahl bricht um.
 */

.positions {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

.positions th,
.positions td {
    padding: 7px 0 7px 5px;
    vertical-align: baseline;
}

/* Die Kopfzeile ist Pflicht: ohne sie raet der Leser, was die Spalten sind. */
/*
 * EINE UEBERSCHRIFT DARF UMBRECHEN, EINE ZAHL NICHT. "Anteil %", "Rendite %"
 * und "YoC %" brauchen bei 390 px zusammen mehr Breite als die Zahlen
 * darunter - mit nowrap liefen sie ineinander, und drei Ueberschriften ohne
 * Zwischenraum sind eine (gemessen 06.10.2026: Spalte 47 px, Wort 72 px).
 *
 * Gekuerzt wird nichts: die Woerter kommen aus der App, und der Server hat
 * keine eigenen (DESIGN.md §6). Also bekommen sie eine zweite Zeile.
 */
.positions thead th {
    color: var(--muted);
    font-size: 11px;
    font-weight: 600;
    text-align: right;
    white-space: normal;
    overflow-wrap: break-word;
    border-bottom: 1px solid var(--line);
    padding-bottom: 6px;
    /*
     * ALLE UEBERSCHRIFTEN STEHEN AUF DER UNTERSTEN ZEILE - der Zeile ueber dem
     * Strich, an dem die Zahlen anfangen. Mit `baseline` haengt eine
     * zweizeilige Ueberschrift an ihrer ERSTEN Zeile, und die einzeiligen
     * daneben standen dann auf halber Hoehe: eine Kopfzeile, die wie drei
     * aussieht (gesehen am 08.10.2026).
     */
    vertical-align: bottom;
}


/* --- Der Ring der Aufteilung -----------------------------------------
   Der Ring steht links, die Namen rechts; auf dem Telefon untereinander. Die
   Liste ist nicht das Beiwerk - sie traegt die Auskunft, der Ring das Bild. */

/* Der Ring steht OBEN und ueber die ganze Breite, die Namen darunter. Daneben
   war er ein Beiwerk neben einer Liste; oben ist er das, was man zuerst sieht
   (Wunsch des Nutzers, 05.10.2026). */
.pie {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* So gross, wie die Karte es zulaesst - der Umfang ist das, was die Stuecke
   voneinander trennt: bei hundert Posten misst ein Stueck von 0,3 % auf einem
   Ring von 230 px einen Punkt und auf einem von 300 deren zwei. Mehr Platz ist
   hier keine Zierde, DESIGN.md §5. */
.pie-figure {
    position: relative;
    align-self: center;
    width: 100%;
    max-width: 300px;
    aspect-ratio: 1;
}

.pie-ring {
    width: 100%;
    height: 100%;
    /* Der erste Posten beginnt oben, nicht rechts: so liest sich der Ring wie
       eine Uhr, und das groesste Stueck faengt da an, wo das Auge anfaengt. */
    transform: rotate(-90deg);
}

.pie-slice {
    transition: stroke-width 120ms ease, stroke-opacity 120ms ease;
}

/*
 * Der Finger darf ueber den Ring fahren - und die Seite trotzdem scrollen.
 *
 * `pan-y` sagt dem Browser: die senkrechte Bewegung gehoert dir, die waagerechte
 * mir. Damit kommt ein Fahren ueber den Ring beim Skript an, ohne dass ein
 * Wischen durch die Seite haengenbleibt. Dieselbe Zeile steht an der Kurve, und
 * aus demselben Grund (DESIGN.md §5).
 */
.pie {
    touch-action: pan-y;
}

/* Die Haarlinie zwischen zwei Stuecken: sie gehoert zum Bild und nicht zur
   Auskunft, also nimmt sie keine Klicks an. */
.pie-gap {
    pointer-events: none;
}

/* Angefasst: dickeres Stueck, und die anderen treten zurueck. */
.pie[data-active] .pie-slice {
    stroke-opacity: 0.25;
}

.pie .pie-slice[data-on] {
    stroke-width: 9;
    stroke-opacity: 1;
}

.pie-centre {
    position: absolute;
    /* In Teilen des Rings, nicht in Pixeln: waechst der Ring, waechst das Loch
       mit, und der Text laeuft nicht unter die Stuecke. */
    inset: 23%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    pointer-events: none;
    gap: 2px;
}

.pie-centre-name {
    color: var(--second);
    font-size: 10px;
    line-height: 12px;
    /* Hoechstens drei Zeilen: ein Fondsname ist laenger als das Loch. */
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

.pie-centre-share {
    color: var(--text);
    font-size: 15px;
    font-weight: 700;
}

/* Zwanzig Namen in einer Spalte waeren eine lange Saeule unter einem breiten
   Ring. So viele Spalten, wie die Breite hergibt - auf dem Telefon eine. */
.pie-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    column-gap: 18px;
    row-gap: 5px;
}

.pie-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    min-width: 0;
}

.pie-chip {
    flex: 0 0 9px;
    width: 9px;
    height: 9px;
    border-radius: 3px;
}

.pie-name {
    flex: 1 1 auto;
    color: var(--second);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.pie-share {
    color: var(--text);
    font-variant-numeric: tabular-nums;
    /* Sonst bricht "6,1 %" zwischen Zahl und Zeichen um, und die Zeile wird
       zweizeilig (gesehen am gezeichneten Ring, 05.10.2026). */
    white-space: nowrap;
}

/* DER REST STEHT NICHT IN DER LISTE - nur im Ring. Seine Zeile bleibt da,
   damit das Skript Name und Anteil von dort holt und nicht aus einer zweiten
   Quelle (DESIGN.md §0). */
/* Nur wo das Skript laeuft: ohne es ist nichts anfassbar, also sieht auch
   nichts danach aus (DESIGN.md §5). */
.pie[data-live] .pie-row {
    cursor: pointer;
}

.pie[data-live] .pie-slice {
    cursor: pointer;
}

.pie[data-active] .pie-row {
    opacity: 0.45;
}

.pie[data-active] .pie-row[data-on] {
    opacity: 1;
}

/* --- Sortieren -------------------------------------------------------
   Der Knopf in der Ueberschrift entsteht in dipsy.js; ohne JavaScript steht
   dort reiner Text und nichts sieht klickbar aus (DESIGN.md §5). Er erbt
   Schrift und Ausrichtung seiner Zelle, damit die Kopfzeile aussieht wie
   vorher - nur anfassbar. */
.positions thead th button.sort {
    appearance: none;
    background: none;
    border: 0;
    margin: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    text-align: inherit;
    cursor: pointer;
    /* Umbrechen wie seine Zelle: mit nowrap stand der Knopf ueber den Rand
       hinaus, waehrend die Zelle daneben umbrach. */
    white-space: inherit;
    /*
     * DER PFEIL STEHT NEBEN DER LETZTEN ZEILE, nie allein in einer eigenen.
     *
     * Der Knopf traegt zwei Dinge: die Ueberschrift, die umbrechen darf, und
     * den Pfeil, der das nicht darf. Als Fliesstext hing der Pfeil hinter dem
     * letzten Wort und wurde mitgerissen - in einer schmalen Spalte stand er
     * dann allein unter "Kauf %" und sah aus wie eine dritte Ueberschrift
     * (gesehen am 08.10.2026, auf einem Rechner mit Schreibmaschinenschrift).
     * Als zweites Flex-Kind kann ihn nichts mitreissen: die Ueberschrift bricht
     * in IHREM Kasten um, der Pfeil steht daneben, und `flex-end` setzt ihn auf
     * die Grundlinie der letzten Zeile.
     */
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    gap: 3px;
    width: 100%;
}

.positions thead th button.sort:hover {
    color: var(--text);
}

/* Der Name steht links, also auch sein Pfeil. */
.positions thead th.col-name button.sort {
    justify-content: flex-start;
}

/* Der Pfeil haelt seinen Platz, auch wenn er leer ist: sonst ruecken die
   Ueberschriften beim ersten Klick zur Seite. */
.sort-arrow {
    display: inline-block;
    width: 9px;
    flex: 0 0 auto;
}

.positions thead th[aria-sort="ascending"] .sort-arrow::after {
    content: "\2191";
}

.positions thead th[aria-sort="descending"] .sort-arrow::after {
    content: "\2193";
}

.positions thead th[aria-sort="ascending"],
.positions thead th[aria-sort="descending"] {
    color: var(--text);
}

/* Der Name ist die Beschriftung seiner Zeile - links, und gekuerzt statt
   umgebrochen: eine Zeile je Position haelt die Spalten in einer Flucht. */
.positions .col-name {
    text-align: left;
    padding-left: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.positions tbody th {
    color: var(--text);
    font-size: 13px;
    font-weight: 600;
}

.positions td {
    color: var(--second);
    font-size: 13px;
    text-align: right;
    white-space: nowrap;
    /* Ziffern gleich breit: so stehen die Kommas untereinander. */
    font-variant-numeric: tabular-nums;
}

.positions tbody tr + tr th,
.positions tbody tr + tr td {
    border-top: 1px solid var(--line);
}

/*
 * Gewinn gruen, Verlust rot - auch in der Tabelle.
 *
 * `.pos` allein verliert hier gegen `.positions td` (gleich viele Klassen, aber
 * das Element entscheidet), und die Zahl stand grau da: die Farbe traegt die
 * Bedeutung, und eine graue Zahl sagt nichts (DESIGN.md §5). Deshalb die Regel
 * mit demselben Gewicht.
 */
.positions td.pos {
    color: var(--gain);
}

.positions td.neg {
    color: var(--loss);
}

/*
 * Die Breiten sind an 390 px gemessen, der schmalsten Breite, die zaehlt.
 * Zusammen 67 % - der Name bekommt den Rest und wird gekuerzt. Mehr fuer die
 * Zahlen hiesse weniger fuer die Namen, und ein Name, von dem drei Buchstaben
 * dastehen, ist kein Name mehr.
 */
/*
 * In der vollen Fassung steht "Anteil %" nicht mehr in dieser Tabelle; an
 * seiner Stelle steht der Gewinn in Geld, und der braucht mehr Platz als eine
 * Prozentzahl - er traegt Tausender.
 *
 * Die Breite fuer col-share bleibt: die anonyme Fassung zeigt den Anteil
 * weiter (dort ist er das Einzige, was die Tabelle hat), und die Zahlertabelle
 * der Dividenden benutzt dieselbe Klasse.
 */
.positions .col-share {
    width: 14%;
}

.positions .col-shares {
    width: 13%;
}

/*
 * NACHGEMESSEN AM GERAET, 06.10.2026: bei 390 px stiessen "+1.055,3" und
 * "+69.470,96" ohne eine Luecke aneinander. Die Tabelle hat feste Spalten
 * (table-layout: fixed), also schieben sich zu enge Zellen nicht auseinander -
 * sie ueberlappen, und zwei Zahlen ohne Zwischenraum sind EINE Zahl.
 *
 * Gemessen bei 13 px und Tabellenziffern: "+69.470,96" und "164.492,01"
 * brauchen je rund 78 px, "+1.055" rund 47, "1.390" rund 39 - zusammen mit den
 * Luecken 76 % von 358 px. Der Rest gehoert dem Namen, der gekuerzt wird.
 */
/*
 * 19 % UND NICHT 17: hier steht die laengste Ueberschrift der Tabelle, und auf
 * einem Telefon ist sie das Breiteste in der Spalte - "seit Kauf %" misst bei
 * 10 px 51 px, die Spalte hatte 38 fuer das Wort. Sie brach nach "seit", und
 * ein einzelnes Wort stand ueber der Zeile (gemeldet 08.10.2026). Mit 19 % sind
 * es 45, "seit Kauf" passt, und die zweite Zeile traegt die Einheit.
 *
 * Die zwei Prozent kommen vom Namen - er wird ohnehin gekuerzt, und unter ihm
 * steht sein Kuerzel.
 */
.positions .col-gain {
    width: 19%;
}

.positions .col-gain-money {
    width: 23%;
}

.positions .col-value {
    width: 23%;
}

/*
 * Und auf dem schmalsten Schirm eine Stufe kleiner. Die Zahlen sind dort das
 * Enge, nicht die Schrift: eine Spalte, in der eine Zahl nicht ganz steht, ist
 * keine Spalte mehr.
 */
@media (max-width: 420px) {
    .positions td,
    .positions tbody th {
        font-size: 12px;
    }
}

/*
 * Zwei Spalten statt fuenf (die anonyme Fassung): dann ist der Anteil die
 * LETZTE Spalte, und er bekommt eine feste, schmale Breite - der Rest gehoert
 * dem Namen. Ohne diese Regel teilten sich beide die Breite haelftig, und
 * "18,8" stuende in einer Spalte von 211 Pixeln, waehrend daneben Namen
 * gekuerzt wuerden (gemessen, 04.10.2026).
 */
.positions thead th.col-share:last-child {
    width: 30%;
}

/* --- Fuss ------------------------------------------------------------- */

.card-foot {
    background: transparent;
    padding: 4px var(--pad) 24px;
    gap: 8px;
}

/*
 * ===================================================================
 * KOPFZEILE UND FUSSZEILE DER SEITE - die der Produktseite
 * ===================================================================
 *
 * Eine veroeffentlichte Seite liegt im selben Verzeichnis wie die Produktseite
 * (website/index.html) und soll aussehen, als gehoere sie dorthin: oben die
 * Marke und der Knopf zum Laden, unten die Zeile mit dem Haus und dem
 * Datenschutz (Wunsch des Nutzers, 07.10.2026).
 *
 * DIE MASSE SIND DIE DER PRODUKTSEITE - 44 px Zeichen, 26 px Wortmarke, 22 px
 * Luft darum. Uebernommen, nicht neu erfunden: dieselbe Kopfzeile, die zwei
 * Klicks weiter steht, darf nicht anders aussehen.
 *
 * DIE FARBEN SIND DIE DIESER SEITE. Die Produktseite nennt sie anders
 * (--red/--ink-2/--ink-3), es sind aber dieselben Toene: --accent ist ihr
 * --red. Eine zweite Palette waere die zweite Stelle (DESIGN.md §0), und ein
 * Literal im Markup behielte sein eigenes Rot (§5).
 *
 * Die Schrift bleibt die des Geraets: die Produktseite laedt Fira, diese Seite
 * laedt nichts - eine Webfont-Datei fuer ein Wort waere ein zweiter Abruf fuer
 * eine Seite, die sonst aus einer Datei besteht.
 */
.site-top,
.site-foot {
    max-width: var(--page-max);
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 24px;
}

.site-top {
    padding: 22px var(--pad) 6px;
}

/* Die Marke: Zeichen und Wortmarke, und das Ganze ist der Link. */
.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    text-decoration: none;
    color: var(--text);
}

.brand-mark {
    width: 44px;
    height: auto;
    display: block;
}

.wordmark {
    font-size: 26px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: -0.01em;
}

/* Die zweite Haelfte des Namens traegt das Akzentrot - so steht sie auf der
   Produktseite, und sie ist dort kein Literal, sondern ihre Variable. */
.wordmark span {
    color: var(--accent);
}

.site-nav {
    display: flex;
    align-items: center;
    gap: 18px;
}

/* Das Haus - leise neben dem Knopf, wie auf der Produktseite (.top-nav .plain). */
.site-plain {
    color: var(--second);
    text-decoration: none;
}

/* Der Knopf zum Laden - derselbe wie auf der Produktseite, nur eine Nummer
   kleiner (dort .btn.btn-small). */
.site-btn {
    display: inline-flex;
    align-items: center;
    padding: 10px 14px;
    border-radius: 11px;
    background: var(--accent);
    color: #FFFFFF;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
}

/*
 * Die Fusszeile steht UNTER dem Hinweis zum Depot und nicht an seiner Stelle:
 * der Hinweis gehoert zu den Zahlen (letzte Karte in <main>), diese Zeile
 * gehoert der Seite.
 */
.site-foot {
    padding: 8px var(--pad) 32px;
    color: var(--muted);
    font-size: 13px;
}

.site-foot a {
    color: var(--second);
    text-decoration: none;
}

.site-legal {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
}

/* Der Hinweis zum Depot - die letzte Karte, nicht die Fusszeile. */
.foot-note {
    margin: 0;
    color: var(--muted);
    font-size: 11px;
    line-height: 16px;
}

/*
 * Die Ueberschrift ueber einem Block - kein Kasten, sondern ein Wort: die
 * Karten darunter sind die Kaesten, und ein Kasten um eine Ueberschrift sieht
 * aus wie eine eigene Karte ohne Inhalt.
 *
 * Sie steht IM Block und ist dessen erstes Kind, also traegt der Abstand der
 * Spalte sie schon - der untere Rand ist negativ dagegen gerechnet, damit sie
 * an ihrer ersten Karte klebt und nicht in der Mitte haengt.
 */
.band {
    margin: 0 0 -2px;
    padding: 0 2px;
    color: var(--muted);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 1.4px;
    text-transform: uppercase;
}

/*
 * Zum Ausklappen - ALLE ZAHLER sind zwanzig Zeilen am Ende eines Blocks, der
 * schon lang ist.
 *
 * <details> und kein Knopf mit JavaScript: es klappt auch ohne auf. Der Pfeil
 * ist der des Browsers; ein eigener waere ein zweites Zeichen fuer dieselbe
 * Sache.
 */
.fold {
    margin: 0;
}

/* Die aufgeklappten Namen gehoeren zu denen darueber: kein Abstand dazwischen,
   sonst sehen sie aus wie eine zweite Liste. */
.pie > .fold .pie-list {
    margin-top: 0;
}

.pie > .fold {
    margin-top: -6px;
}

.fold-head {
    cursor: pointer;
    padding: 6px 0;
    color: var(--second);
    font-size: 13px;
    font-weight: 600;
    line-height: 18px;
}

.fold-head::marker {
    color: var(--muted);
}

.fold[open] .fold-head {
    margin-bottom: 4px;
}

/* Ein Monatsbalken: der Monatsname wird laenger als ein Waehrungscode. */
.bar-month .bar-label {
    font-variant-numeric: tabular-nums;
}

/*
 * Eine Marke hinter dem Namen - "12 J. Erhoehungen", "weniger Zahlungen als
 * gewohnt". Sie steht AN der Zeile, die sie betrifft, und darum als eigene
 * Zeile unter dem Namen statt in einer Spalte: eine Spalte, die meist leer
 * ist, sieht aus wie fehlende Daten.
 */
.row-tag {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 500;
    line-height: 15px;
}

/*
 * In einer Tabelle darf sie UMBRECHEN, der Name darueber nicht: die Zelle ist
 * nowrap, damit ein langer Name gekuerzt wird statt die Zeile zu sprengen - und
 * die graue Zeile darunter wurde davon mitgekuerzt. "mind. 29 J. Erhoehungen"
 * endete als "mind. 29 J. Erhoehun" (gemessen bei 390 px, 06.10.2026). Was
 * nicht ganz dasteht, sagt etwas anderes als das, was dasteht.
 */
.positions .col-name .row-tag {
    white-space: normal;
}

/*
 * Dieselbe Marke, wo sie ein Vorbehalt ist - heller, nicht farbig.
 *
 * NICHT ORANGE und nicht rot: die Farben dieser App haben je EINE Bedeutung,
 * und Orange ist das untere Kurslimit, Rot der Fehler (DESIGN.md §5). "Weniger
 * Zahlungen als gewohnt" ist beides nicht - es ist ein Vorbehalt, und der
 * unterscheidet sich hier durch Helligkeit von der Marke daneben, die eine
 * gute Nachricht ist.
 */
.row-tag-warn {
    color: var(--second);
}

/* Der Ausgangsbetrag unter dem umgerechneten - wo umgerechnet wurde, steht es dabei. */
.col-value-sub {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 500;
    line-height: 15px;
}

/* Was fuer ein Tag das ist, unter dem Datum: ein Zahltag ist nicht ein Ex-Tag. */
.col-when-what {
    display: block;
    margin-top: 2px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 500;
    line-height: 15px;
}

/*
 * Die Spalten der Dividendentabellen, an denselben 390 px gemessen wie die der
 * Positionen. Drei Prozentspalten und ein Betrag: zusammen 66 %, der Name
 * bekommt den Rest.
 */
/* "Rendite" ist das laengste Wort dieser Kopfzeile und braucht drei Prozent
   mehr als "YoC" - gemessen bei 390 px, wo es sonst um einen Punkt ueberlief. */
.positions .col-yield {
    width: 16%;
}

.positions .col-yoc {
    width: 15%;
}


.positions .col-when {
    width: 34%;
    text-align: right;
}

@media (min-width: 720px) {
    .wrap {
        padding: 28px var(--pad) 40px;
        gap: 12px;
    }

    .curve {
        height: 240px;
    }

    /*
     * Mehr Platz: die Zahlen bleiben, wie sie sind - aber die UEBERSCHRIFT ist
     * hier das Breiteste in der Spalte, und so breit muss die Spalte sein.
     *
     * NACHGEMESSEN (08.10.2026, Fira Text halbfett, 11 px): "seit Kauf %" misst
     * 56 px, der Sortierpfeil 12. Bei 12 % einer 520 px breiten Karte blieben
     * dem Wort 52 - 10 Polster - 12 Pfeil = 40 px, und es brach als "seit /
     * Kauf %" um, mit einem einzelnen Wort obendrueber. 16 % geben ihm 73 px,
     * und damit steht es in einer Zeile. Die Prozentspalten daneben brauchen
     * weniger (Anteil 41, Rendite 51, YoC 30) und behalten ihre Breite.
     */
    .positions .col-shares {
        width: 12%;
    }

    /* "Anteil %" misst 41 px und braucht mit Pfeil und Polster 63 - 12 % waeren
       62, und es brach um. */
    .positions .col-share {
        width: 13%;
    }

    .positions .col-gain {
        width: 16%;
    }

    .positions .col-gain-money,
    .positions .col-value {
        width: 18%;
    }

    .positions th,
    .positions td {
        padding-left: 10px;
    }
}

/*
 * Ein Block: die Karten untereinander, in ihrer Reihenfolge. Das ist der
 * Normalfall und gilt auf jeder Breite - zwei Bloecke stehen auf einem Telefon
 * untereinander, nicht nebeneinander.
 *
 * min-width: 0 ist nicht Zierde: ohne das zieht eine breite Tabelle ihre
 * Rasterspalte auf, und die andere wird schmal.
 */
.col {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}

/*
 * AB 1040 PX NEBENEINANDER: links das Depot, rechts die Dividenden.
 *
 * Genau zwei Spalten, und jede traegt ihren ganzen Block. Nicht die Karten im
 * Wechsel verteilt - das zerriss das Depot (links GESAMT, rechts VERLAUF,
 * links GEWICHTUNG) und war nicht gemeint. Darum stehen die Bloecke auch im
 * HTML als Spalten und nicht erst hier.
 *
 * Kopf und Fuss gehoeren zu beiden und laufen ueber die ganze Breite.
 *
 * `wrap-two` setzt der Erzeuger nur, wenn es wirklich zwei Bloecke gibt: ein
 * Depot ohne Dividenden steht in einer Spalte und nicht in der halben Seite.
 */
@media (min-width: 1040px) {
    /* Breiter wird die ganze Seite, nicht nur der Inhalt: die Kopfzeile und die
       Fusszeile lesen dieselbe Variable und behalten damit ihre Kante. */
    body.two {
        --page-max: 1120px;
    }

    .wrap-two {
        display: grid;
        grid-template-columns: 1fr 1fr;
        align-items: start;
        column-gap: 16px;
    }

    .wrap-two > .card-head,
    .wrap-two > .card-foot {
        grid-column: 1 / -1;
    }

    .col {
        gap: 12px;
    }
}

/*
 * AUF DEM TELEFON EINE SPUR KLEINER. Dort hat die Spalte "seit Kauf %" rund
 * 42 px, das Wort misst bei 11 px aber 56 - es muss umbrechen, und bei 11 px
 * brach es nach "seit": ein einzelnes Wort ueber der Zeile (gemeldet
 * 08.10.2026). Bei 10 px misst "seit Kauf" 41 px und passt, und die zweite
 * Zeile traegt die Einheit, wie es sich gehoert. Die Zahlen darunter bleiben,
 * wie sie sind - sie sind die Auskunft, die Ueberschrift ist ihr Name.
 */
@media (max-width: 719px) {
    .positions thead th {
        font-size: 10px;
    }
}
