/* Anwendungsspezifisches, das keiner Radzen-Komponente gehoert. Farben, Radien
   und Kurven kommen aus css/tokens.css (D21) — hier steht kein eigener Wert mehr. */

/* Sichtbar, bis die WASM-Laufzeit die Seite uebernimmt. MainLayout raeumt es weg. */
#app-loading {
    align-items: center;
    color: var(--sp-muted);
    display: flex;
    flex-direction: column;
    gap: 1rem;
    justify-content: center;
    min-height: 60vh;
    /* Kurze Ladezeiten sollen nicht blinken. */
    animation: app-loading-fade-in 0.2s ease-in 0.3s both;
}

.app-loading-spinner {
    animation: app-loading-spin 0.9s linear infinite;
    border: 3px solid var(--sp-border-strong);
    border-radius: 50%;
    border-top-color: var(--sp-accent);
    height: 2.5rem;
    width: 2.5rem;
}

@keyframes app-loading-spin {
    to { transform: rotate(360deg); }
}

@keyframes app-loading-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .app-loading-spinner { animation: none; }
    #app-loading { animation-duration: 0.01ms; }
}

/* Ohne Prerendering steht bis zum Start der Laufzeit nur dieser Platzhalter (D2). Beim ersten
   Aufruf dauert das spuerbar - der Hinweis sagt, dass das so gehoert und nicht haengt. */
.app-loading-hint {
    font-size: 0.85rem;
    color: var(--sp-faint);
    max-width: 24rem;
    text-align: center;
}

/* Felder, die das Modell nur unsicher gelesen hat, werden markiert (D4). Der Ton
   ist derselbe wie bei jeder anderen Warnung dieser Oberflaeche (D21). */
.splitpilot-low-confidence input,
.splitpilot-low-confidence .rz-inputtext,
.splitpilot-low-confidence .rz-textbox {
    background-color: var(--sp-warn-bg);
    border-color: color-mix(in srgb, var(--sp-warn) 42%, transparent);
}

#blazor-error-ui {
    background: var(--sp-warn-bg);
    color: var(--sp-text);
    border-top: 1px solid color-mix(in srgb, var(--sp-warn) 45%, transparent);
    bottom: 0;
    box-shadow: var(--sp-shadow-3);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.7rem 1.25rem 0.8rem;
    /* Der Balken klebt unten; am iPhone liegt dort der Wischstreifen (D34). */
    padding-bottom: calc(0.8rem + env(safe-area-inset-bottom, 0px));
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* Zahlen, die schwerer wiegen: uebersehene Duplikate verfaelschen den Saldo dauerhaft,
   ein falsch gelesener Betrag ebenso (D10). Fehlalarme kosten nur eine Warnung. */
.splitpilot-schwer {
    color: var(--sp-neg);
}

/* Gedaempfter Hinweistext. Nicht rz-color-secondary: das ist im Material-Theme die zweite
   Markenfarbe, und Hinweise saehen damit aus wie Fehlermeldungen. */
.splitpilot-hinweis {
    color: var(--sp-faint);
}

/* Kopfzeile eines Monats in der Eintragsliste (D14). Sie bleibt beim Scrollen stehen: bei
   einer fortlaufenden Liste ueber Jahre ist sonst nach zehn Zeilen nicht mehr klar, welcher
   Monat gerade laeuft. Deshalb traegt sie Glas und nicht nur eine Farbe: darunter laeuft
   die Liste durch, und ein deckender Balken schnitte sie hart ab. */
.splitpilot-monat {
    align-items: baseline;
    backdrop-filter: var(--sp-blur);
    -webkit-backdrop-filter: var(--sp-blur);
    background: var(--sp-glass);
    border-bottom: 1px solid var(--sp-border);
    border-radius: var(--sp-radius-sm) var(--sp-radius-sm) 0 0;
    column-gap: 0.75rem;
    display: grid;
    grid-template-areas: "name zaehler summe";
    grid-template-columns: auto minmax(0, 1fr) auto;
    padding: 0.5rem 0.75rem;
    position: sticky;
    row-gap: 0.15rem;
    top: 0;
    z-index: 2;
}

/* Ein Raster und keine Reihe, damit der Kopf am Telefon anders steht als am
   Schreibtisch (D35): dort laufen Name, Zaehler und Summe in einer Zeile, hier
   stehen Name und Summe oben — die beiden Angaben, wegen derer man hersieht —
   und die Zaehler darunter. Umgebrochen waere die Summe sonst mit den Zaehlern
   in die zweite Zeile gerutscht. */
.splitpilot-monat-name {
    grid-area: name;
}

.splitpilot-monat-zaehler {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    grid-area: zaehler;
    justify-content: flex-end;
}

.splitpilot-monat-summe {
    grid-area: summe;
}

@media (max-width: 767.98px) {
    .splitpilot-monat {
        grid-template-areas:
            "name    summe"
            "zaehler zaehler";
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .splitpilot-monat-zaehler {
        justify-content: flex-start;
    }
}

/* Eine entfernte Belegposition wird nicht geloescht, sondern durchgestrichen (D16). */
.splitpilot-zeile-entfernt {
    opacity: 0.6;
    text-decoration: line-through;
}

/* Der Vermerk am Beleg: was abgezogen wurde, steht im Bild und nicht nur daneben (D16).
   Das gespeicherte Bild bleibt dabei unangetastet - es muss lesbar bleiben (D9). */
.splitpilot-beleg {
    border-radius: var(--sp-radius);
    display: block;
    max-width: 100%;
    overflow: hidden;
    position: relative;
}

/* Der Bon selbst ist der Knopf ins Vollbild (D62) - am Telefon der kuerzeste Weg
   dorthin. Ein echter Knopf und kein Bild mit Klick: Die Tastatur erreicht ihn so,
   und der Vorleser nennt ihn.

   DER RAHMEN TRAEGT DAS SEITENVERHAELTNIS DES BILDES, als Zahl aus dem Skript. Gedreht
   tauschen Hoehe und Breite die Rollen, und ohne den Tausch raegte der quer stehende
   Bon aus der Karte oder liesse eine Luecke unter sich. Der Rueckfall 3/4 gilt nur in
   dem Augenblick, bevor gemessen ist. */
.splitpilot-beleg-flaeche {
    aspect-ratio: var(--sp-beleg-hoch, 3 / 4);
    background: none;
    border: 0;
    container-type: inline-size;
    cursor: zoom-in;
    display: block;
    padding: 0;
    position: relative;
    width: 100%;
}

.splitpilot-beleg-flaeche img {
    display: block;
    inset: 0;
    margin: auto;
    max-height: 100%;
    max-width: 100%;
    position: absolute;
}

/* Eine Vierteldrehung: umgekehrtes Verhaeltnis am Rahmen, und das Bild misst sich an
   dessen Breite statt an seiner Hoehe. 100cqw ist genau diese Breite - der Rahmen ist
   der Container. */
.splitpilot-beleg-flaeche[data-drehung="90"],
.splitpilot-beleg-flaeche[data-drehung="270"] {
    aspect-ratio: var(--sp-beleg-quer, 4 / 3);
}

.splitpilot-beleg-flaeche[data-drehung="90"] img,
.splitpilot-beleg-flaeche[data-drehung="270"] img {
    max-height: 100cqw;
    max-width: calc(100cqw * var(--sp-beleg-hoch, 0.75));
}

.splitpilot-beleg-flaeche[data-drehung="90"] img {
    transform: rotate(90deg);
}

.splitpilot-beleg-flaeche[data-drehung="180"] img {
    transform: rotate(180deg);
}

.splitpilot-beleg-flaeche[data-drehung="270"] img {
    transform: rotate(270deg);
}

.splitpilot-beleg-flaeche:focus-visible {
    outline: 2px solid var(--sp-accent);
    outline-offset: 2px;
}

/* Unter jeder Seite eines Belegs aus mehreren Fotos (D79): welche es ist, und fuer den
   Erfasser der Knopf, der sie entfernt. */
.splitpilot-beleg-seite {
    align-items: center;
    color: var(--sp-muted);
    display: flex;
    font-size: .8rem;
    gap: .5rem;
    justify-content: space-between;
    margin: .25rem 0 .75rem;
}

.splitpilot-beleg-vermerk {
    background: var(--sp-neg);
    border-radius: var(--sp-radius-sm);
    box-shadow: var(--sp-shadow-2);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 600;
    left: 0.5rem;
    line-height: 1.35;
    padding: 0.3rem 0.55rem;
    position: absolute;
    top: 0.5rem;
    max-width: calc(100% - 1rem);
}

/* Das Vollbild aus D62. Schwarz und randlos: Ein Bon liest sich auf dunklem Grund,
   und was hier zaehlt, ist das Bild - nicht die Umgebung. Es liegt ueber allem, auch
   ueber dem Fehlerbalken, weil es waehrenddessen die ganze Anwendung ist. */
.splitpilot-vollbild {
    background: #000;
    inset: 0;
    position: fixed;
    z-index: 1100;
}

/* Die Leiste liegt UEBER dem Bild und nimmt ihm keine Hoehe: Der Bon soll den ganzen
   Bildschirm haben. Der Verlauf darunter haelt die Knoepfe lesbar, auch auf einem
   hellen Bon. Oben am iPhone sitzt die Statusleiste (D34). */
.splitpilot-vollbild-leiste {
    align-items: center;
    background: linear-gradient(to bottom, rgba(0, 0, 0, .55), transparent);
    display: flex;
    gap: .5rem;
    left: 0;
    padding: .5rem .75rem 1.75rem;
    padding-top: calc(.5rem + env(safe-area-inset-top, 0px));
    /* Die Leiste selbst faengt keine Geste ab - nur ihre Knoepfe. Sonst endete jedes
       Wischen, das oben beginnt, an ihr statt am Bild. */
    pointer-events: none;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 1;
}

.splitpilot-vollbild-leiste > * {
    pointer-events: auto;
}

.splitpilot-vollbild-luecke {
    flex: 1 1 auto;
}

/* Welche Seite gerade steht (D79). Weiss auf dem Verlauf der Leiste, wie die Knoepfe daneben. */
.splitpilot-vollbild-seite {
    color: #fff;
    font-size: .875rem;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* Die Buehne faengt die Gesten. touch-action: none, weil der Browser sonst selbst
   zoomt und scrollt - und dann laeuft das Bild dem Finger hinterher. */
.splitpilot-vollbild-buehne {
    align-items: center;
    display: flex;
    inset: 0;
    justify-content: center;
    overflow: hidden;
    overscroll-behavior: contain;
    position: absolute;
    touch-action: none;
}

/* Gezoomt und geschoben wird der Schieber, gedreht das Bild darin. Zwei Angaben in
   einem transform gerieten sich in die Quere: Das Skript schriebe den Winkel weg,
   den Blazor gerade gesetzt hat. */
.splitpilot-vollbild-schieber {
    align-items: center;
    display: flex;
    justify-content: center;
    will-change: transform;
}

.splitpilot-vollbild-schieber img {
    display: block;
    max-height: 100vh;
    max-height: 100dvh;
    max-width: 100vw;
    /* Ein Bild hat eine eigene Ziehgeste. Hier stoert sie die Wischgeste. */
    -webkit-user-drag: none;
    user-select: none;
}

/* Gedreht misst sich das Bild an der anderen Kante des Fensters - sonst raegte der
   quer stehende Bon links und rechts hinaus. */
.splitpilot-vollbild-schieber[data-drehung="90"] img,
.splitpilot-vollbild-schieber[data-drehung="270"] img {
    max-height: 100vw;
    max-width: 100vh;
    max-width: 100dvh;
}

.splitpilot-vollbild-schieber[data-drehung="90"] img {
    transform: rotate(90deg);
}

.splitpilot-vollbild-schieber[data-drehung="180"] img {
    transform: rotate(180deg);
}

.splitpilot-vollbild-schieber[data-drehung="270"] img {
    transform: rotate(270deg);
}

/* Solange das Vollbild steht, scrollt die Seite darunter nicht mit. */
body.splitpilot-vollbild-offen {
    overflow: hidden;
}

/* ------------------------------------------------------------ Erfassung -- */

/* Neuer Eintrag und Eintragsmaske sind EINE Spalte, so breit wie ein Formular auf
   einem Telefon lesbar ist — dafuer ist die Anwendung gebaut (D3). Die drei Huellen
   darin (Spalte, Bild, Spalte) sind hier NICHT DA: display:contents haengt ihre
   Kinder direkt in diese Spalte, in derselben Reihenfolge wie ohne sie. Erst der
   Umbruch weiter unten macht sie zu Zellen eines Rasters (D25). */
.splitpilot-erfassung {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    max-width: 32rem;
}

.splitpilot-erfassung > .splitpilot-erfassung-spalte,
.splitpilot-erfassung > .splitpilot-erfassung-bild {
    display: contents;
}

/* Der Stapel aus D57: ein Streifen kleiner Bons, jeder mit Nummer und Loeschknopf.
   Klein genug, dass fuenf davon aufs Telefon passen, gross genug, um einen
   verwackelten zu erkennen. */
.splitpilot-belegstapel {
    align-items: flex-start;
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
}

/* Ein Beleg im Stapel (D79): seine Seiten stehen in einem gemeinsamen Rahmen, dicht an dicht.
   Dass zwei Fotos ein Bon sind, soll man sehen, bevor gespeichert ist - nicht erst in der
   Liste, wo aus dem Irrtum zwei Eintraege geworden sind. */
.splitpilot-belegstapel-beleg {
    background: var(--sp-glass);
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius-sm);
    display: flex;
    flex-direction: column;
    gap: .3rem;
    padding: .35rem;
}

.splitpilot-belegstapel-titel {
    color: var(--sp-muted);
    font-size: .75rem;
    font-weight: 600;
    line-height: 1.2;
}

.splitpilot-belegstapel-seiten {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
}

/* Das Kettenglied unten links: haengt das Foto an den Beleg davor oder loest es heraus.
   Verbunden steht es in der Akzentfarbe - der Zustand soll zu sehen sein, nicht nur der Knopf. */
.splitpilot-belegstapel-glied {
    bottom: .15rem;
    left: .15rem;
    position: absolute;
}

.splitpilot-belegstapel-glied-an {
    color: var(--sp-accent) !important;
}

.splitpilot-belegstapel-bild {
    background: var(--sp-glass);
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius-sm);
    height: 7rem;
    overflow: hidden;
    position: relative;
    width: 5rem;
}

/* cover und nicht contain: Ein Thermobon ist schmal und lang, contain liesse ihn zum
   Strich zusammenfallen. Was zaehlt, ist zu sehen, ob er scharf ist. */
.splitpilot-belegstapel-bild img {
    display: block;
    height: 100%;
    object-fit: cover;
    width: 100%;
}

/* Ein Format, das der Browser nicht skalieren kann. Der Bon ist trotzdem da, also
   steht hier ein Platzhalter und keine Luecke. */
.splitpilot-belegstapel-ersatz {
    align-items: center;
    color: var(--sp-disabled);
    display: flex;
    height: 100%;
    justify-content: center;
}

/* Die Nummer sagt, der wievielte Eintrag daraus wird — bei fuenf gleich aussehenden
   Thermobons ist sie der einzige Unterschied, den man sieht. Bei einem Beleg aus mehreren
   Fotos steht die Seite dahinter (1·2, D79). */
.splitpilot-belegstapel-nummer {
    background: var(--sp-glass-2);
    border-bottom-right-radius: var(--sp-radius-sm);
    color: var(--sp-text);
    font-size: .75rem;
    font-weight: 600;
    left: 0;
    padding: .1rem .4rem;
    position: absolute;
    top: 0;
}

.splitpilot-belegstapel-weg {
    position: absolute;
    right: .15rem;
    top: .15rem;
}

/* Waehrend ein Stapel laeuft, ist die Maske nicht zu sehen — im Dokument bleibt sie
   trotzdem (D56). Das Datei-Input darin haelt die gewaehlten Bilder: Der Browser gibt
   ihre Bytes nur ueber das Element heraus, in dem sie gewaehlt wurden.

   !important, weil sowohl .splitpilot-erfassung als auch ihre breite Fassung im Media
   Query weiter unten selbst ein display setzen — ohne das gewaenne die spaetere Regel. */
.splitpilot-verdeckt {
    display: none !important;
}

/* Ab 1200 px ist neben den 32 rem des Formulars Platz fuer den Beleg. Darunter
   bliebe ihm eine Spalte, in der ein Bon zur Briefmarke wird — deshalb greift das
   erst hier, und auch hier nur, wenn ueberhaupt ein Bild da ist: die Klasse
   .splitpilot-erfassung-breit setzen die Seiten nur dann. */
@media (min-width: 75rem) {
    .splitpilot-erfassung-breit {
        align-items: start;
        display: grid;
        grid-template-columns: minmax(0, 32rem) minmax(0, 1fr);
        max-width: 60rem;
    }

    /* Beide Spalten stehen links untereinander: Basisdaten oben, die Positionen vom
       Bon darunter. Nur das Bild wandert nach rechts, sonst nichts. */
    .splitpilot-erfassung-breit > .splitpilot-erfassung-spalte {
        display: flex;
        flex-direction: column;
        gap: 1rem;
        grid-column: 1;
    }

    /* Der Beleg steht neben BEIDEN Zeilen — er soll auf der Hoehe der Basisdaten
       beginnen und nicht erst dort, wo sie aufhoeren.

       DAS PAAR height:0 / min-height:100% IST KEIN SCHMUCK. Ein Thermobon wird in
       dieser Spalte leicht hoeher als das ganze Formular, und ein Rasterelement
       ueber zwei Zeilen verteilt, was ueber sie hinausragt, auf beide: gemessen
       standen so 88 px Luft zwischen den Basisdaten und den Positionen darunter —
       genau die Luecke, die es nicht geben soll. Mit height:0 zaehlt der Beleg bei
       der Zeilenberechnung nicht mit (die Zeilen macht allein die linke Spalte),
       und min-height:100% gibt ihm danach die volle Hoehe dieser Spalte zurueck.
       Ist der Bon laenger, wird in seiner Spalte gescrollt; sein Original steht
       ohnehin einen Klick entfernt hinter "In voller Groesse". */
    .splitpilot-erfassung-breit > .splitpilot-erfassung-bild {
        display: block;
        grid-column: 2;
        grid-row: 1 / span 2;
        height: 0;
        min-height: 100%;
        overflow-y: auto;
    }
}

/* ----------------------------------------------------------- Beleg holen -- */

/* Aufnehmen und Hochladen (D27). Sichtbar ist das Label, gedrueckt wird damit das
   Datei-Input dahinter — das bleibt im Dokument und traegt Auswahl wie Fokus.
   display:none waere der kuerzere Weg und nimmt es aus der Tab-Reihenfolge: der
   Beleg waere ohne Maus nicht mehr zu holen. */
.splitpilot-belegquellen {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.splitpilot-belegquelle-datei {
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

.splitpilot-belegquelle {
    align-items: center;
    background: var(--sp-glass-2);
    border: 1px solid var(--sp-border-strong);
    border-radius: var(--sp-radius-pill);
    color: var(--sp-text);
    cursor: pointer;
    display: inline-flex;
    font-size: .875rem;
    font-weight: 600;
    gap: .4rem;
    line-height: 1.2;
    /* Getroffen wird auf dem Telefon mit dem Daumen: 2.75 rem (44 px) ist das Mass,
       das dafuer als Untergrenze gilt. Als min-height und nicht als Polsterung —
       sonst haengt die Trefferflaeche an der Schriftgroesse. */
    min-height: 2.75rem;
    padding: .5rem 1.1rem;
    transition: background var(--sp-fast) var(--sp-ease),
                border-color var(--sp-fast) var(--sp-ease);
}

/* RadzenIcon rendert <i class="rzi">. */
.splitpilot-belegquelle .rzi {
    font-size: 1.15rem;
}

.splitpilot-belegquelle:hover {
    background: var(--sp-accent-soft);
    border-color: var(--sp-accent);
}

/* Die Kamera ist auf dem Telefon der Regelfall, die Datei die Ausnahme — das steht
   in der Farbe und nicht in der Reihenfolge allein. */
.splitpilot-belegquelle-haupt,
.splitpilot-belegquelle-haupt:hover {
    background: var(--sp-accent);
    border-color: transparent;
    color: var(--sp-on-accent);
}

.splitpilot-belegquelle-haupt:hover {
    background: var(--sp-accent-hover);
}

/* Gedrueckt wird das Label, den Fokus haelt das Input: ohne diese Regel waere mit der
   Tastatur nicht zu sehen, wo man steht. */
.splitpilot-belegquelle-datei:focus-visible + .splitpilot-belegquelle {
    box-shadow: var(--sp-glow);
    outline: none;
}

/* Ein Label vor einem gesperrten Input oeffnet von sich aus nichts. Hier steht nur,
   dass man das auch sieht. */
.splitpilot-belegquelle-datei:disabled + .splitpilot-belegquelle {
    background: var(--sp-glass);
    border-color: var(--sp-border);
    color: var(--sp-disabled);
    cursor: not-allowed;
}

/* ---------------------------------------------------------------- Marke -- */

.splitpilot-marke {
    align-items: center;
    display: flex;
    gap: .55rem;
}

/* Das Zeichen IST das App-Icon (D78) und keine zweite Zeichnung daneben: icon-bon.svg bringt
   Plaettchen, Verlauf und Bon selbst mit. Vorher stand hier ein Material-Symbol auf einem
   Verlauf aus CSS — eine Marke, die dem Icon am Startbildschirm nur aehnlich sah. */
.splitpilot-marke-zeichen {
    display: block;
    filter: drop-shadow(0 3px 6px rgba(27, 73, 101, .35));
    height: 1.9rem;
    width: 1.9rem;
}

/* ---------------------------------------------------------------- Zahlen -- */

/* Ein Betrag bricht nicht um: "€ 1.353,62" auf zwei Zeilen ist keine Zahl mehr. */
.splitpilot-betrag {
    white-space: nowrap;
}

/* DIE ZAHL DES SALDOS TRAEGT IHRE AUSSAGE IN DER FARBE. Ein Verlauf stand hier
   zuerst und war die falsche Wahl: er sass auf einem SATZ und nicht auf einer
   Zahl, er sagte nichts, und er griff nicht einmal — .rz-text-h4 setzt die Farbe
   mit derselben Spezifitaet und steht spaeter. Rot heisst "du schuldest", gruen
   "dir wird geschuldet"; ausgeglichen bleibt die gewoehnliche Textfarbe, denn
   dort gibt es nichts zu faerben. */
.splitpilot-saldo-betrag {
    font-weight: 700;
    white-space: nowrap;
}

.splitpilot-saldo-offen {
    color: var(--sp-neg);
}

.splitpilot-saldo-guthaben {
    color: var(--sp-pos);
}

/* ------------------------------------------------------------------ Liste -- */

/* Eine Zeile der Eintragsliste ist anklickbar und darf das zeigen. Die Regel
   dafuer steht in components.css und haengt an dieser Klasse — nicht an
   .rz-card, sonst wandert jede Karte der Anwendung beim Ueberfahren. */
.splitpilot-klickbar {
    cursor: pointer;
}

/* Der Monatskopf klebt oben (D14); die erste Karte darunter soll nicht darunter
   durchscheinen, bevor sie ihn erreicht. */
.splitpilot-monat + * {
    position: relative;
    z-index: 1;
}

/* Zwei Personen tragen in dieselbe Liste ein (D31). WER es war, steht als Text in der
   Zeile - das ist die Antwort, und sie liest sich auch ohne Farbe. Die Kante ist die
   Antwort fuer den ersten Blick: eine Liste wird ueberflogen, nicht gelesen.

   Gefaerbt wird nach eigen und fremd und nicht je Person. Fuer zwei Konten ist das
   dieselbe Unterscheidung, aber es ist die, die sich stellt - und sie bleibt richtig,
   ohne dass jemandem eine Farbe zugeteilt werden muesste, die er nie gewaehlt hat.

   Die Grundregel faerbt nicht, sie verbreitert nur: ohne bekannten Erfasser bleibt die
   Kante in der Randfarbe der Karte. Weglassen ginge nicht - dann stuenden diese Karten um
   drei Pixel versetzt neben den uebrigen; und durchsichtig ginge auch nicht, denn dann
   fehlte ihnen der Umriss, den .rz-card sonst rundum traegt. */
.splitpilot-erfasst {
    border-left: 3px solid var(--sp-border);
}

.splitpilot-erfasst-selbst {
    border-left-color: var(--sp-accent);
}

.splitpilot-erfasst-andere {
    border-left-color: var(--sp-accent-2);
}

/* ============================================================================
   Umbruch auf das Telefon (D35).

   Was hier steht, ist kein Umbrechen, sondern ein Umordnen: dieselben Bedienelemente
   stehen am Telefon an anderer Stelle als am Schreibtisch. Deshalb tragen die Muster
   ihre Anordnung als Raster mit benannten Feldern — die Reihenfolge im Markup ist
   dann nur noch eine, die Anordnung entscheidet die Breite. Ein umgebrochener
   Flex-Container koennte das nicht: dort bleibt die Reihenfolge, wie sie im Dokument
   steht, und die Summe rutscht mit den Zaehlern in die zweite Zeile.

   Die Grenze ist 768 px und ist bei Radzen abgelesen; warum, steht in
   css/components.css.
   ============================================================================ */

/* ---------------------------------------------------------------- Rahmen -- */

/* Die Polsterung des Inhalts an EINER Stelle, damit die Aktionsleiste weiter unten
   sie wieder herausrechnen kann, ohne den Wert zu wiederholen. */
.splitpilot-inhalt {
    --sp-inhalt-polster: 0.75rem;
    padding: var(--sp-inhalt-polster);
}

/* Ein Nebenknopf, der am Telefon nur sein Symbol traegt: "Aktualisieren" neben einer
   Ueberschrift kostet dort ein Drittel der Zeile, und das Symbol allein sagt dasselbe.
   Der Text bleibt im Markup — ohne ihn faende der Screenreader nichts —, die Seiten
   setzen zusaetzlich title und aria-label. */
@media (max-width: 767.98px) {
    .splitpilot-nur-symbol {
        min-width: 2.75rem;
        padding-inline: 0.5rem;
    }

    .splitpilot-nur-symbol .rz-button-text {
        display: none;
    }

    .splitpilot-nur-symbol .rzi {
        margin: 0;
    }
}

/* ------------------------------------------------------------ Seitenkopf -- */

/* Ueberschrift, Hauptknopf und Werkzeuge. Am Schreibtisch eine Zeile; am Telefon
   bleibt neben der Ueberschrift nur, was ein Symbol ist, und der Hauptknopf bekommt
   die ganze Breite darunter — er ist die Handlung, wegen der die Seite offen ist. */
.splitpilot-seitenkopf {
    align-items: center;
    column-gap: 0.75rem;
    display: grid;
    grid-template-areas: "titel haupt werkzeuge";
    grid-template-columns: minmax(0, 1fr) auto auto;
    row-gap: 0.5rem;
}

.splitpilot-seitenkopf-titel {
    grid-area: titel;
    min-width: 0;
}

.splitpilot-seitenkopf-haupt {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    grid-area: haupt;
}

.splitpilot-seitenkopf-werkzeuge {
    align-items: center;
    display: flex;
    gap: 0.5rem;
    grid-area: werkzeuge;
}

@media (max-width: 767.98px) {
    .splitpilot-seitenkopf {
        grid-template-areas:
            "titel werkzeuge"
            "haupt haupt";
        grid-template-columns: minmax(0, 1fr) auto;
        /* Kein row-gap: eine Seite ohne Hauptknopf haette sonst eine leere Zeile,
           die trotzdem Abstand kostet. Den Abstand traegt der Knopf selbst. */
        row-gap: 0;
    }

    .splitpilot-seitenkopf-haupt {
        margin-top: 0.75rem;
    }

    .splitpilot-seitenkopf-haupt > * {
        flex: 1 1 8rem;
    }
}

/* Die Kennzeichnung eines Messlaufs. Am Telefon nimmt sie die Zeile, die sie sich mit
   "Lauf starten" teilt — beide zusammen ergeben eine Handlung. */
.splitpilot-lauf-kennzeichnung {
    width: 12rem;
}

@media (max-width: 767.98px) {
    .splitpilot-lauf-kennzeichnung {
        width: auto;
    }
}

/* ----------------------------------------------------------- Listenzeile -- */

/* Eine Zeile der Eintragsliste und der Dauerauftragsliste: Titel mit Datum, Betrag,
   Plaketten, Knoepfe. Am Schreibtisch stehen Betrag und Knoepfe rechts uebereinander
   und die Plaketten laufen links darunter durch. Am Telefon waere die rechte Spalte
   180 px breit und dem Titel blieben 150 — deshalb wandern die Knoepfe dort in eine
   eigene Zeile unter die Plaketten und werden dabei so breit, dass man sie trifft.
   Der Betrag bleibt oben rechts: er gehoert zum Titel und wird mit ihm gelesen. */
.splitpilot-listenzeile {
    align-items: start;
    column-gap: 1rem;
    display: grid;
    grid-template-areas:
        "titel  zahl"
        "marken aktionen";
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 0.5rem;
}

.splitpilot-listenzeile-titel {
    grid-area: titel;
    min-width: 0;
}

.splitpilot-listenzeile-zahl {
    grid-area: zahl;
    text-align: right;
}

.splitpilot-listenzeile-marken {
    align-content: start;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    grid-area: marken;
}

.splitpilot-listenzeile-aktionen {
    align-self: end;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    grid-area: aktionen;
    justify-content: flex-end;
}

@media (max-width: 767.98px) {
    .splitpilot-listenzeile {
        column-gap: 0.75rem;
        grid-template-areas:
            "titel    zahl"
            "marken   marken"
            "aktionen aktionen";
    }

    .splitpilot-listenzeile-aktionen > * {
        flex: 1 1 7rem;
    }

    /* Ein Knopf, der nur ein Symbol traegt, wird nicht breit: er soll gross genug
       zum Treffen sein und nicht so aussehen, als fehle ihm die Beschriftung. */
    .splitpilot-listenzeile-aktionen > .rz-button-icon-only {
        flex: 0 0 auto;
    }
}

/* Eine Zeile ohne Betrag — die Kategorienliste. Links, was sie ist, rechts, was man
   damit tun kann; am Telefon untereinander, damit die Knoepfe die volle Breite bekommen. */
.splitpilot-listenzeile-schmal {
    grid-template-areas: "titel aktionen";
}

.splitpilot-listenzeile-schmal > .splitpilot-listenzeile-titel {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

@media (max-width: 767.98px) {
    .splitpilot-listenzeile-schmal {
        grid-template-areas:
            "titel    titel"
            "aktionen aktionen";
    }
}

/* Eine Meldung in einer Zeile — die Duplikatwarnung (D4). Am Telefon stehen ihre
   Knoepfe unter dem Text statt daneben, sonst quetschen sich drei Ziele in eine
   Zeile, von denen eines loescht. */
.splitpilot-hinweiszeile {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.splitpilot-hinweiszeile-aktionen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

@media (max-width: 767.98px) {
    .splitpilot-hinweiszeile {
        align-items: stretch;
        flex-direction: column;
    }

    .splitpilot-hinweiszeile-aktionen > * {
        flex: 1 1 7rem;
    }
}

/* ----------------------------------------------------------------- Frage -- */

/* Eine Frage statt sechs Filter (D59). Das Feld nimmt, was da ist, der Knopf nur, was
   er braucht — ein Satz ist laenger als ein Suchbegriff, und er soll ganz zu lesen
   sein. Am Telefon stehen beide untereinander: Nebeneinander blieben dem Satz 150 px,
   und der Knopf waere zu schmal fuer einen Daumen (D35). */
.splitpilot-frage {
    align-items: center;
    display: flex;
    gap: 0.5rem;
}

.splitpilot-frage-feld {
    flex: 1 1 auto;
    min-width: 0;
}

@media (max-width: 767.98px) {
    .splitpilot-frage {
        align-items: stretch;
        flex-direction: column;
    }
}

/* ------------------------------------------------------------------ Satz -- */

/* Erfassen in einem Satz (D60). Dieselbe Zeile wie die Frage ueber der Liste (D59):
   Das Feld nimmt, was da ist, die Knoepfe nur, was sie brauchen. Am Telefon stehen
   sie untereinander — nebeneinander blieben dem Satz mit Mikrofon und Knopf keine
   150 px mehr (D35). */
.splitpilot-satz {
    align-items: center;
    display: flex;
    gap: 0.5rem;
}

.splitpilot-satz-feld {
    flex: 1 1 auto;
    min-width: 0;
}

@media (max-width: 767.98px) {
    .splitpilot-satz {
        align-items: stretch;
        flex-direction: column;
    }
}

/* ---------------------------------------------------------------- Filter -- */

/* Sechs Auswahlfelder nebeneinander sind auf 390 px eine Kolonne, durch die man sich
   bis zur Liste scrollt — und meistens filtert niemand (D35). Am Telefon steht
   deshalb nur ein Knopf da, der sagt, wie viel gerade gefiltert wird; die Felder
   klappen darunter auf und stehen dann untereinander, jedes ueber die volle Breite.
   Am Schreibtisch bleibt die Zeile, wie sie war, und der Knopf ist nicht da. */
.splitpilot-filter {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.splitpilot-filter-schalter {
    display: none;
}

.splitpilot-filter-feld {
    width: 11rem;
}

.splitpilot-filter-datum {
    width: 9rem;
}

.splitpilot-filter-schalterfeld {
    align-items: center;
    display: flex;
    gap: 0.5rem;
}

@media (max-width: 767.98px) {
    .splitpilot-filter {
        display: none;
    }

    .splitpilot-filter-offen {
        align-items: stretch;
        display: flex;
        flex-direction: column;
        gap: 0.75rem;
        margin-top: 0.75rem;
    }

    .splitpilot-filter-feld,
    .splitpilot-filter-datum {
        width: 100%;
    }

    .splitpilot-filter-schalter {
        display: inline-flex;
        width: 100%;
    }
}

/* ---------------------------------------------------------- Aktionsleiste -- */

/* Speichern, Bestaetigen, Loeschen, Zurueck. Am Schreibtisch eine Zeile in dieser
   Reihenfolge — die das Raster macht und nicht das Markup, denn am Telefon ist die
   Reihenfolge umgekehrt: dort stehen die Nebenwege im Fluss, und die Hauptwege
   kleben als Leiste am unteren Rand.

   DER GRUND IST DIE LAENGE DER MASKE. Der Eintrag hat acht Felder, den Beleg und die
   Positionen darunter; "Speichern" lag damit zwei Bildschirme unter dem Feld, das man
   gerade geaendert hat. Loeschen bleibt bewusst DRAUSSEN: ein Knopf, der dauerhaft
   unter dem Daumen liegt, soll nichts vernichten koennen.

   position:sticky braucht einen Kasten, in dem es sich bewegen kann. Als Rasterzelle
   haette die Leiste genau ihre eigene Groesse und stuende still — deshalb loest sich
   die Huelle am Telefon in display:contents auf, und die beiden Gruppen haengen
   direkt in der Spalte der Seite, die so lang ist wie das Formular. */
.splitpilot-aktionen {
    column-gap: 0.5rem;
    display: grid;
    grid-template-areas: "haupt neben";
    grid-template-columns: auto auto;
    justify-content: start;
    row-gap: 0.5rem;
}

.splitpilot-aktionen-haupt {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    grid-area: haupt;
}

.splitpilot-aktionen-neben {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    grid-area: neben;
}

@media (max-width: 767.98px) {
    .splitpilot-aktionen {
        display: contents;
    }

    .splitpilot-aktionen-neben > * {
        flex: 1 1 7rem;
    }

    /* Nur, wenn ueberhaupt Platz ist. Quer gehalten bleiben von einem Telefon rund
       350 px Hoehe — eine feste Leiste naehme davon ein Siebtel und stuende dann im
       Weg, statt zu helfen. */
    @media (min-height: 30rem) {
        .splitpilot-aktionen-haupt {
            backdrop-filter: var(--sp-blur);
            -webkit-backdrop-filter: var(--sp-blur);
            background: var(--sp-glass);
            border-top: 1px solid var(--sp-border);
            bottom: 0;
            margin-bottom: calc(-1 * var(--sp-inhalt-polster, 0.75rem));
            margin-inline: calc(-1 * var(--sp-inhalt-polster, 0.75rem));
            padding: 0.75rem;
            /* Der Rumpf polstert unten schon um den Wischstreifen herum (D34); die
               Leiste klebt aber an der Unterkante seines Polsterkastens und liegt
               damit wieder darueber. Also noch einmal, hier. */
            padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
            position: sticky;
            z-index: 3;
        }
    }

    .splitpilot-aktionen-haupt > * {
        flex: 1 1 8rem;
    }
}

/* --------------------------------------------------------------- Formular -- */

/* Felder, die zusammengehoeren, stehen in einer Zeile. Am Telefon bleibt gepaart, was
   kurz ist und zusammen gelesen wird ("alle 3 Monate"); alles andere bekommt die
   ganze Breite. Ein Datumsfeld gehoert dazu: dd.MM.yyyy und der Kalenderknopf fuellen
   eine halbe Telefonbreite bereits aus. */
.splitpilot-felder-kategorie {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr);
}

.splitpilot-felder-takt {
    align-items: end;
    display: grid;
    gap: 0.75rem;
    grid-template-columns: minmax(0, 1fr) 8rem;
}

.splitpilot-felder-zeitraum {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

@media (max-width: 767.98px) {
    .splitpilot-felder-kategorie {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }

    /* Der Name des Symbols wird getippt und ist lang; Farbe und Reihung sind kurz
       und stehen nebeneinander. */
    .splitpilot-felder-kategorie > :first-child {
        grid-column: 1 / -1;
    }

    .splitpilot-felder-takt {
        grid-template-columns: minmax(0, 1fr) 6rem;
    }

    .splitpilot-felder-zeitraum {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Eine Staffel eines Dauerauftrags (D13): ab wann, wie viel, wozu, und weg damit.
   Am Telefon wird aus der Zeile ein Block aus zwei Zeilen — vier Felder nebeneinander
   waeren dort vier angeschnittene Felder. */
.splitpilot-staffel {
    align-items: center;
    display: grid;
    gap: 0.5rem;
    grid-template-areas: "datum betrag notiz weg";
    grid-template-columns: 9rem 7rem minmax(0, 1fr) auto;
}

.splitpilot-staffel > * {
    width: 100%;
}

.splitpilot-staffel-datum  { grid-area: datum; }
.splitpilot-staffel-betrag { grid-area: betrag; }
.splitpilot-staffel-notiz  { grid-area: notiz; }

.splitpilot-staffel-weg {
    grid-area: weg;
    justify-self: end;
    width: auto;
}

@media (max-width: 767.98px) {
    .splitpilot-staffel {
        grid-template-areas:
            "datum betrag"
            "notiz weg";
        /* Der Betrag darf schmaler sein als das Datum: "1 032,50" ist kuerzer als
           "01.01.2025" samt Kalenderknopf. Auf einem 320 px breiten Bildschirm fiel
           sonst die Jahreszahl hinter dem Knopf ab. */
        grid-template-columns: minmax(0, 1fr) 6.5rem;
    }

    /* Ohne Trennung liefen drei Staffeln zu einem Feld aus sechs Kaesten zusammen. */
    .splitpilot-staffel + .splitpilot-staffel {
        border-top: 1px solid var(--sp-border);
        padding-top: 0.75rem;
    }
}

/* Eine gelesene Position am Bon (D16). Text, Preis, und der Knopf, der sie abzieht.
   Die Zeile bleibt auch am Telefon eine Zeile — ein Bon hat dreissig davon, und
   jede auf zwei Zeilen waere eine Seite, durch die man sich wischt. Der Text nimmt,
   was uebrig bleibt, und bricht um; der Knopf traegt dort nur sein Symbol. */
.splitpilot-belegzeile {
    align-items: center;
    column-gap: 0.5rem;
    display: grid;
    grid-template-areas: "text betrag kategorie aktion";
    grid-template-columns: minmax(0, 1fr) auto auto auto;
}

.splitpilot-belegzeile-text   { grid-area: text; min-width: 0; }

/* Die Position selbst ist der Knopf in ihre Maske (D76) - wie der Bon der Knopf ins
   Vollbild ist (D62). Ein Stift je Zeile waere das dritte Symbol neben Kategorie und
   Abziehen, und am Telefon bliebe fuer den Text nichts uebrig.

   Er sieht aus wie der Text, den er traegt: kein Rahmen, keine Flaeche, dieselbe
   Schrift. Sichtbar wird er beim Ueberfahren und beim Tabben - dreissig hervorgehobene
   Zeilen waeren ein Formular und keine Liste. Ausgegraut wird er nicht, solange
   gespeichert wird: Das Durchgestrichene einer abgezogenen Zeile traegt schon eine
   Bedeutung, und eine zweite Blasstufe darueber liesse beide unklar. */
.splitpilot-zeilenknopf {
    background: none;
    border: 0;
    border-radius: var(--sp-radius);
    color: inherit;
    cursor: pointer;
    font: inherit;
    margin-inline-start: -0.25rem;
    overflow-wrap: anywhere;
    padding: 0.1rem 0.25rem;
    text-align: start;
}

.splitpilot-zeilenknopf:hover {
    background: var(--sp-tint-2);
}

.splitpilot-zeilenknopf:focus-visible {
    outline: 2px solid var(--sp-accent);
    outline-offset: 1px;
}

.splitpilot-zeilenknopf:disabled {
    cursor: default;
}

/* Der Loeschknopf in der Positionsmaske (D76): am anderen Ende der Leiste als
   "Uebernehmen" und "Abbrechen". Was eine Zeile vernichtet, soll nicht neben dem
   liegen, was man am haeufigsten drueckt - dieselbe Ueberlegung wie bei "Loeschen",
   das aus der Leiste am unteren Rand herausgehalten ist (D35). */
.splitpilot-schieb-rechts {
    margin-inline-start: auto;
}
.splitpilot-belegzeile-betrag { grid-area: betrag; white-space: nowrap; }
.splitpilot-belegzeile-aktion { grid-area: aktion; }

/* Die eigene Kategorie einer Position (D69). Ein Zeichen und kein Auswahlfeld: Der Regelfall
   ist "wie der Eintrag", und dreissig Felder machten aus der Zeile am Telefon eine Seite.

   Es steht HINTER dem Betrag: Der ist verschieden lang, und davor saesse das Zeichen in jeder
   Zeile woanders. Hinter ihm - vor dem gleich breiten Knopf am Rand - stehen alle Zeichen
   untereinander.

   Kein gefuellter Hintergrund und keine gefuellte Zeichnung: Der Knopf ist durchsichtig, und
   das Symbol bleibt sein Umriss. Radzens Icon-Schrift ist eine variable Schrift - die Achse
   FILL entscheidet ueber die Fuellung, und 0 ist der Umriss. Gefuellt neben dreissig Zeilen
   waere es ein Farbklecks und keine Auskunft. */
.splitpilot-belegzeile-kategorie {
    --rz-icon-fill: 0;
    grid-area: kategorie;
    min-width: 0;
    opacity: 0.8;
    padding: 0 0.15rem;
}

.splitpilot-belegzeile-kategorie:hover,
.splitpilot-belegzeile-kategorie:focus-visible {
    opacity: 1;
}

/* So spezifisch wie Radzens eigene Regel und danach geladen: Der Knopf traegt kein Feld,
   auch wenn eine Vorgabe sich aendert. Die Rueckmeldung beim Ueberfahren bleibt Radzens. */
.splitpilot-belegzeile .rz-button.splitpilot-belegzeile-kategorie {
    background: transparent;
    box-shadow: none;
}

/* Der Umriss, unabhaengig von der Achsenvorgabe des Themas. */
.splitpilot-belegzeile-kategorie .rzi {
    font-variation-settings: "FILL" 0;
}

/* Die zwei Knopfleisten ueber der Auswertung (D41/D48): Gruppe und Jahr. Der Name
   steht davor und nicht darueber — zwei Leisten, die beide mit "Alle" beginnen,
   sind sonst nicht auseinanderzuhalten. Er bekommt eine feste Breite, damit die
   Leisten darunter buendig anfangen.

   min-width:0 an der Leiste ist noetig, sonst waechst das Flex-Element mit seinem
   Inhalt statt zu scrollen — bei zehn Jahren schiebt es die Seite in die Breite. */
.splitpilot-leiste {
    align-items: center;
    display: flex;
    gap: 0.75rem;
    min-width: 0;
}

.splitpilot-leiste-name {
    flex: 0 0 auto;
    width: 3.2rem;
}

.splitpilot-leiste > .splitpilot-gruppenleiste {
    flex: 1 1 auto;
    /* Der volle Anschlag am Rand gilt nur der Leiste, die allein steht — hier
       beginnt sie neben ihrem Namen. */
    margin: 0;
    min-width: 0;
    padding: 0;
}

/* ------------------------------------------------------------- Diagramme -- */

/* Die zwei Diagramme der Auswertung (D48). Radzen misst die Hoehe an seinem
   Behaelter; ohne eine gesetzte faellt es auf seine eigenen 300 px zurueck, und
   die passen weder zu einem Telefon noch zu acht Kategorien. Die Balkenkarte
   setzt ihre Hoehe zusaetzlich am Element — sie waechst mit der Zahl der Zeilen. */
.splitpilot-diagramm {
    height: 18rem;
    min-width: 0;
}

.splitpilot-diagramm .rz-chart {
    height: 100%;
}

@media (max-width: 767.98px) {
    .splitpilot-diagramm {
        height: 15rem;
    }

    /* Am Telefon (D35) tragen sechs Werte nebeneinander; zwoelf schieben sich uebereinander
       und aus der Linie wird eine Wolke aus Zahlen (D72). Die Klasse setzt der Client, wenn es
       zu viele Punkte sind - wie breit das Fenster ist, weiss nur das Stylesheet. Der Wert
       geht damit nicht verloren: Er steht am Zeiger auf dem Punkt. */
    .splitpilot-diagramm-gedraengt .rz-series-data-label-group {
        display: none;
    }
}

/* --------------------------------------------------------------- Artikel -- */

/* Der Reiter "Artikel" neben der Trefferliste (D58). Je Haendler der zuletzt
   gezahlte Preis, nebeneinander: Sie werden verglichen und nicht gelesen, und
   untereinander waere jeder Vergleich ein Sprung mit dem Auge. Am Telefon
   brechen sie um, statt sich auf 90 px zu quetschen (D35). */
.splitpilot-preise {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem 1.5rem;
}

.splitpilot-preis {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
}

/* Eine gefundene Bonzeile: Text und Preis nebeneinander, wie in der Eintragsliste.
   Der Preis rechts, weil dort die Betraege dieser Anwendung stehen und die Spalte
   damit von selbst untereinander liegt. */
.splitpilot-bonzeile {
    align-items: baseline;
    border-bottom: 1px solid var(--sp-border);
    display: flex;
    gap: .75rem;
    justify-content: space-between;
    padding-bottom: .5rem;
}

.splitpilot-bonzeile:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

.splitpilot-bonzeile-text {
    min-width: 0;
}

.splitpilot-bonzeile-preis {
    flex: 0 0 auto;
}

/* ------------------------------------------------------------- Nachschub -- */

/* Eine Zeile des Einkaufszettels (D70): Kaestchen, Artikel, Frist. Das ganze Feld
   ist ein <label> und damit das Ziel des Fingers - 44 px hoch, weil darunter am
   Telefon danebengetippt wird (D35), und mit einer Hand am Einkaufswagen erst recht. */
.splitpilot-nachschub-zeile {
    align-items: center;
    cursor: pointer;
    display: flex;
    gap: .75rem;
    min-height: 44px;
    padding: .25rem 0;
}

/* Der Zeiger kommt nicht ans Kaestchen heran: Geklickt wird die Zeile, und der
   Schalter zeigt nur, wie es steht. Sonst zaehlte ein Klick auf das Kaestchen
   zweimal - einmal dort und einmal an der Zeile darum. Die Tastatur ist davon
   nicht betroffen: Fokus und Leertaste bedienen ihn weiterhin selbst. */
.splitpilot-nachschub-zeile .rz-chkbox {
    pointer-events: none;
}

.splitpilot-nachschub-text {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: .1rem;
    min-width: 0;
}

/* Abgehakt wird durchgestrichen und blasser, aber nicht ausgeblendet: Wer sich
   vertippt, muss die Zeile wiederfinden. */
.splitpilot-nachschub-erledigt {
    opacity: .6;
    text-decoration: line-through;
}

.splitpilot-nachschub-frist {
    flex: 0 0 auto;
}

/* ------------------------------------------------------------- Kennzahlen -- */

/* Die vier Zahlen unter dem Saldo. Am Schreibtisch eine Reihe mit ihren natuerlichen
   Breiten, am Telefon ein Raster aus zwei Spalten: umgebrochen standen sie sonst
   ungleich verteilt untereinander, mal zwei, mal eine je Zeile. */
.splitpilot-kennzahlen {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
}

@media (max-width: 767.98px) {
    .splitpilot-kennzahlen {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

/* --------------------------------------------------------------- Aufteilung -- */

/* Ein Regler je Beteiligtem (D37). Der Aufbau ist bewusst untereinander und nicht
   nebeneinander: am Telefon ist eine Zeile 390 px breit, und Name, Prozent, Betrag
   und Regler nebeneinander waeren vier Spalten zu je 90 px. */
.splitpilot-anteil {
    display: flex;
    flex-direction: column;
    gap: .2rem;
}

.splitpilot-anteil + .splitpilot-anteil {
    margin-top: .35rem;
}

.splitpilot-anteil-kopf {
    align-items: baseline;
    display: flex;
    gap: .5rem;
    justify-content: space-between;
    min-width: 0;
}

.splitpilot-anteil-name {
    color: var(--sp-text);
    font-weight: 500;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.splitpilot-anteil-werte {
    align-items: baseline;
    display: flex;
    flex: 0 0 auto;
    gap: .5rem;
}

/* Prozent und Betrag stehen in der Ziffernschrift: sie werden verglichen, nicht gelesen,
   und tabellarische Ziffern springen beim Ziehen am Regler nicht in der Breite. */
.splitpilot-anteil-prozent {
    color: var(--sp-muted);
    font-family: var(--sp-font-num);
    font-size: .82rem;
    font-variant-numeric: tabular-nums;
}

.splitpilot-anteil-betrag {
    color: var(--sp-text);
    font-family: var(--sp-font-num);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* Der Griff des Reglers ist die Trefferflaeche fuer den Daumen. Radzen gibt ihm 1rem;
   44 px gelten als Untergrenze, und die Bahn darf dabei duenn bleiben. */
.splitpilot-anteil .rz-slider {
    margin: .35rem 0;
}

.splitpilot-anteil .rz-slider-handle {
    height: 1.5rem;
    margin-top: -.75rem;
    width: 1.5rem;
}

.splitpilot-anteil .rz-slider-handle::after {
    content: "";
    inset: -.6rem;
    position: absolute;
}

/* ------------------------------------------------------------- Mitglieder -- */

/* Ein Mitglied einer Gruppe als Chip (D36): Name, dahinter der Vermerk „Gast" fuer wen
   kein Konto hat, und was bisher auf ihn entfallen ist. */
.splitpilot-mitglied {
    align-items: baseline;
    background: var(--sp-accent-soft);
    border-radius: var(--sp-radius-pill);
    display: inline-flex;
    gap: .4rem;
    padding: .2rem .7rem;
}

.splitpilot-mitglied-name {
    color: var(--sp-text);
    font-weight: 500;
}

.splitpilot-mitglied-gast {
    color: var(--sp-faint);
    font-size: .75rem;
}

.splitpilot-mitglied-betrag {
    color: var(--sp-muted);
    font-family: var(--sp-font-num);
    font-size: .8rem;
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ Titelzeile -- */

/* Die Titelzeile eines Eintrags (D42). Sie traegt drei Dinge in einer Zeile: die
   Bezeichnung, ein Zeichen dafuer, dass ein Bon dranhaengt, und die Gruppe. Vorher
   standen die letzten beiden als Abzeichen in der Reihe darunter — dort standen bis
   zu sieben nebeneinander, und keines fiel mehr auf. */
.splitpilot-titel {
    align-items: baseline;
    display: flex;
    gap: .4rem;
    min-width: 0;
}

/* Die Bezeichnung darf brechen, aber nicht die Zeile sprengen: auf 390 px ist sie
   oft laenger als die Karte breit. */
.splitpilot-titel-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Der Bon als Zeichen und nicht als Wort. Er steht an sehr vielen Eintraegen — als
   Text waere er Rauschen, als Symbol ist er zu ueberfliegen. */
.splitpilot-titel-beleg {
    color: var(--sp-faint);
    flex: 0 0 auto;
    font-size: 1.05rem;
}

/* Wie viele Seiten der Beleg hat (D79) - nur ab zweien, und so leise wie das Zeichen davor. */
.splitpilot-titel-seiten {
    color: var(--sp-faint);
    flex: 0 0 auto;
    font-size: .75rem;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    margin-left: -.2rem;
}

/* Die Gruppe: kleiner als der Titel und in der zweiten Akzentfarbe, damit auf den
   ersten Blick klar ist, dass hier nicht die Bezeichnung weitergeht. Kein Abzeichen —
   ein Rahmen drumherum waere wieder das, was aus der Reihe darunter wegsollte. */
.splitpilot-titel-split {
    color: var(--sp-accent-2);
    flex: 0 1 auto;
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .02em;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Vor der Gruppe ein feiner Trenner statt eines Abstands allein: sonst liest sie sich
   als Fortsetzung des Titels. */
.splitpilot-titel-split::before {
    color: var(--sp-border-strong);
    content: "·";
    margin-right: .35rem;
}

/* Am Telefon bekommt die Gruppe eine eigene Zeile unter dem Titel (D43). Nebeneinander
   bleiben der Titelspalte neben dem Betrag rund 240 px, und beide Texte kuerzen sich
   gegenseitig weg: aus "Kino" wird "Ki…", aus der Gruppe "WG L…". Dazu kommt, was den
   Ausschlag gab: endet die Bezeichnung mit Auslassungspunkten, steht die Gruppe
   unmittelbar dahinter und liest sich als deren Fortsetzung — der Trenner ist dafuer
   zu fein, und wo kein Bon-Zeichen dazwischensteht, klebt sie am abgeschnittenen Titel. */
@media (max-width: 767.98px) {
    /* Ein Raster und kein umbrechendes Flexbox: umgebrochen wandert das Bon-Zeichen
       mit in die zweite Zeile, sobald die Bezeichnung die erste fuellt — es gehoert
       aber neben sie. Im Raster steht es fest in der zweiten Spalte. */
    .splitpilot-titel {
        display: grid;
        grid-template-columns: minmax(0, max-content) max-content;
        row-gap: .15rem;
    }

    /* Die zweite Zeile, und zwar immer — nicht erst bei Platznot: sonst stuende die
       Gruppe mal neben und mal unter dem Titel, je nachdem wie lang die Bezeichnung
       gerade ist, und man sucht sie beim zweiten Blick. Sie steht in der ersten Spalte
       und ueberspannt nicht beide: ein Element ueber zwei Spalten mit Inhalt bemessener
       Breite zieht die zweite mit auf, und die gehoert dem Bon-Zeichen allein. */
    .splitpilot-titel-split {
        grid-column: 1;
        grid-row: 2;
    }

    /* Der Trenner faellt weg: er trennt innerhalb einer Zeile, am Zeilenanfang waere er
       ein Satzzeichen ohne Aufgabe. Was die Gruppe vom Titel unterscheidet, tragen hier
       Groesse und Farbe allein — dafuer waren sie nach D42 ohnehin da. */
    .splitpilot-titel-split::before {
        content: none;
    }
}

/* Der Export haengt als gewoehnlicher Link in der Kopfzeile (D40) und soll dort wie
   die Knoepfe daneben aussehen — nicht wie ein Wort im Fliesstext. */
.splitpilot-export {
    align-items: center;
    display: inline-flex;
    height: 2.25rem;
    justify-content: center;
    width: 2.25rem;
}

/* ---------------------------------------------------------------- Pager -- */

/* Der Pager steht oben und unten (D39). Oben traegt er die Zusammenfassung und die
   Auswahl der Seitengroesse; auf dem Telefon soll das umbrechen duerfen, statt in
   einer Zeile zu quetschen. */
.rz-paginator {
    flex-wrap: wrap;
    gap: .35rem .5rem;
    row-gap: .35rem;}

/* Die Gruppenleiste der Auswertung (D41). Sie scrollt seitlich statt umzubrechen:
   umgebrochen stuende "Alle" allein in einer Zeile, und die Gruppen darunter saehen
   aus wie eine zweite Leiste. Der Schleier am Rand sagt, dass es weitergeht. */
.splitpilot-gruppenleiste {
    -webkit-overflow-scrolling: touch;
    margin: 0 calc(-1 * var(--sp-rand, 0px));
    overflow-x: auto;
    padding: 0 var(--sp-rand, 0px);
    scrollbar-width: thin;
}

/* .rz-selectbar und nicht .rz-selectbutton: So heisst die Leiste in Radzen 11.
   Der alte Name traf nichts, und die Regel darunter hat nie gegriffen — auf dem
   Telefon brach die Leiste um, statt zu scrollen. */
.splitpilot-gruppenleiste .rz-selectbar {
    flex-wrap: nowrap;
    width: max-content;
}

/* Geld, das hereinkam (D82): Vorzeichen und Farbe am Betrag und an der Zeile des Monatskopfs. */
.splitpilot-eingang {
    color: var(--sp-pos) !important;
}

/* Der Schalter Ausgabe | Eingang | An Person (D82): am Telefon über die ganze Breite, damit
   jede Stellung mit dem Daumen zu treffen ist. */
.splitpilot-art {
    display: flex;
    flex-wrap: wrap;
    max-width: 100%;
}

@media (max-width: 640px) {
    .splitpilot-art {
        width: 100%;
    }

    .splitpilot-art .rz-button {
        flex: 1 1 0;
        min-width: 0;
    }
}

.splitpilot-ausgang {
    color: var(--sp-neg) !important;
}

/* ============================================================================
   Statistik (D82). Die Diagramme sind von Hand gezeichnetes SVG; Text und Gitter
   tragen die Tokens, die Flächen ihre Farben aus StatisticsCharts.
   ============================================================================ */
.splitpilot-statistik-filter {
    align-items: center;
    /* Fast deckend: Beim Scrollen laufen die Diagramme darunter durch, und ihre Zahlen sollen
       nicht durch die Kennzahlen scheinen. */
    background: color-mix(in srgb, var(--sp-bg) 94%, transparent);
    border: 1px solid var(--sp-border);
    border-radius: var(--sp-radius);
    display: flex;
    flex-wrap: wrap;
    gap: .6rem 1rem;
    padding: .65rem .8rem;
    position: sticky;
    top: 0;
    z-index: 3;
    -webkit-backdrop-filter: var(--sp-blur);
    backdrop-filter: var(--sp-blur);
}

.splitpilot-statistik-schritte {
    display: flex;
    gap: .25rem;
}

.splitpilot-statistik-kennzahlen {
    color: var(--sp-muted);
    display: flex;
    flex-wrap: wrap;
    font-size: .875rem;
    gap: .25rem 1rem;
    margin-left: auto;
}

.splitpilot-statistik-kennzahlen b {
    color: var(--sp-text);
    font-family: var(--sp-font-num);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.splitpilot-statistik-raster {
    align-items: start;
    display: grid;
    gap: 1rem;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.splitpilot-statistik-breit {
    grid-column: 1 / -1;
}

@media (max-width: 900px) {
    .splitpilot-statistik-raster {
        grid-template-columns: minmax(0, 1fr);
    }

    .splitpilot-statistik-kennzahlen {
        margin-left: 0;
    }
}

/* Am Telefon bricht die Filterzeile auf vier Zeilen um und deckte klebend ein Drittel des
   Bildschirms zu (D84). Dort scrollt sie mit; zurück nach oben ist ein Wisch. */
@media (max-width: 640px) {
    .splitpilot-statistik-filter {
        position: static;
    }
}

.splitpilot-statistik-karte {
    display: grid;
    gap: .75rem;
    min-width: 0;
}

.splitpilot-statistik-grafik svg {
    display: block;
    height: auto;
    width: 100%;
}

/* Breite Grafiken scrollen am Telefon in sich, statt die Beschriftung unlesbar klein zu rechnen. */
.splitpilot-statistik-quer {
    overflow-x: auto;
}

.splitpilot-statistik-quer svg {
    min-width: 620px;
}

.splitpilot-statistik svg text {
    fill: var(--sp-muted);
    font-family: var(--sp-font);
    font-size: 11px;
}

.splitpilot-statistik svg text.splitpilot-statistik-name {
    fill: var(--sp-text);
    font-weight: 600;
}

.splitpilot-statistik svg text.splitpilot-statistik-zahl {
    font-family: var(--sp-font-num);
}

.splitpilot-statistik svg text.splitpilot-statistik-kachel {
    fill: #ffffff;
    font-size: 12px;
    font-weight: 600;
    pointer-events: none;
}

.splitpilot-statistik-gitter {
    stroke: var(--sp-border);
}

.splitpilot-statistik-mitte {
    fill: var(--sp-accent);
}

/* Über eine Fläche fahren hebt sie hervor und lässt die übrigen zurücktreten. */
.splitpilot-statistik svg:hover .splitpilot-statistik-marke {
    opacity: .55;
}

.splitpilot-statistik svg .splitpilot-statistik-marke:hover {
    opacity: 1;
}

@media (prefers-reduced-motion: no-preference) {
    .splitpilot-statistik-marke {
        transition: opacity var(--sp-fast) var(--sp-ease);
    }
}

.splitpilot-statistik-legende {
    color: var(--sp-muted);
    display: flex;
    flex-wrap: wrap;
    font-size: .8rem;
    gap: .3rem 1rem;
}

.splitpilot-statistik-legende span {
    align-items: center;
    display: inline-flex;
    gap: .4rem;
}

.splitpilot-statistik-legende i,
.splitpilot-statistik-farbe {
    background: var(--farbe);
    border-radius: 3px;
    display: inline-block;
    flex: none;
    height: 10px;
    width: 10px;
}

.splitpilot-statistik-farbe {
    margin-right: .5rem;
    vertical-align: -1px;
}

.splitpilot-statistik-legende i.schraffiert,
.splitpilot-statistik-farbe.schraffiert {
    background: repeating-linear-gradient(45deg, var(--farbe) 0 2px, transparent 2px 4px);
}

.splitpilot-statistik-legende i.gestrichelt {
    background: transparent;
    border: 1.5px dashed var(--farbe);
}

.splitpilot-statistik-tabelle {
    border-collapse: collapse;
    font-size: .9rem;
    width: 100%;
}

.splitpilot-statistik-tabelle th {
    border-bottom: 1px solid var(--sp-border-strong);
    color: var(--sp-muted);
    font-size: .75rem;
    font-weight: 500;
    letter-spacing: .04em;
    padding: .35rem .5rem;
    text-align: left;
    text-transform: uppercase;
}

.splitpilot-statistik-tabelle td {
    border-bottom: 1px solid var(--sp-border);
    padding: .4rem .5rem;
}

.splitpilot-statistik-tabelle .zahl {
    font-family: var(--sp-font-num);
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

.splitpilot-statistik-tabelle tr.summe td {
    background: var(--sp-tint);
    font-weight: 600;
}

.splitpilot-statistik-tabelle td.balken {
    width: 40%;
}

.splitpilot-statistik-tabelle td.balken div {
    border-radius: 0 4px 4px 0;
    height: 8px;
}

/* Der Weg in die Liste (D84): Was sich antippen lässt, zeigt es am Zeiger. */
.splitpilot-statistik-link {
    cursor: pointer;
}

.splitpilot-statistik-link:focus-visible {
    outline: 2px solid var(--sp-accent);
    outline-offset: 2px;
}

.splitpilot-statistik-zeilenlink {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: var(--sp-border-strong);
    text-underline-offset: 3px;
}

.splitpilot-statistik-zeilenlink:hover,
.splitpilot-statistik-zeilenlink:focus-visible {
    color: var(--sp-accent);
    text-decoration-color: currentColor;
}

/* ============================================================================
   Kalender-Heatmap (D84). Eine Farbe von hell nach dunkel (--sp-heat-*), Stufe 0
   ist ein Tag ohne Ausgabe. Monat als Kalenderblatt, Jahr als Raster aus Wochen.
   ============================================================================ */
.splitpilot-heat-0 { background: var(--sp-heat-0); }
.splitpilot-heat-1 { background: var(--sp-heat-1); }
.splitpilot-heat-2 { background: var(--sp-heat-2); }
.splitpilot-heat-3 { background: var(--sp-heat-3); }
.splitpilot-heat-4 { background: var(--sp-heat-4); color: #ffffff !important; }
.splitpilot-heat-5 { background: var(--sp-heat-5); color: #ffffff !important; }

:root[data-theme="dark"] .splitpilot-heat-5 { color: #06222E !important; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .splitpilot-heat-5 { color: #06222E !important; }
}

.splitpilot-heat-tag {
    border-radius: 6px;
    color: var(--sp-text);
    text-decoration: none;
}

a.splitpilot-heat-tag:hover,
a.splitpilot-heat-tag:focus-visible {
    outline: 2px solid var(--sp-accent);
    outline-offset: 1px;
}

.splitpilot-heat-tag.heute {
    box-shadow: inset 0 0 0 2px var(--sp-accent);
}

.splitpilot-heat-tag.zukunft {
    border: 1px dashed var(--sp-border);
    color: var(--sp-disabled);
}

.splitpilot-heat-monat {
    display: grid;
    gap: 4px;
    grid-template-columns: repeat(7, minmax(0, 1fr));
}

.splitpilot-heat-kopf {
    color: var(--sp-muted);
    font-size: .75rem;
    text-align: center;
}

.splitpilot-heat-monat .splitpilot-heat-tag {
    aspect-ratio: 1.15;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    max-width: 100%;
    min-width: 0;
    padding: 4px 6px;
}

.splitpilot-heat-monat .splitpilot-heat-tag b {
    font-size: .8rem;
    font-weight: 600;
}

.splitpilot-heat-monat .splitpilot-heat-tag small {
    font-family: var(--sp-font-num);
    font-size: .7rem;
    overflow: hidden;
    text-align: right;
    white-space: nowrap;
}

@media (max-width: 480px) {
    .splitpilot-heat-monat .splitpilot-heat-tag small {
        font-size: .58rem;
    }
}

.splitpilot-heat-jahr {
    --zelle: 12px;
    display: grid;
    gap: 4px 6px;
    grid-template-areas: ". monate" "tage raster";
    grid-template-columns: auto max-content;
    min-width: max-content;
}

.splitpilot-heat-monate {
    color: var(--sp-muted);
    display: grid;
    font-size: .7rem;
    gap: 3px;
    grid-area: monate;
    grid-template-columns: repeat(var(--wochen), var(--zelle));
}

.splitpilot-heat-tage-links {
    color: var(--sp-muted);
    display: grid;
    font-size: .65rem;
    gap: 3px;
    grid-area: tage;
    grid-template-rows: repeat(7, var(--zelle));
    line-height: var(--zelle);
}

.splitpilot-heat-raster {
    display: grid;
    gap: 3px;
    grid-area: raster;
    grid-auto-flow: column;
    grid-template-rows: repeat(7, var(--zelle));
}

.splitpilot-heat-raster .splitpilot-heat-tag {
    border-radius: 3px;
    height: var(--zelle);
    width: var(--zelle);
}

.splitpilot-heat-raster .splitpilot-heat-tag.leer {
    background: transparent;
}

.splitpilot-heat-legende {
    align-items: center;
    color: var(--sp-muted);
    display: flex;
    font-size: .75rem;
    gap: 4px;
    justify-content: flex-end;
}

.splitpilot-heat-legende i {
    border-radius: 3px;
    display: inline-block;
    height: 12px;
    width: 12px;
}

.splitpilot-heat-wochentage {
    display: grid;
    gap: .3rem;
    max-width: 30rem;
}

.splitpilot-heat-wochentag {
    align-items: center;
    display: grid;
    font-size: .85rem;
    gap: .6rem;
    grid-template-columns: 2rem minmax(0, 1fr) 5rem;
}

.splitpilot-heat-wochentag div {
    background: var(--sp-heat-0);
    border-radius: 4px;
    height: 10px;
    overflow: hidden;
}

.splitpilot-heat-wochentag div i {
    background: var(--sp-heat-3);
    border-radius: 0 4px 4px 0;
    display: block;
    height: 100%;
}

.splitpilot-heat-wochentag.spitze div i {
    background: var(--sp-heat-5);
}

.splitpilot-heat-wochentag.spitze span:first-child {
    font-weight: 700;
}

.splitpilot-heat-wochentag .zahl {
    font-family: var(--sp-font-num);
    font-variant-numeric: tabular-nums;
    text-align: right;
}
