/* ===========================================================================
   OS4 — Blatt für den Bereich „Übersicht"
   ===========================================================================
   EIGENE DATEI, nicht ein Anhang an os4.css: an os4.css wird parallel gearbeitet
   (die Karten aus os3), und zwei Agenten, die dieselbe 35-KB-Datei neu schreiben,
   verlieren gegenseitig ihre Arbeit. src/fassungen.js liest die Dateiliste einer
   Fassung aus den Verweisen der index.html (REF_RE), es gibt also keine zweite
   Stelle, an der eine neue Datei angemeldet werden müsste.

   KEIN EINZIGER FESTER FARBWERT — dieselbe Regel wie in os4.css. Alles hängt an
   den zehn Variablen aus src/oberflaeche.js; wer sein Thema auf Papier stellt,
   soll auch hier Papier sehen und nicht ein dunkles Loch. Deckkraft statt
   rgba(255,255,255,…): ein fester Weisston ist auf einem hellen Thema unsichtbar.
   =========================================================================== */

/* ===========================================================================
   BALKEN UND RINGE — Owner 09.08.2026: „kacke farbe, sieht man schlecht,
   mach das anders"
   ===========================================================================
   ZUSAMMENGELEGT AM 09.08.2026. Diese Regeln standen kurzzeitig in os4.css
   (Block „BALKEN UND RINGE", ab Zeile 659), weil an der Fassung mehrere Hände
   gleichzeitig arbeiteten und os4.css das einzige Blatt war, das der Thema-
   Aufgabe offenstand. Dort mussten sie die Gewichtung mit doppelt genannten
   Klassen anheben (`.ub-balken.ub-balken.warn`), weil uebersicht.css NACH
   os4.css geladen wird (index.html:57-59) und bei gleicher Gewichtung sonst
   das spätere Blatt gewinnt.

   Jetzt wohnen sie dort, wo das Bauteil wohnt — und damit fällt beides weg:
   die zweite Kopie UND der Gewichtungstrick. Kein !important; in os4.css
   spricht keine Regel mehr über `.ub-*`. „Zwei Kopien, die auseinanderlaufen"
   ist genau der Fehler, wegen dem diese Welle läuft — die Palette lag dreifach
   herum, und deshalb war der Akzent noch blau.

   VORLAGE ist das lebende Produkt, nicht eine neue Erfindung — ui/style.css:
     260-265  die Diagnose des Owners (5 px hoch, Spur bei 8 % Deckung, immer
              derselbe Warmton) und die drei Gegenmassnahmen
     266-267  Höhe 8px · Spur rgba(255,240,234,.16) · inset 0 0 0 1px …,.10)
     268-269  Füllung als Verlauf, grün
     270      Verlauf amber      271  Verlauf rot

   ÜBERSETZT, NICHT ABGESCHRIEBEN: dieses Blatt trägt keinen festen Farbwert.
   rgba(255,240,234,…) ist der Weisston des Produkts; hier steht dieselbe
   Deckung auf var(--text), damit die Spur auch auf einem HELLEN Thema noch
   eine Spur ist und nicht ein weisser Fleck auf Weiss. Auf dem dunklen Thema
   ist der Unterschied rechnerisch nicht sichtbar: #fff0ea gegen --text #f3efec.

   WARUM DIE SPUR DAS EIGENTLICHE BAUTEIL IST: bei 0 % ist die Füllung 0 px
   breit. Bleibt die Spur unsichtbar, sieht ein leeres Fenster aus wie ein
   fehlender Balken — „ich weiss es gerade nicht" wäre nicht von „hier ist
   etwas kaputt" zu unterscheiden. Genau das war die Beschwerde. Gerechnet auf
   --hintergrund #0a0909 (WCAG 2.1, dieselbe Formel wie OS4.kontrast):
     Spur allein    rgb(47,46,45) → 1,47:1
     mit Randlinie  rgb(67,65,64) → 1,96:1   ← die Kante, die man sieht
     vorher (var(--rahmen) #272524, rgb(39,37,36)) → 1,30:1

   UND DIE GEGENPROBE, damit „voll" von „leer" zu unterscheiden ist — die
   Füllung gegen die Spur, nicht nur gegen den Hintergrund:
     grün  6,55:1 … 8,48:1     amber 7,19:1 … 9,05:1     rot 4,35:1 … 6,85:1
   =========================================================================== */
:root {
  --balken-spur:      color-mix(in srgb, var(--text) 16%, transparent);
  --balken-spur-rand: color-mix(in srgb, var(--text) 10%, transparent);
  --balken-hoehe: 8px;   /* ui/style.css:266 — vorher 5 px, das war der Tadel */
}

/* ---------- Ringe ---------------------------------------------------------- */
.ub-ringe {
  display: flex; flex-wrap: wrap; gap: calc(var(--luft) * 1.5);
  align-items: flex-start; margin: 0 0 var(--luft);
}
.ub-ring { width: 108px; text-align: center; }
.ub-ring-bild { position: relative; width: 80px; height: 80px; margin: 0 auto 6px; }
/* Der Bogen beginnt oben, nicht rechts: gedreht wird das BILD, damit die
   Winkelrechnung im JS bei 0 anfangen darf. */
.ub-ring-bild svg { transform: rotate(-90deg); display: block; }
/* Ein SVG-Strich kann keinen inset-Schatten tragen; das Bett hat also nur die Spur
   selbst — dafür ist es 8 px dick auf 80 px Durchmesser, ein weit grösseres Feld
   als der 8-px-Balken. Dieselbe Spur wie dort: 1,47:1 statt 1,31:1 vorher. */
.ub-bett {
  fill: none; stroke: var(--balken-spur); stroke-width: 8;
}
/* GRÜN AUS DER BASISREGEL, nicht aus einer `.akzent`-Regel: artVon()
   (uebersicht.js:209) liefert unter 70 % „akzent", und der Akzent ist die Farbe
   der Knöpfe. Ein freier Ring in Knopffarbe sagt nichts; grün sagt „da ist noch
   Luft". Amber und Rot überschreiben es unten, sie wiegen eine Klasse mehr. */
.ub-bogen {
  fill: none; stroke: var(--gut); stroke-width: 8; stroke-linecap: round;
  transition: stroke-dasharray var(--einfach) linear;
}
.ub-ring.warn .ub-bogen { stroke: var(--warn); }
.ub-ring.schlecht .ub-bogen { stroke: var(--schlecht); }
.ub-ring-wert {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 1.15em; font-weight: 700; font-variant-numeric: tabular-nums;
}
.ub-ring.warn .ub-ring-wert { color: var(--warn); }
.ub-ring.schlecht .ub-ring-wert { color: var(--schlecht); }
.ub-ring-titel { font-size: .82em; font-weight: 600; line-height: 1.25; }
.ub-ring-unten { line-height: 1.3; margin-top: 2px; }

/* ---------- Konto-Kopf, Hinweise ------------------------------------------- */
.ub-konto {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin: var(--luft) 0 .5em;
}
.ub-konto:first-child { margin-top: 0; }
.ub-konto b { font-size: .98em; }
/* „Auslastung geht aktuell nicht" — bewusst KRÄFTIGER als eine gedämpfte Zeile.
   Der Satz ersetzt eine Zahl; wer ihn überliest, hält den leeren Ring für eine 0. */
.ub-aus { margin: -4px 0 var(--luft); }
.ub-aus-t { color: var(--warn); font-weight: 650; font-size: .92em; }
.ub-hinw {
  font-size: .84em; color: var(--gedaempft); line-height: 1.45;
  border-left: 2px solid var(--rahmen); padding-left: 10px; margin: 4px 0 0;
}

/* ===========================================================================
   ANBIETER UND KONTEN — der Aufbau, den der Owner hingemalt hat (09.08.2026)
   ===========================================================================
       AUSLASTUNG

       Claude
         Magnus-Privat                    Herm&Herm
         5h  0 %   7d 100 %               5h 23 %   7d 23 %

       GPT                                Grok
         7d  0 %                          —

   ZWEI FLEX-REIHEN, MEHR IST ES NICHT — und genau deshalb ist es richtig:
     `.ub-anbieter-reihe`  die Anbieter nebeneinander (Claude · GPT · Grok)
     `.ub-konten`          die Konten EINES Anbieters nebeneinander

   NIRGENDS STEHT EINE SPALTENZAHL. Jeder Anbieter ist so breit wie seine Konten;
   Claude mit zwei Konten ist breit, GPT und Grok sind schmal und landen deshalb
   von allein nebeneinander — genau die Skizze. Kommt ein drittes Claude-Konto
   dazu, wächst die Reihe weiter und bricht um, ohne dass hier eine Zeile
   nachgezogen werden müsste. Auf dem Handy fällt alles untereinander, weil
   `flex-wrap` genau das tut, wenn kein Platz mehr ist.

   `align-items: flex-start` in beiden Reihen: sonst zöge die höchste Karte alle
   anderen auf ihre Höhe und deren Grund-Zeilen stünden mitten im Leeren.
   =========================================================================== */
.ub-anbieter-reihe {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: var(--luft) calc(var(--luft) * 2.5);
  margin: 0 0 var(--luft);
}
/* `flex: 0 1 auto` — so breit wie der Inhalt, aber schrumpffähig. Kein `1 1 auto`:
   das zöge Grok („—") auf dieselbe Breite wie Claude mit zwei Konten und risse
   genau den Leerraum auf, den der Owner nicht mehr sehen will. */
.ub-anbieter { flex: 0 1 auto; min-width: 0; }
.ub-anbieter > h3 { margin-top: 0; }
.ub-konten {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: var(--luft) calc(var(--luft) * 2);
}
.ub-konto-karte { flex: 0 1 auto; min-width: 0; }

/* „—" statt einer Zahl. Es nimmt die Höhe eines Ringsatzes NICHT ein: ein leeres
   Feld in Ringgrösse sähe aus wie ein Ring, der nicht geladen hat. Der Strich ist
   gross genug, um als Aussage gelesen zu werden, und der Grund steht darunter. */
.ub-kein-wert { display: flex; flex-direction: column; gap: 2px; max-width: 22em; }
.ub-kein-wert > b {
  font-size: 1.6em; font-weight: 700; line-height: 1.1; color: var(--gedaempft);
}

/* ---------- Kennzahlen ----------------------------------------------------- */
.ub-kacheln {
  display: grid; gap: var(--luft);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
/* 🔴 REPARIERT 10.08.2026 (Owner: „die Woerter gehen aus Boxen raus und co").
   Die drei Teile einer Kachel sind <span> - also INLINE. Ohne Spaltenrichtung flossen
   sie ineinander: „GESAMT$538.8851alles zusammen" statt drei Zeilen. Verraeterisch war
   `.ub-k-v { margin: .1em 0 }` direkt darunter: ein senkrechter Rand ist auf einem
   Inline-Element wirkungslos - die Regeln waren fuer ein Block-Layout geschrieben, das
   es hier nie gab.
   `min-width: 0` gehoert dazu: die Kachel ist ein Grid-Kind, und ohne diese Zeile
   weigert es sich zu schrumpfen, sobald ein Betrag laenger wird als die Spalte - dann
   waechst die Kachel ueber ihren Kasten hinaus statt umzubrechen. */
.ub-kachel {
  display: flex; flex-direction: column; min-width: 0;
  background: var(--flaeche); border: 1px solid var(--rahmen);
  border-radius: var(--radius); padding: var(--luft);
}
.ub-kachel > * { min-width: 0; }
/* Lange Betraege brechen um, statt die Kachel aufzureissen. */
.ub-k-v { overflow-wrap: anywhere; }
.ub-k-k { font-size: .74em; letter-spacing: .08em; text-transform: uppercase; color: var(--gedaempft); font-weight: 700; }
.ub-k-v { font-size: 1.6em; font-weight: 700; line-height: 1.2; margin: .1em 0; font-variant-numeric: tabular-nums; }
.ub-k-s { line-height: 1.3; }

/* ---------- KACHELN, DIE EIN TOR SIND --------------------------------------
   `kachel(..., ziel)` in uebersicht.js macht aus der Kachel ein <button> mit
   `data-ziel`. Bis zum 09.08.2026 fehlte dazu jede Regel — die Kachel trug einen
   Browser-Knopfrahmen, mittige Grauschrift und keinen Zeigefinger; sie sah aus
   wie ein Fehler, nicht wie ein Weg. (Angeklickt wurde sie ohnehin nie: der
   Aufruf von verdrahten() fehlte in uebersicht.js.)
   Hover NUR unter `(hover: hover)` — dieselbe Regel wie in os4.css. Auf einem
   Finger-Gerät bliebe der zuletzt berührte Knopf sonst dauerhaft hervorgehoben
   und sähe aus wie „ausgewählt".
   --------------------------------------------------------------------------- */
.ub-kachel-tor {
  display: flex; flex-direction: column; align-items: stretch;
  width: 100%; text-align: left; cursor: pointer;
  color: inherit; font: inherit;
  transition: border-color var(--schnell) var(--kurve), background-color var(--schnell) var(--kurve);
}
.ub-k-hin { margin-top: .5em; font-size: .8em; font-weight: 650; color: var(--akzent); }
@media (hover: hover) {
  .ub-kachel-tor:hover { border-color: var(--akzent-rand); background: var(--akzent-hauch); }
}

/* ---------- „WIRD GELADEN" — der Zustand, der KEINE Behauptung ist ----------
   Owner 09.08.2026: in allen vier Karten stand ein Fehlersatz, obwohl die Daten
   nur noch unterwegs waren („Kein aktives Claude-Abo verbunden" bei ZWEI
   verbundenen Abos). Ein 401 beim ersten Zeichnen sagt nichts über die Welt.
   Deshalb gibt es diesen dritten Zustand neben „Daten" und „nicht ladbar".
   Er ist ABSICHTLICH ruhig: gedämpfte Schrift, ein einzelner pulsierender Punkt,
   keine Warnfarbe. Der Punkt bewegt sich wie die Live-Pille (nur transform und
   opacity, damit ihn der Compositor trägt) und steht unter
   `prefers-reduced-motion` still — dann bleibt der Text, und der sagt alles.
   --------------------------------------------------------------------------- */
.ub-laedt { display: flex; align-items: center; gap: 8px; }
.ub-laedt-punkt {
  width: 7px; height: 7px; border-radius: 50%; background: var(--gedaempft);
  flex: 0 0 auto; transform-origin: center;
  animation: ub-puls 1.6s ease-in-out infinite;
}

/* ---------- Der Weg aus einer Karte heraus ---------------------------------
   Zwei Knöpfe tragen diese Klasse: „Abos verwalten →" und „Noch einmal
   versuchen". Beide sind Nebenwege, keine Hauptaktion — also ein Umriss und
   keine gefüllte Fläche; gefüllt stünden sie lauter da als die Zahlen darüber,
   um die es eigentlich geht.
   --------------------------------------------------------------------------- */
.ub-hin {
  margin-top: 10px; padding: .45em .9em; cursor: pointer;
  background: transparent; color: var(--akzent); font: inherit; font-weight: 650;
  border: 1px solid var(--akzent-rand); border-radius: var(--radius);
  transition: background-color 120ms ease;
}
.ub-hin[disabled] { opacity: .55; cursor: default; }
@media (hover: hover) {
  .ub-hin:not([disabled]):hover { background: var(--akzent-hauch); }
}

/* ⚠️ HIER STANDEN `.ub-lauf`, `.ub-lauf-t` und `.ub-lauf-n` — am 09.08.2026
   entfernt. Sie gehörten zu einer Liste „die letzten Läufe", die es in
   uebersicht.js seit dem Umbau auf die vier Karten nicht mehr gibt (gemessen:
   null Treffer auf `ub-lauf` in der ganzen Datei). Regeln ohne Bauteil sind
   Fallen: der nächste Leser hält sie für einen Hinweis, dass es die Liste noch
   gibt, und sucht sie. */

/* ---------- Überschrift zweiter Ordnung ------------------------------------
   os4.css kennt nur `.abschnitt > h2` (Zeile 349). Die Kartengruppen und „Die
   jüngsten Posten" sind eine Stufe darunter: derselbe Klang, etwas leiser, ohne
   die Versalien der Bereichsüberschrift — sonst schreien zwei Ebenen gleich laut.
   --------------------------------------------------------------------------- */
.detail-inhalt .abschnitt h3 {
  margin: calc(var(--luft) * 1.4) 0 .5em; font-size: .9em; font-weight: 650;
  letter-spacing: .01em; color: var(--text);
}
.detail-inhalt .abschnitt h3:first-child { margin-top: 0; }

/* ===========================================================================
   DAS MITWACHSENDE RASTER — Owner 09.08.2026, 21:45
   ===========================================================================
   „also ich will, dass der Platz effizient genutzt wird!"

   WAS HIER BIS DAHIN STAND: `.ub-paar` — Kosten und Aktivität in `1fr 1fr`, und
   zwar erst ab 1200 px, darüber Auslastung und Kennzahlen je als volle Zeile.
   Auf 1400 px stand damit oben eine schmale Ringspalte und rechts daneben
   nichts. Zwei fest verdrahtete Spalten sind genau das, was der Owner nicht
   mehr wollte.

   JETZT: EIN Raster über alle vier Karten, `repeat(auto-fit, minmax(…, 1fr))`.
   DIE SPALTENZAHL STEHT NIRGENDS — der Browser rechnet sie aus der Breite:
     ~390 px  → 1 Spalte      ~900 px → 2 Spalten      ~1400 px → 3 Spalten
   Kein `@media`, keine Schwelle, die bei der nächsten Bildschirmgrösse falsch ist.

   `minmax(min(100%, 340px), 1fr)`: das innere `min()` ist die Bremse gegen den
   klassischen Überlauf — ohne es wäre die Spalte auf einem 320-px-Gerät 340 px
   breit und die Seite liesse sich seitwärts schieben.

   340 px ist eine BREITEN-Untergrenze, keine Verkleinerung: vier Kennzahl-Kacheln
   passen darin zu zweit nebeneinander, eine Kostenzeile (Art · Titel · Zeit ·
   Betrag) bleibt lesbar. Schriftgrössen, Balkenhöhe und Ringdurchmesser sind
   unverändert — der Owner hat sich am 09.08. um 15:10 über zu KLEINE Balken
   beschwert, und „den Platz nutzen" heisst die BREITE nutzen, nicht die Zahlen
   schrumpfen.

   `align-items: start` — sonst zöge die Rasterzelle die kürzere Karte auf die
   Höhe der längeren und ihr unterer Rand stünde mitten im Leeren.
   =========================================================================== */
.ub-raster {
  display: grid; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: calc(var(--luft) * 2);
}
/* Die Auslastung über die ganze Breite: sie trägt ihrerseits die Anbieter
   nebeneinander (Claude · GPT · Grok) und nutzt den Platz dort, wo die Zahlen
   stehen. In eine 340-px-Spalte gezwängt fiele jedes Konto wieder untereinander —
   also genau der Zustand, der weg sollte. `1 / -1` gilt auch bei einer einzigen
   Spalte und braucht deshalb keine Abfrage. */
.ub-raster > .ub-voll { grid-column: 1 / -1; }
/* DEN ABSTAND MACHT DAS RASTER, NICHT DIE KARTE. `.abschnitt` bringt aus os4.css
   einen unteren Rand mit; zusammen mit `gap` klaffte die Lücke doppelt — und
   unter der letzten Zeile bliebe ein Streifen Leerraum stehen, den niemand
   bestellt hat („die Seite endet, wo der Inhalt endet"). */
.ub-raster > .abschnitt { margin-bottom: 0; }
/* Dieselbe Regel für die Fusszeile: sie sitzt direkt unter dem Raster und braucht
   keinen zweiten Abstand über sich. */
.ub-fuss { margin: calc(var(--luft) * 1.5) 0 0; }

/* ---------- Die Live-Pille „N läuft" ---------------------------------------
   Vorlage: ui/views/dashboard.js:314-316 (`.live-pill` / `.live-dot`). Sie steht
   NUR da, wenn wirklich etwas läuft — deshalb darf sie auch auffallen.
   Der Punkt pulsiert ausschliesslich über transform und opacity: beides trägt der
   Compositor, auch auf dem Handy. Eine Animation auf width/height/top/left würde
   bei jedem Bild das Layout neu rechnen lassen.
   --------------------------------------------------------------------------- */
.ub-live {
  display: inline-flex; align-items: center; gap: 6px; margin-left: 10px;
  padding: .2em .6em; border-radius: 99px;
  font-size: .92em; font-weight: 650; letter-spacing: 0; text-transform: none;
  color: var(--akzent); background: var(--akzent-hauch); border: 1px solid var(--akzent-rand);
  vertical-align: middle;
}
.ub-live-punkt {
  width: 7px; height: 7px; border-radius: 50%; background: var(--akzent);
  flex: 0 0 auto; transform-origin: center;
  animation: ub-puls 1.6s ease-in-out infinite;
}
@keyframes ub-puls {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.5); opacity: .4; }
}

/* ---------- Kostenposten ---------------------------------------------------
   Vier Spalten, die auf 390 px umbrechen dürfen: Art · Titel · Zeit · Betrag.
   Der Betrag steht rechts und bricht NIE um — eine Geldspalte, die springt, ist
   nicht mehr überfliegbar. `min-width: 0` am Titel, sonst schiebt ein langer
   Prompt die Zahl aus dem Bild (Flex-Kinder haben min-width:auto).
   --------------------------------------------------------------------------- */
.ub-posten {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 6px 0; border-top: 1px solid var(--rahmen);
}
.ub-posten:first-child { border-top: 0; padding-top: 0; }
.ub-posten-t {
  flex: 1 1 12em; min-width: 0; font-size: .92em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ub-posten-t i { font-style: normal; }
.ub-posten-n { flex: 0 0 auto; white-space: nowrap; }
.ub-posten-g {
  flex: 0 0 auto; font-variant-numeric: tabular-nums; white-space: nowrap;
  min-width: 5.4em; text-align: right;
}
/* (`.ub-lauf-n` stand hier — mit `.ub-lauf` und `.ub-lauf-t` am 09.08.2026
   entfernt; die Liste „die letzten Läufe" gibt es in uebersicht.js nicht mehr.) */

/* ---------- Aktivität ------------------------------------------------------
   Eine Zeitleiste wie in ui/views/dashboard.js:519-530, aber ohne deren glühenden
   Punkt aus ::before — os4.css setzt `prefers-reduced-motion` nur auf `*` und
   `*::after` (os4.css:595), ein ::before bliebe dort also in Bewegung. Hier
   bewegt sich ohnehin nichts: die Linie ist ein Rahmen, der Punkt ein Quadrat
   darauf. Ruhig, weil die Liste sich beim Zuhören von selbst ändert.
   --------------------------------------------------------------------------- */
.ub-verlauf { border-left: 2px solid var(--rahmen); padding-left: var(--luft); }
.ub-punkt { position: relative; padding: 0 0 var(--luft); }
.ub-punkt:last-child { padding-bottom: 0; }
.ub-punkt::after {
  content: ''; position: absolute; left: calc(-1 * var(--luft) - 6px); top: .45em;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--flaeche); border: 2px solid var(--akzent-rand);
}
/* GEMESSEN AM ABZUG (13.08.): beide sind <span>, also inline — im Abzug stand
   „Am Bauen von Programmen hat sich etwas geaendert13.08., 02:09 Uhr" in EINER
   Zeile, ohne Trenner, zehnmal untereinander. Das ist kein Abstandsproblem,
   das ist ein fehlender Zeilenumbruch. */
.ub-punkt-t { display: block; font-size: .92em; line-height: 1.4; }
.ub-punkt-u { display: block; line-height: 1.3; margin-top: 2px; }
/* Ein Eintrag, hinter dem ein Bereich steht, ist ein <button> (uebersicht.js →
   `wohin`). Ohne diese Regel trüge er den Browser-Knopfrahmen mitten in der
   Zeitleiste. Er bleibt bewusst FLACH: die Leiste ist eine Erzählung, kein
   Kachelfeld — der Weg steht als „Chats →" in der Fusszeile, sichtbar auch dort,
   wo es kein Hover gibt. */
.ub-punkt-tor {
  display: flex; flex-direction: column; align-items: stretch;
  width: 100%; text-align: left; cursor: pointer;
  background: transparent; border: 0; color: inherit; font: inherit;
  border-radius: var(--radius);
}
.ub-punkt-hin { color: var(--akzent); font-weight: 650; }
@media (hover: hover) {
  .ub-punkt-tor:hover .ub-punkt-t { color: var(--akzent); }
}

/* ⚠️ HIER STAND `.ub-karten` — am 09.08.2026 entfernt. Es war der Abstand für die
   Kartengruppen aus karten.js („Weiter, wo du warst" · „Projekte" · …). Die Datei
   ist gelöscht, die Gruppen sind auf Owner-Anweisung ersatzlos weg (14:55: „vier
   Karten, sonst nichts"), und eine Regel, die auf sie zeigt, lädt zum Wiederaufbau
   des Menüs ein, das dreimal gestrichen wurde. */

/* ---------- Einblenden beim Seitenwechsel ----------------------------------
   Nur transform und opacity, 180 ms, einmal. Gesetzt wird `ub-ein` ausschliesslich
   beim WECHSEL der Seite (uebersicht.js, detailFuellen) — nicht bei den
   Auffrischungen über die Dauerleitung, sonst zuckte die Seite im Sekundentakt,
   während ein Agent-Lauf arbeitet.
   --------------------------------------------------------------------------- */
@keyframes ub-ein-auf {
  from { opacity: 0; transform: translate3d(0, 6px, 0); }
  to   { opacity: 1; transform: none; }
}
.ub-ein { animation: ub-ein-auf 180ms ease-out both; }

/* Wer weniger Bewegung will, bekommt keine. os4.css:595 stellt `*` und `*::after`
   ab; dass es hier noch einmal steht, ist Absicht: diese Datei soll auch dann
   ruhig sein, wenn sie einmal ohne os4.css ausgeliefert wird. */
@media (prefers-reduced-motion: reduce) {
  .ub-live-punkt, .ub-laedt-punkt, .ub-ein { animation: none; }
  .ub-ein { opacity: 1; transform: none; }
}

/* ---------- UNTERWEGS: 390 px und Fingerbedienung --------------------------
   ⚠️ NICHT NACH GERÄTENAMEN ENTSCHIEDEN. iPadOS meldet sich im User-Agent
   wörtlich als „Macintosh" — eine Weiche darauf hätte jedes iPad als Schreibtisch
   behandelt. Hier entscheidet ausschliesslich, was wirklich zählt: die BREITE und
   die ART DES ZEIGERS. Beides steht in CSS zur Verfügung, es braucht dafür keine
   einzige Zeile JavaScript und keine Geräteliste, die veraltet.
   --------------------------------------------------------------------------- */
@media (pointer: coarse) {
  /* Am Finger sind die Zeilen der Kosten- und Aktivitätsliste Zielflächen zum
     Lesen, nicht zum Treffen — aber sie dürfen nicht aneinanderkleben. */
  .ub-posten { padding: 9px 0; }
  .ub-punkt { padding-bottom: calc(var(--luft) * 1.2); }
}
@media (max-width: 460px) {
  /* Drei Ringe nebeneinander ergäben bei 390 px Zeilen von 8 px Schrift. Zwei
     passen, der dritte rutscht in die nächste Zeile — dafür bleibt jeder lesbar. */
  .ub-ringe { gap: var(--luft); justify-content: flex-start; }
  .ub-ring { width: calc(50% - var(--luft)); max-width: 130px; }
  /* Zwei Kacheln nebeneinander statt vier gequetschten. */
  .ub-kacheln { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }
  .ub-k-v { font-size: 1.35em; }
  /* Der Betrag rutscht unter den Titel, statt ihn auf drei Zeichen zu kürzen. */
  .ub-posten-t { flex: 1 1 100%; white-space: normal; }
  .ub-posten-g { margin-left: auto; }
  .ub-live { margin-left: 8px; }
}

/* ---------- Der Streifen an der Schiene: nur noch die FARBE ----------------
   Das MARKUP entsteht in dieser Fassung (uebersicht.js → streifenZeichnen), die
   FORM steht seit dem 09.08.2026 in os4.css unter „DIE NUTZUNG IN DER SCHIENE":
   Name, Plan-Pille, Wort und Zahl ÜBER dem Balken, 8 px Höhe, sichtbare Spur,
   Schraffur für „nicht gemessen", und der eingeklappte Fall.

   ⚠️ WARUM HIER NICHTS MEHR ÜBER GRÖSSE STEHT. Bis heute lagen beide Blätter auf
   demselben Streifen: hier `.ub-s-name/-zeile/-bar` (0-1-x), dort
   `.schiene .ub-s-…` (0-2-x). Die Gewichtung entschied es richtig — os4.css gewann
   jede überlappende Eigenschaft —, aber es blieben zwei Orte für eine Entscheidung,
   und der hiesige stammte aus der 86-px-Zeit mit `.54em` (7,8 px). Genau diese
   Miniatur hat der Owner am 09.08. um 15:10 gerügt („dass man die Nutzung richtig
   lesen kann"). Stehengelassen wartet sie nur auf den Tag, an dem jemand os4.css
   entrümpelt — dann kehrt sie zurück, ohne dass jemand etwas geändert hätte.

   WAS BLEIBT, ist das, was os4.css NICHT setzt: die AUSSAGE der Farbe — grün frei,
   amber knapp, rot voll. Und die drei Variablen `--balken-hoehe/--balken-spur/
   --balken-spur-rand` (oben in diesem Blatt), aus denen os4.css seine Masse liest.

   KEIN `cursor: pointer` und KEINE Hover-Aufhellung. Beides stammt aus der Zeit,
   als der Streifen ein <button> war und auf „#/uebersicht/abos" sprang; seit dem
   09.08. ist er ein <div> und nur noch Anzeige. Ein Zeigefinger über etwas, das auf
   keinen Klick reagiert, ist ein Versprechen, das die Oberfläche nicht hält — und in
   der Schiene sollen drei Dinge klickbar sein, nicht vier.
   --------------------------------------------------------------------------- */
.ub-s-bar > b {
  display: block; height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--gut), color-mix(in srgb, var(--gut) 55%, var(--text)));
  transition: width var(--einfach) linear;
}
.ub-s-zeile.warn .ub-s-bar > b {
  background: linear-gradient(90deg, var(--warn), color-mix(in srgb, var(--warn) 55%, var(--text)));
}
.ub-s-zeile.warn u { color: var(--warn); }
.ub-s-zeile.schlecht .ub-s-bar > b {
  background: linear-gradient(90deg, var(--schlecht), color-mix(in srgb, var(--schlecht) 55%, var(--text)));
}
.ub-s-zeile.schlecht u { color: var(--schlecht); }

/* Schmal wird die Schiene zu einer waagerechten Leiste am unteren Rand: fünf
   beschriftete Knöpfe sitzen dort auf 390 px schon knapp (os4.css, „FINGERZIELE"),
   ein Balkenblock daneben spränge die Zeile. Auf dem Handy führt der Weg über den
   Tab „Übersicht" — einen Tipp entfernt statt gequetscht.
   `min-height: 44px` aus der Fingerziel-Regel trifft jeden <button>; hier wird es
   ohnehin nicht sichtbar, aber `display:none` gewinnt gegen beides. */
@media (max-width: 860px) { .ub-streifen { display: none; } }


/* ————— KONTO IM LIMIT (Owner-Order 10.08.2026) —————
   Kein Balken, keine Skala — ein Satz. Rot wie die volle Leiste vorher, damit der
   Blick dieselbe Stelle findet, aber ohne vorzutäuschen, dass es hier noch etwas
   zu messen gäbe. */
/* ---- Ausgeschoepft, in der UEBERSICHT (11.08.2026) ------------------------
   Owner: „die Anzeigen oben sind nicht wie die unten hier — unten links will ich
   es haben, das soll genau so sein." Also derselbe Kasten wie im Streifen, nur in
   der Schriftgroesse der Uebersicht: dieselbe Aussage soll auch gleich AUSSEHEN,
   sonst liest man zweimal nach, ob es dasselbe meint.
   Er steht dort, wo sonst die Ringe stehen — nicht daneben. Ein Ring „0 %" neben
   „Limit erreicht" waere die Einladung, doch noch etwas zu versuchen. */
.ub-voll-kasten {
  display: flex; flex-direction: column; gap: 3px;
  margin: 4px 0 2px; padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--schlecht, #e2564a) 38%, transparent);
  background: color-mix(in srgb, var(--schlecht, #e2564a) 12%, transparent);
  color: var(--schlecht, #e2564a);
  font-size: 14px; font-weight: 650; line-height: 1.3;
  min-width: 0;
}
.ub-voll-kasten span { font-weight: 500; opacity: .9; font-size: 13px; }

.ub-s-voll {
  display: flex; flex-direction: column; gap: 2px;
  margin: 6px 0 2px; padding: 7px 9px;
  border-radius: 8px;
  border: 1px solid color-mix(in srgb, var(--schlecht, #e2564a) 38%, transparent);
  background: color-mix(in srgb, var(--schlecht, #e2564a) 12%, transparent);
  color: var(--schlecht, #e2564a);
  font-size: 12px; font-weight: 650; line-height: 1.25;
  min-width: 0;
}
.ub-s-voll span {
  font-weight: 500; font-size: 11px;
  color: var(--text-2, #9aa4b2);
  /* Bei 244 px Spaltenbreite muss der Zusatz umbrechen dürfen — sonst schiebt er
     die Kachel auf, und genau das war am 10.08. der Tadel „Wörter gehen aus Boxen raus". */
  overflow-wrap: anywhere;
}


/* Dieselbe Aussage wie im Streifen, nur an der Stelle, wo sonst zwei Ringe
   stehen — deshalb etwas mehr Luft und Schriftgroesse. */
.ub-voll-gross { font-size: 13.5px; padding: 12px 14px; margin: 10px 0 2px; }
.ub-voll-gross span { font-size: 12px; }


/* ---- Ersparnis und Kosten je Projekt (11.08.2026) -------------------------
   Owner: „damit man weiss, was man diesen Monat gespart hat." Die Zahl ist die
   Aussage, also steht sie gross und allein in der ersten Zeile; darunter, was sie
   gegeneinander stellt, und zuletzt die Annahmen (Kurs, Zeitraum) in der leisen
   Schrift. Grün bei Ersparnis, warnfarben wenn es andersherum ausgeht — dann ist
   das Abo teurer als die Nutzung, und genau das will man sofort sehen. */
.ub-sparen {
  display: flex; flex-direction: column; gap: 3px;
  margin: 10px 0 4px; padding: 12px 14px;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--gut, #3ecf8e) 34%, transparent);
  background: color-mix(in srgb, var(--gut, #3ecf8e) 10%, transparent);
}
.ub-sparen b { font-size: 1.25em; color: var(--gut, #3ecf8e); }
.ub-sparen.minus { border-color: color-mix(in srgb, var(--warn, #e0a33e) 38%, transparent);
  background: color-mix(in srgb, var(--warn, #e0a33e) 10%, transparent); }
.ub-sparen.minus b { color: var(--warn, #e0a33e); }
.ub-sparen span { font-size: .88em; }

.ub-projekte { width: 100%; border-collapse: collapse; }
.ub-projekte th { text-align: right; font-weight: 600; font-size: .78em;
  color: var(--gedaempft); padding: 0 0 6px; }
.ub-projekte th:first-child { text-align: left; }
.ub-projekte td { padding: 5px 0; border-top: 1px solid var(--rahmen);
  text-align: right; font-variant-numeric: tabular-nums; }
.ub-projekte td:first-child { text-align: left; overflow-wrap: anywhere; }
