/* ---------------------------------------------------------------------------
   Dashboard – gemeinsames Aussehen aller Rollen.

   Bisher lag dieses Vokabular dreimal als Inline-<style> in den Rollen-Partials
   (rund 1500 Zeilen). Hier steht es einmal. Die Klassennamen sind bewusst die
   bisherigen (.dashboard-card, .dashboard-stat-card, …), damit die Optik nicht
   springt; für Statusanzeigen wird das globale .pba-status-pill aus
   pba-compact-ui.css genutzt statt eigener Chips.

   Farben kommen über die Branding-Variablen aus ui/main.blade.php
   (--pba-accent, --pba-accent-rgb, …).
--------------------------------------------------------------------------- */

.dashboard-page {
    --db-luecke: 10px;
    --db-rahmen: #e6e9ef;

    /* ── EINE NEUTRALRAMPE, UND ZWAR DIE DER ANWENDUNG ───────────────────
       Hier standen zwoelf warme Grautoene (Gelbstich) neben dreizehn kuehlen.
       Die warmen kamen alle aus dem Abschnitt, der am 13.10.2026 entstanden
       ist; die uebrige Anwendung kennt keinen einzigen davon, sie zaehlt
       #f8fafc 31x, #475569 31x, #334155 10x. Zwei Neutralfamilien auf einer
       Seite sieht man, auch wenn man sie nicht benennen kann - das ist das
       Erste, woran eine Oberflaeche alt wirkt.

       Die Werte sind die, die die Anwendung schon fuehrt. Neu ist nur, dass
       sie Namen haben, damit die naechste Zeile keinen neuen Ton erfindet.
       Die Kontraste auf Weiss stehen dabei. */
    --db-text:      #1f2937;   /* 14,68:1  Titel und Werte          */
    --db-text-2:    #334155;   /* 10,35:1  zweite Stufe             */
    --db-text-3:    #475569;   /*  7,58:1  dritte Stufe             */
    --db-leise:     #5f6672;   /*  5,78:1  Beiwerk, erfuellt AA     */
    --db-schwach:   #94a3b8;   /*  2,56:1  nur Punkte und Striche   */
    --db-linie:     #f1f3f7;   /*          Trennlinie innerhalb     */
    --db-flaeche:   #f8fafc;   /*          ruhige Flaeche           */
    --db-flaeche-2: #eef2f7;   /*          Chip, Hover              */
    --db-gedaempft: #6b7280;
    display: flex;
    flex-direction: column;
    gap: var(--db-luecke);
}

/* --- Aufgabenleiste ------------------------------------------------------ */

.dashboard-aufgaben {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    background: #fff;
    border: 1px solid var(--db-rahmen);
    border-radius: 12px;
}

.dashboard-aufgaben-titel {
    font-size: 13px;
    font-weight: 700;
    color: var(--db-gedaempft);
    margin-right: 4px;
    letter-spacing: .01em;
}

.dashboard-aufgabe {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 11px 4px 7px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
    transition: transform .12s ease, box-shadow .12s ease;
}

.dashboard-aufgabe:hover {
    text-decoration: none;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(15, 23, 42, .1);
}

.dashboard-aufgabe .db-zahl {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 21px;
    height: 21px;
    padding: 0 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .75);
    font-size: 12px;
    font-weight: 800;
    white-space: nowrap;
}

/* Der Nenner einer Verhältnisangabe ("6/17").

   Leichter als der Zähler, denn er ist der Bezug und nicht die Nachricht: Wer
   hinsieht, soll zuerst die 6 lesen und erst dann, worauf sie sich bezieht.
   Deshalb dünner, kleiner und gedeckt – und ohne Leerzeichen vor dem Schrägstrich,
   damit die Pille schmal bleibt. */
.dashboard-aufgabe .db-zahl-von {
    font-size: 10px;
    font-weight: 600;
    opacity: .6;
    margin-left: 1px;
}

.dashboard-aufgabe.ist-gefahr { background: rgba(220, 53, 69, .12); color: #a4243b; border-color: rgba(220, 53, 69, .22); }
.dashboard-aufgabe.ist-warn   { background: rgba(253, 126, 20, .14); color: #9a4a06; border-color: rgba(253, 126, 20, .24); }
.dashboard-aufgabe.ist-info   { background: rgba(37, 99, 235, .12);  color: #1d4ed8; border-color: rgba(37, 99, 235, .2); }

/* --- Raster -------------------------------------------------------------- */

/* Zwölf Spalten und FEINE Zeilen von 10px.

   Warum so fein: Wäre eine Rasterzeile so hoch wie ihre größte Kachel, gäbe es
   unter einer kurzen Kachel zwar sichtbar Platz – aber keine Zelle, die man
   ansprechen könnte. Mit 10px-Zeilen ist "unterhalb dieser Kachel" eine eigene
   Position, und Kacheln lassen sich wirklich frei setzen.

   Wo eine Kachel liegt, steht in der Einstellung. Berechnet wird nur, wie viele
   10px-Zeilen ihr Inhalt hoch ist. Lücken bleiben Lücken. */
.dashboard-raster {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-auto-rows: 10px;
    column-gap: var(--db-luecke);
    row-gap: 0;              /* der Abstand steckt in der Kachel selbst */
    align-items: start;
}

/* box-sizing ausdrücklich: die App hat keinen globalen border-box-Reset. Ohne
   das zählte eine eingestellte Höhe von 200px als 200px INHALT plus 10px
   Abstand – die Kachel wäre also 21 Rasterzeilen hoch, obwohl 20 reserviert
   sind, und ragte in ihre Nachbarin. */
.dashboard-platz {
    box-sizing: border-box;
    min-width: 0;
    padding-bottom: var(--db-luecke);
}

/* Feste Höhe: die Karte füllt den Platz aus, statt sich am Inhalt zu
   orientieren. Passt der Inhalt nicht, scrollt er INNERHALB der Karte – ein
   Überlaufen würde die Nachbarkacheln überdecken, weil die Position im Raster
   ja gesetzt ist. */
/* Anklickbare Kachel: führt zu ihrer Seite. Der kleine Verweis im Kartenkopf
   bleibt stehen – er benennt das Ziel, die Fläche macht es bequem. */
.dashboard-platz.ist-anklickbar { cursor: pointer; }
/* Reine Angaben in einer anklickbaren Kachel – kein Handzeiger, der einen
   Verweis verspricht (siehe Klick-Handler in dashboard/overview). */
.dashboard-platz.ist-anklickbar .dashboard-kein-kachelklick { cursor: default; }
.dashboard-platz.ist-anklickbar > .dashboard-card {
    transition: border-color .12s ease, box-shadow .12s ease;
}
.dashboard-platz.ist-anklickbar:hover > .dashboard-card,
.dashboard-platz.ist-anklickbar:focus-visible > .dashboard-card {
    border-color: rgba(var(--pba-accent-rgb, 28, 82, 36), .45);
    box-shadow: 0 4px 14px rgba(15, 23, 42, .08);
}
.dashboard-platz.ist-anklickbar:focus-visible {
    outline: 2px solid var(--pba-accent, #1c5224);
    outline-offset: 2px;
}

.dashboard-platz.ist-feste-hoehe { display: flex; }
.dashboard-platz.ist-feste-hoehe > .dashboard-card {
    flex: 1 1 auto;
    min-height: 0;
}
.dashboard-platz.ist-feste-hoehe .dashboard-card-header { flex: 0 0 auto; }
.dashboard-platz.ist-feste-hoehe .dashboard-card-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* --- Container ("übergeordnete Kachel") ---------------------------------
   Ein umrandeter Kasten mit Überschrift, der mehrere Kacheln zusammenfasst.
   Er liegt wie eine Kachel im Top-Level-Raster; der äussere Platz trägt nur
   Lage und Rasterabstand, der sichtbare Kasten steckt in .-innen – dasselbe
   Muster wie .dashboard-platz > .dashboard-card, damit die Höhenmessung
   (10px-Zeilen) für beide gleich aufgeht. */
.dashboard-container {
    box-sizing: border-box;
    min-width: 0;
    padding-bottom: var(--db-luecke);
}
.dashboard-container-innen {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: #fff;
    border: 1px solid var(--db-rahmen);
    border-radius: 12px;
    padding: 8px 10px 2px;
}
.dashboard-container-kopf {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 2px 7px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--db-rahmen);
}
.dashboard-container-titel {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .02em;
    color: #334155;
}
/* Das Innen-Raster füllt den Kasten – kein eigener Aussenrand mehr. */
.dashboard-container-raster { width: 100%; }

/* Feste Höhe / Obergrenze: der Kasten füllt den Platz, die Kacheln scrollen
   darin – wie bei .dashboard-platz.ist-feste-hoehe. */
.dashboard-container.ist-feste-hoehe { display: flex; }
.dashboard-container.ist-feste-hoehe .dashboard-container-innen { flex: 1 1 auto; min-height: 0; }
.dashboard-container.ist-feste-hoehe .dashboard-container-raster {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

/* Farbkategorie des Containers – dieselbe schwache Tönung wie bei Kacheln. */
.dashboard-container.ist-farbig .dashboard-container-innen {
    background: rgba(var(--kachel-farbe), .05);
    border-color: rgba(var(--kachel-farbe), .30);
}
.dashboard-container.ist-farbig .dashboard-container-kopf {
    border-bottom-color: rgba(var(--kachel-farbe), .28);
}

/* Schmale Bildschirme: das 12er-Raster ergibt keinen Sinn mehr, alles
   untereinander.

   Nicht "ein Raster mit einer Spalte", sondern gar kein Raster mehr: die
   Zeilen des Rasters sind 10px hoch, und wie viele davon eine Kachel belegt,
   setzt pba-dashboard-hoehe.js als Inline-Stil (grid-row: 12 / span 34). Eine
   Regel wie "grid-row: auto" nähme jeder Kachel genau EINE 10px-Zeile – die
   Kacheln lägen übereinander. Als Flex-Spalte sind grid-row und grid-column
   wirkungslos, und jede Kachel ist so hoch wie ihr Inhalt.

   Die Reihenfolge kommt aus --mobil-rang (KachelRegistry), nicht aus der im
   Editor eingerichteten Lage: nebeneinander liegende Kacheln sind gleichrangig,
   untereinander liegende nicht – gestapelt muss aber etwas zuerst kommen. */
@media (max-width: 991.98px) {
    .dashboard-raster {
        display: flex;
        flex-direction: column;
        /* Muss ausdrücklich hier stehen: das Grundgerüst setzt align-items:
           start. Im Raster meint das "oben ausrichten", in einer Flex-Spalte
           aber die Querachse – also die Breite. Ohne diese Zeile ist jede
           Kachel nur so breit wie ihr Inhalt, und untereinander gestellt
           ergibt das eine ausgefranste Kante. */
        align-items: stretch;
    }

    .dashboard-raster > .dashboard-platz {
        order: var(--mobil-rang, 100);
        /* Untereinander gibt es keinen Grund, Inhalt abzuschneiden – beide
           Maße stehen als Inline-Stil an der Kachel, deshalb !important. */
        height: auto !important;
        max-height: none !important;
    }

    /* Feste Höhe heißt auf dem Desktop "Inhalt scrollt in der Karte". Auf dem
       Telefon wäre das ein Scrollbereich im Scrollbereich – die Karte wächst
       stattdessen mit. */
    .dashboard-platz.ist-feste-hoehe { display: block; }
    .dashboard-platz.ist-feste-hoehe .dashboard-card-body { overflow-y: visible; }

    /* Container genauso: untereinander, nach mobilem Rang, ohne Höhendeckel. */
    .dashboard-raster > .dashboard-container {
        order: var(--mobil-rang, 100);
        height: auto !important;
        max-height: none !important;
    }
    .dashboard-container.ist-feste-hoehe { display: block; }
    .dashboard-container.ist-feste-hoehe .dashboard-container-raster { overflow-y: visible; }
}

/* --- Karte --------------------------------------------------------------- */

.dashboard-card {
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: #fff;
    border: 1px solid var(--db-rahmen);
    border-radius: 12px;
    overflow: hidden;
}

/* Farbkategorie: ein sehr schwacher Ton, damit zusammengehörende Kacheln als
   Gruppe erkennbar sind.

   Bewusst so schwach: die Farbe ist Gliederung, nicht Bedeutung. Was eine
   Kachel aussagt, steht in ihrem Text – sonst wäre die Anzeige für Menschen
   mit Farbsehschwäche wertlos. Aus demselben Grund bekommt auch der Kartenkopf
   nur eine Spur mehr, statt kräftig zu färben. */
.dashboard-platz[data-kategorie] > .dashboard-card {
    background: rgba(var(--kachel-farbe), .05);
    border-color: rgba(var(--kachel-farbe), .28);
}
.dashboard-platz[data-kategorie] .dashboard-card-header {
    background: rgba(var(--kachel-farbe), .09);
    border-bottom-color: rgba(var(--kachel-farbe), .22);
}

.dashboard-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--db-rahmen);
    background: #fbfcfe;
}

.dashboard-card-header h5 {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    color: #1f2937;
}

.dashboard-card-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
}

/* Vor und zurück blättern im Kartenkopf. */
.dashboard-blaettern { display: inline-flex; align-items: center; gap: 2px; }
.dashboard-blaettern button {
    border: 1px solid var(--db-rahmen);
    background: #fff;
    color: #475569;
    border-radius: 5px;
    padding: 1px 6px;
    font-size: 11px;
    line-height: 17px;
    cursor: pointer;
}
.dashboard-blaettern button:hover { background: #eef2f7; color: #16345c; }
.dashboard-blaettern button.ist-aktiv {
    background: rgba(var(--pba-accent-rgb, 28, 82, 36), .12);
    border-color: rgba(var(--pba-accent-rgb, 28, 82, 36), .35);
    color: var(--pba-accent, #1c5224);
    font-weight: 600;
}
.dashboard-blaettern button[disabled] { opacity: .35; cursor: default; }
.dashboard-blaettern button[disabled]:hover { background: #fff; color: #475569; }
.dashboard-blaettern.ist-laedt { opacity: .5; pointer-events: none; }
.dashboard-blaettern.ist-fehler button { border-color: rgba(220, 53, 69, .5); color: #a4243b; }

.dashboard-card-body { padding: 10px 12px; }
.dashboard-card-body.ist-eng { padding: 4px 0; }

.dashboard-empty {
    padding: 12px 4px;
    text-align: center;
    color: var(--db-gedaempft);
    font-size: 13px;
}

/* --- Kennzahlen ---------------------------------------------------------- */

.dashboard-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
    gap: 8px;
}

/* Im Dashboard-Raster NICHT frei packen.

   auto-fit nimmt so viele Spalten, wie hineinpassen – bei vier Werten ergab
   das je nach Kachelbreite 3 + 1: eine volle Zeile und eine fast leere. Die
   Aufteilung soll aufgehen, deshalb richtet sie sich nach der ANZAHL der
   Werte: schmal zwei Spalten, breit alle nebeneinander. Drei plus eins kommt
   damit nicht mehr vor.

   Gemessen wird die Kachel selbst (Container-Anfrage), nicht das Fenster – die
   gleiche Kachel ist im Editor schmaler als im Dashboard. Kann der Browser
   keine Container-Anfragen, bleibt es bei zwei Spalten; das ist einer der
   beiden erwünschten Zustände, nie der schiefe. */
.dashboard-raster .dashboard-card-body { container-type: inline-size; }

.dashboard-raster .dashboard-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Derselbe Selektor wie oben, sonst gewinnt die Zwei-Spalten-Regel: eine
   Container-Abfrage erhöht die Spezifität nicht. */
@container (min-width: 440px) {
    .dashboard-raster .dashboard-stats {
        grid-template-columns: repeat(var(--stats-spalten, 2), minmax(0, 1fr));
    }
}

.dashboard-stat-card {
    display: block;
    padding: 8px 10px;
    border: 1px solid var(--db-rahmen);
    border-radius: 10px;
    background: #fff;
    text-decoration: none;
    color: inherit;
    transition: border-color .12s ease, box-shadow .12s ease;
}

a.dashboard-stat-card:hover {
    text-decoration: none;
    border-color: rgba(var(--pba-accent-rgb, 28, 82, 36), .45);
    box-shadow: 0 4px 14px rgba(15, 23, 42, .08);
}

.dashboard-stat-label {
    font-size: 12px;
    color: var(--db-gedaempft);
    margin-bottom: 2px;
}

.dashboard-stat-value {
    margin: 0;
    font-size: 21px;
    font-weight: 800;
    line-height: 1.1;
    color: var(--pba-accent, #1c5224);
}

.dashboard-stat-tone { font-size: 12px; color: var(--db-gedaempft); margin-top: 2px; }

/* --- Listen und Zeilen --------------------------------------------------- */

.dashboard-liste { display: flex; flex-direction: column; }

/* Ein Zeilenmaß für alle Listen.

   Manche Kacheln führen eine Unterzeile (Partner · Platz), andere nicht.
   Ohne festen Rahmen waren einzeilige Listen deutlich dichter als zweizeilige,
   und nebeneinander gestellt sah das aus wie zwei verschiedene Bauteile.
   44px ist die natürliche Höhe einer zweizeiligen Zeile (Titel 17 + Unterzeile
   16 + Innenabstand + Trennlinie); einzeilige Listen halten dasselbe Maß.
   box-sizing ist hier ausdrücklich gesetzt: ohne das gilt content-box, und
   die 44 wären 55. */
.dashboard-zeile {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 44px;
    padding: 5px 12px;
    border-bottom: 1px solid #f1f3f7;
    font-size: 13px;
    color: inherit;
    text-decoration: none;
}

.dashboard-zeile:last-child { border-bottom: 0; }
a.dashboard-zeile:hover { background: #f8fafc; text-decoration: none; }

.dashboard-zeile-haupt { min-width: 0; }
.dashboard-zeile-titel { font-weight: 600; color: #1f2937; line-height: 1.25; }
.dashboard-zeile-titel.ist-ungelesen::before {
    content: '';
    display: inline-block;
    width: 7px; height: 7px;
    margin-right: 7px;
    border-radius: 50%;
    background: var(--pba-accent, #1c5224);
    vertical-align: middle;
}
.dashboard-zeile-neben { color: var(--db-gedaempft); font-size: 12px; line-height: 1.2; }
.dashboard-zeile-rechts { flex: 0 0 auto; color: var(--db-gedaempft); font-size: 12px; white-space: nowrap; }

.dashboard-zeile-abschnitt {
    padding: 4px 12px;
    background: #f8fafc;
    border-bottom: 1px solid #f1f3f7;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--db-gedaempft);
}

/* --- Stufenliste (Praxisbesuche) ----------------------------------------- */

.dashboard-stufe {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px;
    border-bottom: 1px solid #f1f3f7;
    text-decoration: none;
    color: inherit;
}

.dashboard-stufe:last-child { border-bottom: 0; }
a.dashboard-stufe:hover { background: #f8fafc; text-decoration: none; }

.dashboard-stufe-punkt {
    flex: 0 0 auto;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: #cbd5e1;
}

.dashboard-stufe-label { flex: 1 1 auto; font-size: 13px; font-weight: 600; color: #1f2937; }
.dashboard-stufe-hinweis { display: block; font-weight: 400; font-size: 12px; color: var(--db-gedaempft); }
.dashboard-stufe-zahl { flex: 0 0 auto; font-size: 14px; font-weight: 800; }
.dashboard-stufe.ist-ruhig .dashboard-stufe-zahl { color: #94a3b8; }

/* --- Diagramm-Farben -----------------------------------------------------
   Bewusst NICHT die Branding-Farbe: --pba-accent wechselt je Betrieb (grün,
   orange, blau …). Datenfarben müssen aber über alle Betriebe hinweg dasselbe
   bedeuten und geprüft bleiben. Der Akzent bleibt der Oberfläche vorbehalten.

   Geprüft gegen die Kartenfläche #fff (Skript validate_palette.js):
   Serienfarben bestehen alle Prüfungen als Dreier-Satz (schlechteste
   CVD-Trennung ΔE 9.2, Normalsicht 24.0). Aqua liegt bei 2.82:1 unter der
   3:1-Marke – deshalb trägt es überall eine sichtbare Beschriftung.

   Statusfarben sind KEIN Serien-Satz; sie stehen immer mit Symbol und Text,
   nie allein über die Farbe.
-------------------------------------------------------------------------- */

.dashboard-page {
    --viz-serie-1: #2a78d6;   /* blau   – Termine, Standard-Balken */
    --viz-serie-2: #eb6834;   /* orange – Praxisbesuche */
    --viz-serie-3: #1baf7a;   /* aqua   – Einsätze */
    --viz-spur:    #cde2fb;   /* hellste Stufe derselben Blau-Rampe */
    --viz-gut:     #0ca30c;
    --viz-warnung: #fab219;
    --viz-ernst:   #ec835a;
    --viz-kritisch:#d03b3b;
    --viz-raster:  #e1e0d9;   /* Hilfslinien, eine Stufe von der Fläche entfernt */
    --viz-achse:   #c3c2b7;
}

/* --- Meter (Anteil gegen ein Ziel) ---------------------------------------
   Die Spur ist eine hellere Stufe derselben Rampe, damit der Zustand über die
   ganze Breite lesbar bleibt – nicht ein neutrales Grau.
-------------------------------------------------------------------------- */

.dashboard-meter {
    position: relative;
    height: 6px;
    border-radius: 999px;
    background: var(--viz-spur);
    overflow: hidden;
}

/* RUNDUNG NUR AUSSEN, UND DIE NULL BLEIBT SICHTBAR. Rundum 999px kostet bei 6px
   Hoehe an jedem Ende 3px Laenge, und `width: 0%` zeichnete gar nichts - ausgerechnet
   bei dem Betrieb, um den es der Kachel geht (0,0 Einsaetze je Azubi). Ein Balken, der
   bei null verschwindet, sieht aus wie "nicht gemessen". */
.dashboard-meter-fuellung {
    min-width: 3px;
    height: 100%;
    border-radius: 999px;
    background: var(--viz-serie-1);
    transition: width .2s ease;
}

.dashboard-meter-fuellung.ist-gut      { background: var(--viz-gut); }
.dashboard-meter-fuellung.ist-warnung  { background: var(--viz-warnung); }
.dashboard-meter-fuellung.ist-kritisch { background: var(--viz-kritisch); }

/* Zielmarke bei 100 %: zeigt, wo "erfüllt" liegt, wenn die Skala darüber geht. */
.dashboard-meter-ziel {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: var(--viz-achse);
}

/* --- Säulendiagramm ------------------------------------------------------
   Inline-SVG statt Diagramm-Bibliothek: eine Kachel braucht keine 200 KB und
   keinen Initialisierungslauf, und es überlebt den View-Cache unverändert.
-------------------------------------------------------------------------- */

.db-saeulen {
    display: flex;
    align-items: flex-end;
    gap: 2px;                 /* Flächenlücke zwischen benachbarten Säulen */
    width: 100%;
}

.db-saeulen-band {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.db-saeulen-wert {
    font-size: 10px;
    font-weight: 700;
    color: #1f2937;
    line-height: 1;
    min-height: 10px;
    font-variant-numeric: tabular-nums;
}

/* Die Spur gibt die Höhe vor; der Balken wächst darin von der Grundlinie. */
.db-saeulen-spur {
    width: 100%;
    height: 72px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    border-bottom: 1px solid var(--viz-achse);
}

.db-saeulen-balken {
    display: block;
    width: 100%;
    max-width: 24px;          /* gedeckelt – der Rest des Bandes bleibt Luft */
    background: var(--viz-serie-1);
    border-radius: 4px 4px 0 0;   /* oben gerundet, an der Grundlinie eckig */
}

.db-saeulen-balken.ist-betont { background: var(--viz-kritisch); }

.db-saeulen-tick {
    font-size: 10px;
    color: #6b7280;
    line-height: 1;
    min-height: 10px;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.dashboard-chart-legende {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 6px;
    font-size: 11px;
    color: var(--db-gedaempft);
}

.dashboard-chart-legende span { display: inline-flex; align-items: center; gap: 6px; }

.dashboard-chart-legende i {
    width: 9px; height: 9px;
    border-radius: 50%;
    display: inline-block;
}

/* --- Wochenblick ---------------------------------------------------------
   Sieben Spalten statt eines Monatsrasters: nur so ist Platz für den Eintrag
   selbst statt für einen Punkt.
-------------------------------------------------------------------------- */

.dashboard-woche {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 3px;
}

.dashboard-woche-tag {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-height: 82px;
    padding: 5px 5px;
    border-radius: 8px;
    background: #f8fafc;
    color: inherit;
    text-decoration: none;
}

a.dashboard-woche-tag:hover { background: #eef2f7; text-decoration: none; }

/* Leere Woche: nur die Tagesköpfe, keine Eintragshöhe vorhalten. */
.dashboard-woche.ist-leer .dashboard-woche-tag { min-height: 0; }

.dashboard-woche-tag.ist-wochenende { background: #f1f3f7; }

.dashboard-woche-tag.ist-heute {
    background: #fff;
    outline: 2px solid var(--pba-accent, #1c5224);
    outline-offset: -2px;
}

.dashboard-woche-kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px;
}

.dashboard-woche-wt {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--db-gedaempft);
}

.dashboard-woche-zahl {
    font-size: 14px;
    font-weight: 700;
    color: #1f2937;
    font-variant-numeric: tabular-nums;
}

.dashboard-woche-tag.ist-heute .dashboard-woche-zahl { color: var(--pba-accent, #1c5224); }
.dashboard-woche-tag.ist-wochenende .dashboard-woche-zahl { color: #9aa3af; }

.dashboard-woche-liste { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

/* Farbige Kante links statt Vollfläche: die Schrift bleibt in Textfarbe und
   damit lesbar, die Identität trägt die Marke daneben. */
.dashboard-woche-eintrag {
    display: block;
    min-width: 0;
    padding: 2px 4px 2px 5px;
    border-left: 3px solid var(--viz-serie-1);
    border-radius: 3px;
    background: #fff;
    font-size: 11px;
    line-height: 1.25;
    color: #1f2937;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard-woche-eintrag.ist-termin  { border-left-color: var(--viz-serie-1); }
.dashboard-woche-eintrag.ist-besuch  { border-left-color: var(--viz-serie-2); }
.dashboard-woche-eintrag.ist-einsatz { border-left-color: var(--viz-serie-3); }

.dashboard-woche-zeit {
    font-weight: 700;
    color: var(--db-gedaempft);
    margin-right: 3px;
    font-variant-numeric: tabular-nums;
}

.dashboard-woche-mehr { font-size: 10px; color: var(--db-gedaempft); padding-left: 6px; }

/* Kartenkopf: Blättern und Woche als Gruppe. Am Rechner dieselben 8px wie
   zwischen den übrigen Kopfelementen – die Gruppe ändert dort nichts. Die
   kurze Woche und der Punkt davor sind nur fürs Telefon. */
.dashboard-woche-navi,
.dashboard-woche-label { display: inline-flex; align-items: center; gap: 8px; }
.dashboard-woche-trenner,
.dashboard-woche-zeitraum-kurz { display: none; }

/* „+ XX weitere"-Fußzeile gekürzter Listen (siehe partials/mehr_zeile). */
.dashboard-zeile-mehr { font-size: 12px; color: var(--db-gedaempft); padding: 6px 4px 2px; text-align: center; }
.dashboard-zeile-mehr a { color: inherit; text-decoration: none; }
.dashboard-zeile-mehr a:hover { text-decoration: underline; }

/* Auf schmalen Bildschirmen untereinander statt sieben Spalten zu quetschen.
   Dieselbe Grenze wie das Stapeln der Kacheln – sonst stünde die Woche in einer
   vollbreiten Kachel noch als Sieben-Spalten-Raster. */
@media (max-width: 991.98px) {
    /* minmax(0, …) wie oben bei den sieben Spalten: ein blankes 1fr wächst bis
       zur Mindestbreite seines Inhalts, und die war bei nowrap der ganze Titel –
       die Zeilen ragten dann rechts aus der Karte. */
    .dashboard-woche { grid-template-columns: minmax(0, 1fr); }
    .dashboard-woche-tag { min-height: 0; flex-direction: row; align-items: flex-start; gap: 10px; }
    .dashboard-woche-kopf { flex: 0 0 52px; flex-direction: row; gap: 6px; }
    .dashboard-woche-liste { flex: 1 1 auto; }
    /* Untereinander hat der Eintrag die ganze Zeile: der Titel bricht um statt
       mit „…“ zu enden. In den sieben schmalen Spalten bleibt es beim Kürzen. */
    .dashboard-woche-eintrag { white-space: normal; overflow-wrap: anywhere; }

    /* Kartenkopf in zwei Zeilen statt einer, die nicht passt (Pille und
       Zeitraum brachen in sich um). Zeile 1: Titel links, „Kalender" rechts –
       wie bei den anderen Kacheln. Zeile 2: Blättern links, „KW 41 · 05.–11.10."
       rechts. Die Aktionen lösen sich dafür auf, damit Titel, Verweis und
       Gruppe Geschwister im Kopf werden. */
    .dashboard-woche-kopf-zeile { row-gap: 8px; }
    .dashboard-woche-kopf-zeile .dashboard-card-header-actions { display: contents; }
    .dashboard-woche-kopf-zeile h5 { flex: 1 1 auto; min-width: 0; }
    .dashboard-woche-kopf-zeile .dashboard-card-header-actions > a { order: 1; }
    .dashboard-woche-navi { order: 2; flex: 1 0 100%; justify-content: space-between; }

    .dashboard-woche-label { gap: 5px; font-size: 14px; line-height: 1.2; white-space: nowrap; }
    .dashboard-woche-label .pba-status-pill {
        min-width: 0;
        padding: 0;
        background: none;
        font-size: inherit;
        color: #1f2937;
    }
    .dashboard-woche-trenner { display: inline; color: var(--db-gedaempft); }
    .dashboard-woche-label .dashboard-zeile-neben { font-size: inherit; }
    .dashboard-woche-zeitraum-lang { display: none; }
    .dashboard-woche-zeitraum-kurz { display: inline; }
}

/* Legenden-Marke in der Farbe der jeweiligen Art. */
.dashboard-chart-legende i.ist-termin  { color: var(--viz-serie-1); }
.dashboard-chart-legende i.ist-besuch  { color: var(--viz-serie-2); }
.dashboard-chart-legende i.ist-einsatz { color: var(--viz-serie-3); }

/* --- Fortschritt (Altbestand, wird von einigen Kacheln noch genutzt) ------ */


/* .dashboard-progress und .dashboard-progress-bar standen hier als zweites
   Balkenbauteil neben .dashboard-meter - 8px gegen 6px, fuer dieselbe Aufgabe.
   Benutzt hat es niemand: Die Klassen kommen in resources/, public/js/ und app/
   kein einziges Mal vor. Entfernt, damit nicht die naechste Kachel das falsche
   von beiden erwischt. */

.dashboard-progress-zeile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 78px;
    align-items: center;
    gap: 8px;
    padding: 5px 12px;
    border-bottom: 1px solid #f1f3f7;
    font-size: 13px;
}

.dashboard-progress-zeile:last-child { border-bottom: 0; }
.dashboard-progress-wert { text-align: right; font-variant-numeric: tabular-nums; color: var(--db-gedaempft); font-size: 12px; }

/* --- Zeitstrahl (Stationen der Ausbildung) -------------------------------
   Eine Zeile je Station. Die durchgehende Linie entsteht aus dem Achsen-
   Element, nicht aus Rahmen an den Zeilen – sonst bräuchte jede Zeile eine
   Sonderbehandlung an den Enden.
-------------------------------------------------------------------------- */

.db-station {
    display: flex;
    align-items: stretch;
    gap: 9px;
    padding: 5px 12px;
}

.db-station-achse {
    position: relative;
    flex: 0 0 9px;
    display: flex;
    justify-content: center;
}

/* Die Linie läuft durch; der Punkt liegt darüber. */
.db-station-achse::before {
    content: '';
    position: absolute;
    top: -5px; bottom: -5px;
    width: 2px;
    background: #e6e9ef;
}

.db-station:first-child .db-station-achse::before { top: 9px; }
.db-station:last-child  .db-station-achse::before { bottom: calc(100% - 9px); }

.db-station-punkt {
    position: relative;
    width: 9px; height: 9px;
    margin-top: 5px;
    border-radius: 50%;
    background: #cbd5e1;
    box-shadow: 0 0 0 2px #fff;   /* Flächenring, damit der Punkt die Linie trennt */
}

.db-station.ist-laufend .db-station-punkt { background: var(--viz-serie-1); }
.db-station.ist-geplant .db-station-punkt { background: var(--viz-spur); }

.db-station-inhalt { flex: 1 1 auto; min-width: 0; }

.db-station-kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.db-station-titel {
    font-size: 13px;
    font-weight: 600;
    color: #1f2937;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.db-station-zeit {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--db-gedaempft);
    font-variant-numeric: tabular-nums;
}

.db-station-neben { display: block; font-size: 11px; color: var(--db-gedaempft); }

/* --- Kontakt und Chips --------------------------------------------------- */

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

.dashboard-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    background: #eef2f7;
    color: #475569;
    font-size: 12px;
    font-weight: 600;
}

.dashboard-info-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 4px 0;
    font-size: 13px;
}

.dashboard-info-row + .dashboard-info-row { border-top: 1px solid #f1f3f7; }
.dashboard-info-label { color: var(--db-gedaempft); }
.dashboard-info-wert { font-weight: 600; color: #1f2937; text-align: right; }

.dashboard-kontakt { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }

/* --- Hinweisstreifen ----------------------------------------------------- */

.dashboard-hinweis {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 8px 12px;
    border-radius: 8px;
    background: rgba(253, 126, 20, .1);
    border: 1px solid rgba(253, 126, 20, .24);
    color: #9a4a06;
    font-size: 13px;
}

.dashboard-hinweis.ist-info {
    background: rgba(37, 99, 235, .08);
    border-color: rgba(37, 99, 235, .2);
    color: #1d4ed8;
}

/* --- Vorschau im Editor -------------------------------------------------- */

.dashboard-page.ist-vorschau { pointer-events: none; }
.dashboard-page.ist-vorschau a { cursor: default; }

.dashboard-vorschau-band {
    padding: 8px 14px;
    border-radius: 10px;
    background: rgba(37, 99, 235, .1);
    border: 1px dashed rgba(37, 99, 235, .35);
    color: #1d4ed8;
    font-size: 13px;
    font-weight: 600;
}

/* --- Telefon und Tablet --------------------------------------------------
   Was hier steht, ist nicht "kleiner", sondern grobmotorisch bedienbar: mit
   der Maus trifft man 21px, mit dem Daumen nicht. Die Kartenfläche selbst ist
   auf dem Telefon das eigentliche Bedienelement (ein Tipp führt zur Seite),
   die kleinen Verweise im Kartenkopf sind der Notausgang für alle, die genau
   zielen können.
-------------------------------------------------------------------------- */

@media (max-width: 991.98px) {

    /* Der Abstand zwischen den Kacheln darf grösser sein: gestapelt trennt er
       zwei Themen, nebeneinander trennte er zwei Spalten. */
    .dashboard-page { --db-luecke: 12px; }

    /* ── Ein Mass für alle Bedienelemente ────────────────────────────────
       34px, dieselbe Höhe wie die Schaltflächen im Kalender und am grossen
       Bildschirm. Vorher standen auf einem Bildschirm 44px (Aufgaben-Chip),
       28px (Verweis im Kartenkopf) und 21px (Blättern) nebeneinander – drei
       Grössen für drei Dinge, die alle nur „hier tippen" bedeuten.

       Sichtbar 34px, treffbar 44px: die Fläche wächst über ::after nach oben
       und unten. Seitlich bleibt sie, wo sie ist – nebeneinander stehende
       Elemente würden sich sonst gegenseitig die Treffer wegnehmen. */
    .dashboard-aufgaben { padding: 10px; gap: 8px; }
    .dashboard-aufgabe {
        position: relative;
        height: 34px;
        padding: 0 12px 0 8px;
        font-size: 14px;
    }

    /* Nur 4px: die Chips stehen 8px auseinander, bei 5px berührten sich die
       Trefferflächen der Nachbarn. */
    .dashboard-aufgabe::after {
        content: '';
        position: absolute;
        top: -4px; bottom: -4px; left: 0; right: 0;
    }

    /* Blättern im Kartenkopf (eine Woche vor, eine zurück). Mit 23×21px war
       das die kleinste Schaltfläche der Anwendung – und die einzige, die für
       schmale Bildschirme nie angepasst wurde. */
    .dashboard-blaettern { gap: 4px; }
    .dashboard-blaettern button {
        position: relative;
        height: 34px;
        min-width: 34px;
        padding: 0 10px;
        font-size: 13px;
        line-height: 1;
    }
    .dashboard-blaettern button::after {
        content: '';
        position: absolute;
        top: -5px; bottom: -5px; left: 0; right: 0;
    }

    /* Der kleine Verweis im Kartenkopf („Alle", „Ganze Historie") bleibt ein
       Verweis und keine Schaltfläche – seine Grösse gehört zur Überschrift,
       nicht zur Bedienung. Er bekommt nur eine grössere Trefferfläche; sie
       darf hier auch seitlich wachsen, weil rechts der Kartenrand kommt. */
    .dashboard-card-header-actions a { position: relative; }
    .dashboard-card-header-actions a::after {
        content: '';
        position: absolute;
        top: -8px; bottom: -8px; left: -6px; right: -6px;
    }

    /* Handlung an einer Aufgabe, z. B. „Alle erinnern". */
    .dashboard-aufgaben form .btn { height: 34px; padding: 0 12px; font-size: 14px; }
    /* Ohne Zeigegerät gibt es kein Hover – die Verschiebung beim Antippen
       wirkte wie ein Ruckeln. */
    .dashboard-aufgabe:hover { transform: none; box-shadow: none; }

    /* Kartenkopf: Überschrift und Verweis brauchen zusammen mehr Platz, als
       eine Zeile hergibt, sobald der Titel lang ist. */
    .dashboard-card-header { flex-wrap: wrap; padding: 10px 12px; }
    .dashboard-card-header h5,
    .dashboard-card-header h3 { font-size: 15px; }
    .dashboard-card-header-actions { font-size: 13px; }
    .dashboard-card-header-actions a { padding: 4px 0; }

    /* Listenzeilen sind Verweise: 48px statt 44px, und der Text darf umbrechen
       statt den Statuswert nach rechts aus der Karte zu schieben. */
    .dashboard-zeile { min-height: 48px; padding: 8px 12px; font-size: 14px; }
    .dashboard-zeile-neben { font-size: 12.5px; }
    .dashboard-zeile-rechts { white-space: normal; text-align: right; }

    /* Kontaktknöpfe des laufenden Einsatzes ("Anrufen", "E-Mail"). Genau die
       sind auf dem Telefon der Grund, das Dashboard aufzumachen – als
       12px-Pille wären sie kaum zu treffen. */
    .dashboard-kontakt { gap: 10px; }
    .dashboard-kontakt .dashboard-chip {
        position: relative;
        height: 34px;
        padding: 0 14px;
        font-size: 14px;
    }
    .dashboard-kontakt .dashboard-chip::after {
        content: '';
        position: absolute;
        top: -5px; bottom: -5px; left: 0; right: 0;
    }
    a.dashboard-chip {
        background: rgba(var(--pba-accent-rgb, 28, 82, 36), .1);
        color: var(--pba-accent, #1c5224);
    }

    .dashboard-stat-value { font-size: 24px; }
    .dashboard-empty { padding: 16px 4px; }
}

/* Sehr schmal (Telefon hochkant): Bezeichnung und Wert stehen untereinander.
   Nebeneinander gewinnt bei einem langen Partnernamen die Bezeichnung den
   Platz, und der Wert bricht auf drei Zeilen um – ausgerechnet die Angabe,
   wegen der die Zeile da ist. */
@media (max-width: 575.98px) {

    /* Eine Zeile je Aufgabe. Nebeneinander bliebe auf 390px von jeder nur ein
       Bruchteil der Fläche – auf dem Tablet passen dagegen zwei nebeneinander,
       und dort wäre die volle Breite je Chip nur verschenkter Platz. */
    .dashboard-aufgaben-titel { flex: 1 0 100%; margin-right: 0; }
    .dashboard-aufgabe { flex: 1 1 100%; }

    .dashboard-info-row {
        flex-direction: column;
        align-items: stretch;
        gap: 1px;
        padding: 6px 0;
    }
    .dashboard-info-wert { text-align: left; }

    /* Der Zeitstrahl führt Titel und Zeitraum in einer Zeile – gemeinsam
       passen sie hier nicht mehr nebeneinander. */
    .db-station-kopf { flex-direction: column; align-items: flex-start; gap: 0; }
    .db-station-titel { white-space: normal; }
}

/* ── Zustandszeile ────────────────────────────────────────────────────────

   Muss root jetzt etwas tun? Steht ueber dem Handlungsbedarf und IMMER da -
   auch bei Ruhe. Bis hierher verschwand die Aufgabenzeile, wenn nichts anlag,
   und "alles ruhig" sah aus wie "nichts geladen".

   Die Stufe steht als Wort UND als Farbe. Farbe allein traegt keine Aussage:
   wer sie nicht unterscheidet, liest sonst gar nichts. Der farbige Streifen
   links ist die Wiederholung, nicht der Traeger.                            */

.dashboard-zustand {
    background: #fff;
    border: 1px solid var(--viz-raster, #e1e0d9);
    border-left: 5px solid var(--viz-achse, #c3c2b7);
    border-radius: 12px;
    padding: 20px 24px;
    margin-bottom: 18px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.dashboard-zustand-kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px 16px;
}

.dashboard-zustand-kopf h2 {
    margin: 0;
    font-size: 21px;
    letter-spacing: .01em;
}

.dashboard-zustand-punkt {
    width: 11px;
    height: 11px;
    border-radius: 999px;
    flex: none;
    background: var(--viz-achse, #c3c2b7);
}

.dashboard-zustand-stand {
    font-size: 13px;
    color: var(--db-leise);
    margin-left: auto;
}

.dashboard-zustand-befunde {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 9px;
    font-size: 16px;
    line-height: 1.45;
}

.dashboard-zustand-befunde li {
    display: flex;
    gap: 10px;
}

/* Der Strich traegt die Schwere des EINZELNEN Befundes - eine Zeile kann
   dringender sein als die Ueberschrift der Karte. */
.dashboard-zustand-befunde li > span:first-child {
    font-weight: 700;
    flex: none;
    color: var(--viz-achse, #c3c2b7);
}

.dashboard-zustand-befunde li.ist-sofort > span:first-child   { color: var(--viz-kritisch, #d03b3b); }
.dashboard-zustand-befunde li.ist-sieh_hin > span:first-child { color: #9a4a06; }

.dashboard-zustand-satz {
    font-size: 16px;
    line-height: 1.45;
}

.dashboard-zustand-fuss {
    border-top: 1px solid var(--db-rahmen);
    padding-top: 12px;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 14px;
    align-items: center;
    font-size: 13px;
    color: var(--db-leise);
}

.dashboard-zustand-quellen {
    margin-left: auto;
    font-weight: 600;
    color: #3f6b2f;
}

/* Fehlbestand: nicht gruen, nicht still. */
.dashboard-zustand-quellen.ist-fehlbestand,
.dashboard-zustand-satz.ist-fehlbestand {
    color: #a4243b;
    font-weight: 700;
}

.dashboard-zustand.ist-sofort     { border-left-color: var(--viz-kritisch, #d03b3b); }
.dashboard-zustand.ist-sofort h2  { color: #a4243b; }
.dashboard-zustand.ist-sofort .dashboard-zustand-punkt { background: var(--viz-kritisch, #d03b3b); }

.dashboard-zustand.ist-sieh_hin     { border-left-color: var(--viz-warnung, #fab219); }
.dashboard-zustand.ist-sieh_hin h2  { color: #9a4a06; }
.dashboard-zustand.ist-sieh_hin .dashboard-zustand-punkt { background: var(--viz-warnung, #fab219); }

.dashboard-zustand.ist-ruhig     { border-left-color: var(--viz-gut, #0ca30c); }
.dashboard-zustand.ist-ruhig h2  { color: #2f6b2f; }
.dashboard-zustand.ist-ruhig .dashboard-zustand-punkt { background: var(--viz-gut, #0ca30c); }

.dashboard-zustand.ist-ungeprueft     { border-left-color: var(--db-schwach); }
.dashboard-zustand.ist-ungeprueft h2  { color: var(--db-text-3); }
.dashboard-zustand.ist-ungeprueft .dashboard-zustand-punkt { background: var(--db-schwach); }

@media (max-width: 575.98px) {
    .dashboard-zustand-stand,
    .dashboard-zustand-quellen { margin-left: 0; }
}

/* ── Leitzahl und Leitzeile ────────────────────────────────────

   DIE GROESSE FOLGT DER ABWEICHUNG, NICHT DER KATEGORIE.

   Der erste Anlauf gab jeder Kachel eine 30px-Zahl - und damit schrie
   "49 % Plattenplatz frei" genauso laut wie "letzte Sicherung verschwunden".
   49 % ist Normalzustand. Zwei Leute angemeldet ist Normalzustand. Null
   Protokolleintraege ist Normalzustand. Wer Normalzustaende schreit, hat fuer
   den Ausnahmefall keine Lautstaerke mehr uebrig.

   Ein Dashboard hat EINE laute Stelle - die Zustandszeile oben. Die Kacheln
   darunter sind ruhige Einzelheiten. Nur wenn der Wert einer Kachel selbst
   ein Befund ist, wird er gross: dann traegt er die Dringlichkeit, die er
   verdient, und faellt zwischen den ruhigen auf.

   .dashboard-leitzeile  der Normalfall: eine Zeile, Textgroesse, gedeckt
   .dashboard-leitzahl   der Ausnahmefall: gross und farbig                   */

/* 12px links und rechts wie .dashboard-zeile und .dashboard-progress-zeile.
   Der Kartenrumpf selbst hat KEINE waagerechte Einrueckung - die bringt jede
   Zeile mit. Meine ersten Fassungen von Leitzahl und Leitzeile taten das nicht
   und klebten am Kartenrand; am Rumpf zu drehen haette dagegen jede bestehende
   Zeile in jedem Dashboard doppelt eingerueckt.

   Die Einrueckung ist Innenabstand, kein Rand: Der Trennstrich laeuft weiter
   ueber die volle Breite, so wie bei den Zeilen daneben. */
.dashboard-leitzeile {
    font-size: 14px;
    color: var(--db-text-3);
    padding: 0 12px 10px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--db-linie);
    display: flex;
    align-items: baseline;
    gap: 7px;
}

/* DIE LEITZEILE MUSS IHRE KACHEL ANFUEHREN. Sie stand auf 14px/600 - die
   Listenzeilen darunter stehen auf 13px/600. Ein Pixel und derselbe Schnitt sind
   kein Schritt: Der Normalfall, der in fuenf von sieben root-Kacheln steht, sah aus
   wie eine weitere Zeile der Liste. Die Leitzahl des Ausnahmefalls hat 26px - der
   Abstand dazwischen war die ganze Abstufung, die es gab.

   18px/700 fuer die Aussage, 12px fuer das Beiwerk daneben. Damit fuehrt der ruhige
   Fall seine Kachel an, ohne so laut zu werden wie ein Befund. */
.dashboard-leitzeile b {
    font-size: 18px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: -.01em;
    font-variant-numeric: tabular-nums;
    color: var(--db-text);
}

.dashboard-leitzeile span {
    font-size: 12px;
    /* #807e74 ergab auf Weiss 4,07:1 und verfehlte damit die 4,5:1, die WCAG AA
       fuer Text dieser Groesse verlangt. --db-leise ergibt 5,78:1 und bleibt
       gedeckt - und steht auf derselben Rampe wie der Rest der Anwendung. */
    color: var(--db-leise);
}

/* MITTIG, NICHT AUF DER GRUNDLINIE. Mit `align-items: baseline` lag die erste
   Textzeile auf der Grundlinie der Zahl und die zweite hing darunter ins Leere -
   der Block kippte nach unten weg, und die zweite Zeile hatte optisch keinen
   Bezug mehr zur Zahl. Zentriert haengt der ganze Textblock an ihr. */
.dashboard-leitzahl {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 12px 12px;
    border-bottom: 1px solid var(--db-linie);
    margin-bottom: 12px;
}

.dashboard-leitzahl-wert {
    font-size: 26px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    flex: none;
}

.dashboard-leitzahl-wort {
    font-size: 13px;
    color: var(--db-text-2);
    line-height: 1.35;
    min-width: 0;
}

/* Die zweite Zeile ist Beiwerk - Datum, Herkunft, Vergleichswert. Sie braucht
   eine eigene Abstufung, sonst stehen Aussage und Fussnote gleich laut da. */
.dashboard-leitzahl-neben {
    display: block;
    font-size: 12px;
    /* #807e74 ergab auf Weiss 4,07:1 und verfehlte damit die 4,5:1, die WCAG AA
       fuer Text dieser Groesse verlangt. --db-leise ergibt 5,78:1 und bleibt
       gedeckt - und steht auf derselben Rampe wie der Rest der Anwendung. */
    color: var(--db-leise);
}

/* Dieselben Stufen wie in der Zustandszeile - zwei Farbwelten auf einer
   Seite waeren eine zu viel. Ein RUHIGER Ton ist hier nicht vorgesehen:
   Was ruhig ist, bekommt gar keine Leitzahl. */
.dashboard-leitzahl.ist-sofort .dashboard-leitzahl-wert { color: #a4243b; }
.dashboard-leitzahl.ist-warn .dashboard-leitzahl-wert   { color: #9a4a06; }

/* Lange Bezeichnungen in Listen: eine Zeile, Rest mit Auslassungspunkten.
   Der volle Text steht im title-Attribut. Betriebsnamen sind in dieser
   Anlage bis zu 100 Zeichen lang - umgebrochen schoben sie die Zahlen
   rechts aus dem Blick. */
.ist-eine-zeile {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
    min-width: 0;
}

/* Die Chipzeile als Auskunft: Traegt die Zustandszeile die Befunde, sind die
   verbliebenen Chips keine Alarme mehr. Dann faellt ihre Ampelfarbe weg -
   eine rote Pille unter einer Ueberschrift "Zur Kenntnis" waere ein
   Widerspruch, und Farbe ist auf diesem Dashboard Alarm, nicht Schmuck. */
/* AUF root EINGEGRENZT. `.dashboard-aufgaben` steht in allen fuenf Rollen; dass
   `ist-auskunft` heute nur bei root ankommt, haengt allein daran, dass die Klasse an
   einem gefuellten $db['zustand'] haengt (overview.blade.php) - das ist zufaellig,
   nicht strukturell. Ohne die Eingrenzung wuerde die naechste Rolle, die eine
   Zustandszeile bekaeme, diese Regeln stillschweigend erben. */
.dashboard-page.ist-rolle-root .dashboard-aufgaben.ist-auskunft .dashboard-aufgabe,
.dashboard-page.ist-rolle-root .dashboard-aufgaben.ist-auskunft .dashboard-aufgabe.ist-gefahr,
.dashboard-page.ist-rolle-root .dashboard-aufgaben.ist-auskunft .dashboard-aufgabe.ist-warn,
.dashboard-page.ist-rolle-root .dashboard-aufgaben.ist-auskunft .dashboard-aufgabe.ist-info {
    background: var(--db-flaeche-2);
    color: var(--db-text-2);
    border-color: #e1e0d9;
}

/* ── Nicht berechnet ──────────────────────────────────────────────────────────
   Stolpert eine Kachel, verschwand sie spurlos - auf einer Ueberwachungsseite das
   gefaehrlichste Fehlerbild, weil ein leeres Raster aussieht wie ein ruhiges System.
   Leise gehalten: Es ist kein Befund der Anlage, sondern einer der Anzeige. Nur das
   root-Dashboard rendert diese Zeile ueberhaupt. */
.dashboard-gestolpert {
    margin: 10px 0 0;
    padding: 8px 12px;
    border-left: 3px solid var(--viz-warnung, #fab219);
    background: rgba(250, 178, 25, .07);
    border-radius: 0 6px 6px 0;
    font-size: 12px;
    color: var(--db-leise);
}
.dashboard-gestolpert b { color: #9a4a06; font-weight: 700; }
/* Volle Deckung: .85 ergab 3,69:1 bei 12px und verfehlte AA. */
.dashboard-gestolpert span { opacity: 1; }

/* ── Der Weg vom Befund zur Sache ─────────────────────────────────────────────
   Die Saetze der Zustandszeile sind Verweise. Sie sollen aber nicht wie Verweise
   AUSSEHEN: Fuenf blaue Zeilen uebereinander lesen sich als Navigation, nicht als
   Befund. Deshalb erben sie die Farbe ihrer Stufe und zeigen den Verweis erst beim
   Darueberfahren - und fuer die Tastatur bei Fokus, sonst waere er dort unsichtbar. */
.dashboard-zustand-ziel {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid transparent;
}
.dashboard-zustand-ziel:hover,
.dashboard-zustand-ziel:focus-visible {
    color: inherit;
    border-bottom-color: currentColor;
}
.dashboard-zustand-ziel:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
    border-radius: 2px;
}

/* Wo sich etwas bewegt, darf es sich auf Wunsch nicht bewegen. Die beiden anderen
   Dashboard-Stile fuehren diese Regel seit laengerem, diese Datei nicht. */
@media (prefers-reduced-motion: reduce) {
    .dashboard-card,
    .dashboard-meter-fuellung,
    .dashboard-zustand-ziel {
        transition: none !important;
        animation: none !important;
    }
}

/* ── Schmale Bildschirme: die Zeile, auf der fuenf root-Kacheln stehen ────────
   `.dashboard-progress-zeile` traegt Anlagenzustand, Auffaelliges im Protokoll,
   Sicherheitsbericht, Fachliche Bewegung und Betriebe - und hatte als einzige der
   Zeilenarten KEINE Regel fuer schmale Bildschirme. Ihr Raster ist
   `minmax(0,1fr) 78px`: Die rechte Spalte bleibt bei 390px fest, die linke wird
   gequetscht, und seit die Betriebsliste dort eine zweite Textzeile fuehrt, bricht
   es. Gestapelt hat jede Angabe die volle Breite.

   AUSDRUECKLICH NUR FUER root. Dieselbe Klasse steht in 17 Kachelansichten aller
   Rollen; eine nackte Regel haette vier fremde Dashboards mitgeaendert. Der Haken
   dafuer ist `.ist-rolle-root` am Seitenrumpf (overview.blade.php). */
@media (max-width: 575.98px) {
    .dashboard-page.ist-rolle-root .dashboard-progress-zeile {
        grid-template-columns: minmax(0, 1fr);
        align-items: start;
        gap: 2px;
    }
    .dashboard-page.ist-rolle-root .dashboard-progress-wert {
        text-align: left;
    }
}

/* ════════════════════════════════════════════════════════════════════════════
   NUR DAS root-DASHBOARD

   Alles hier haengt an `.dashboard-page.ist-rolle-root`, weil es Klassen beruehrt,
   die sich bis zu siebzehn Kachelansichten aller Rollen teilen. Der Haken dafuer
   sitzt in overview.blade.php am Seitenrumpf.
   ════════════════════════════════════════════════════════════════════════════ */

/* DIE DREI BEHAELTER DER SELBSTAKTUALISIERUNG SIND KEIN LAYOUT. `.dashboard-page` ist
   ein Flex-Spalten-Container mit 10px Luecke; jeder der drei Behaelter zaehlt als Kind
   und verbraucht seine Luecke auch leer - also ausgerechnet im ruhigen Zustand, wenn
   weder Chipzeile noch Fussnote etwas zu sagen haben. `:empty` greift nicht, weil
   Blade Zeilenumbrueche darin stehen laesst. `display: contents` nimmt sie aus dem
   Layout und laesst sie im Dokument, wo der Takt sie braucht. */
#dashboard-live-zustand,
#dashboard-live-aufgaben,
#dashboard-live-gestolpert { display: contents; }

/* KARTEN, DIE AUF DEM BLATT LIEGEN. Der Seitengrund ist weiss, die Karte ist weiss,
   und dazwischen stand eine 1px-Kante mit 1,22:1 - die Karten schwammen. Zwei sehr
   flache Schatten statt eines harten: der erste setzt die Kante ab, der zweite gibt
   die Hoehe. Dieselbe Rampe wie die uebrige Anwendung (#0f172a). */
.dashboard-page.ist-rolle-root .dashboard-card,
.dashboard-page.ist-rolle-root .dashboard-container-innen {
    box-shadow: 0 1px 2px rgba(15, 23, 42, .05), 0 6px 16px rgba(15, 23, 42, .04);
}

/* EIN TAKT FUER ALLE ZEILEN. `.dashboard-zeile` begruendet weiter oben ihre 44px;
   `.dashboard-progress-zeile` war die einzige Zeilenart ohne Mindestmass und lag je
   nach Inhalt bei 40 oder 51px. Zeilen mit Balken brauchen eine Stufe mehr. */
.dashboard-page.ist-rolle-root .dashboard-progress-zeile { min-height: 44px; }
.dashboard-page.ist-rolle-root .dashboard-progress-zeile:has(.dashboard-meter) { min-height: 56px; }

/* Die rechte Spur war fest 78px. "3.067 Zeilen" braucht rund 92px und wurde
   abgeschnitten oder drueckte die linke Spalte. Mindestens 78, mehr wenn noetig. */
.dashboard-page.ist-rolle-root .dashboard-progress-zeile {
    grid-template-columns: minmax(0, 1fr) minmax(78px, auto);
}

/* Die Zahl in der rechten Spalte traegt die Aussage der Zeile und war gedaempfte 12px:
   `class="db-zahl"` trifft dort KEINE Regel, denn der einzige Selektor dafuer verlangt
   einen Aufgaben-Chip als Elternteil. */
.dashboard-page.ist-rolle-root .dashboard-progress-wert .db-zahl {
    font-size: 16px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--db-text);
}

/* Zahlen, die untereinander stehen, brauchen ein Ziffernraster - sonst springen sie
   von Zeile zu Zeile. Die rechte Spalte der Listen fuehrt "N min inaktiv" und
   Zeitstempel und war die einzige Zahlenspalte ohne. */
.dashboard-page.ist-rolle-root .dashboard-zeile-rechts { font-variant-numeric: tabular-nums; }

/* AA auch dort, wo die anwendungsweite Pille es knapp verfehlt (4,45:1 bei 12px/700). */
.dashboard-page.ist-rolle-root .pba-status-pill.is-success { color: #136f34; }

/* Der Nenner im Chip stand auf opacity .75 und ergab bei 10px bis zu 2,71:1. Die
   Abstufung zum Zaehler tragen jetzt Groesse und Schnitt statt Durchsichtigkeit. */
.dashboard-page.ist-rolle-root .dashboard-aufgabe .db-zahl-von { font-size: 11px; opacity: 1; }

/* Der Balken gegen seine Spur: #fab219 auf #cde2fb ergab 1,39:1 - als Grafik nicht
   unterscheidbar. #9a4a06 ist dasselbe Orange, das die Seite im Text schon fuehrt. */
.dashboard-page.ist-rolle-root { --viz-warnung: #9a4a06; --viz-gut: #15803d; }

/* LESEBREITE. Die Saetze der Zustandszeile liefen auf einem breiten Bildschirm ueber
   rund 175 Zeichen - das verliert die Zeile beim Zurueckspringen. */
.dashboard-page.ist-rolle-root .dashboard-zustand-befunde,
.dashboard-page.ist-rolle-root .dashboard-zustand-satz { max-width: 78ch; }

/* DER STAND BLINKT KURZ AUF, WENN ER SICH ERNEUERT. Ohne eine Zeile JavaScript: Der
   Takt tauscht den Behaelter-Inhalt, das Element entsteht dabei neu, und eine
   Animation an einem neuen Element laeuft von selbst an. Wer Bewegung abbestellt hat,
   bekommt sie nicht. */
@media (prefers-reduced-motion: no-preference) {
    .dashboard-page.ist-rolle-root .dashboard-zustand-stand {
        padding: 1px 6px;
        margin: -1px -6px;
        border-radius: 5px;
        animation: db-stand-frisch 1.4s ease-out;
    }
    @keyframes db-stand-frisch {
        from { background: rgba(15, 23, 42, .10); }
        to   { background: transparent; }
    }
}

/* Die root-Kacheln tragen seit dem 13.10.2026 ein h3 statt eines h5 - die Ueberschrift
   darueber ist ein h2, und h2 -> h5 ueberspringt drei Ebenen. Die GROESSE haengt an der
   Klasse, nicht am Tag; `nachrichten.blade.php` bleibt bei h5, weil die Kachel vier
   weiteren Rollen gehoert. Deshalb hier beide. */
.dashboard-card-header h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    color: var(--db-text);
    line-height: 1.2;
}

/* Der Balken der Plattenzeile: Beschriftung links, Balken nimmt den Rest. Stand
   vorher dreifach inline in der Kachel. */
.dashboard-plattenbalken {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
    padding: 0 12px;
}
.dashboard-plattenbalken .dashboard-zeile-neben { flex: none; }
.dashboard-plattenbalken .dashboard-meter { flex: 1 1 auto; }

/* Das Stufenwort an einem Befund, der von der Ueberschrift abweicht. Klein und
   gedeckt - es ist eine Einordnung, keine zweite Meldung. */
.dashboard-zustand-stufe {
    flex: none;
    align-self: center;
    margin-left: 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--db-leise);
    border: 1px solid var(--db-rahmen);
    border-radius: 999px;
    padding: 0 7px;
    line-height: 18px;
    white-space: nowrap;
}
