/*
 * Die Bauteile: Karte, Häkchen, Zähler, Zustandsetikett, Tagesstreifen, Wochengitter,
 * Leerzustand, Formulare, Meldungen.
 *
 * Entwurf „Karten" (Auswahl 17.08.2026): eine erhobene Fläche je Kategorie, das Bedienelement
 * groß und rund am rechten Rand, darunter einzeilig, was die Regel gerade sagt.
 *
 * Zwei Regeln, die überall gelten und aus docs/02 kommen:
 *   Kein Tap-Ziel unter 44 × 44 px — Maßstab ist ein Daumen, abends, im Halbdunkel.
 *   Kein Zustand allein über Farbe — jedes Etikett trägt zusätzlich ein Zeichen und ein Wort.
 *
 * Keine Farbwerte in dieser Datei: alles kommt aus den Tokens in app.css.
 */

/* --- Karte: eine Kategorie -------------------------------------------------------------- */

.karten {
    display: flex;
    flex-direction: column;
    gap: var(--raum-3);
}

.karte {
    background: var(--flaeche-erhoben);
    border: 1px solid var(--linie);
    border-radius: var(--rund-3);
    padding: var(--raum-4);
    box-shadow: var(--schatten);
}

.karte-kopf {
    display: flex;
    align-items: center;
    gap: var(--raum-3);
}

.karte-kopf .benennung {
    flex: 1;
    min-width: 0;
}

.karte-kopf h2 {
    margin: 0;
}

.karte-kopf .detail {
    margin-top: 2px;
    font-size: 15px;
    color: var(--text-leise);
}

/* --- Häkchen ---------------------------------------------------------------------------- */

.haken {
    flex: none;
    width: 56px;
    height: 56px;
    display: grid;
    place-items: center;
    border: 2px solid var(--linie-stark);
    border-radius: var(--rund-voll);
    background: var(--flaeche);
    color: var(--text-leise);
    font-size: 26px;
    line-height: 1;
    cursor: pointer;
}

.haken[aria-pressed="true"] {
    border-color: var(--gut);
    background: var(--gut);
    color: var(--gut-flaeche);
}

/* --- Zähler ----------------------------------------------------------------------------- */

.zaehler {
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--raum-1);
}

/* Dieselbe Formensprache wie das Häkchen: rund, zwei Pixel Rahmen, dieselbe Fläche. Sie stehen
   an derselben Stelle derselben Karte und tun dasselbe — einen Wert setzen —, und sahen bis dahin
   aus wie zwei Bauteile aus zwei Anwendungen (docs/03, Schritt B). Kleiner als das Häkchen dürfen
   sie bleiben: der Zähler ist zu zweit, das Häkchen allein. */
.zaehler-taste {
    width: 48px;
    height: 48px;
    border: 2px solid var(--linie-stark);
    border-radius: var(--rund-voll);
    background: var(--flaeche);
    color: var(--text);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
}

.zaehler-taste[disabled] {
    color: var(--text-leise);
    cursor: default;
}

.zaehler-wert {
    min-width: 34px;
    text-align: center;
    font-size: 22px;
    font-weight: 640;
    font-variant-numeric: tabular-nums;
}

/* --- Regelstand und Zustandsetikett ----------------------------------------------------- */

.staende {
    margin-top: var(--raum-3);
    display: flex;
    flex-direction: column;
    gap: var(--raum-2);
}

.stand {
    display: flex;
    align-items: center;
    gap: var(--raum-2);
    font-size: 17px;
}

.stand .satz {
    color: var(--text-leise);
}

.etikett {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    border-radius: var(--rund-voll);
    border: 1px solid transparent;
    font-size: 15px;
    font-weight: 620;
    white-space: nowrap;
}

.etikett .zeichen {
    font-size: 13px;
}

/* Der unauffällige Zustand auf „Heute": nur das Zeichen, kein Wort, keine Fläche. Es steht in
   der Breite, die das Etikett hätte, damit die Sätze darunter eine gemeinsame Kante behalten —
   vier Zeilen, die alle zwei Pixel woanders anfangen, sind unruhiger als vier Etiketten. */
.zeichen-leise {
    flex: none;
    display: inline-flex;
    justify-content: center;
    min-width: 20px;
    color: var(--text-leise);
    font-size: 15px;
}

.etikett-met {
    background: var(--gut-flaeche);
    color: var(--gut);
}

.etikett-on_track,
.etikett-open {
    background: var(--flaeche);
    border-color: var(--linie);
    color: var(--text-leise);
}

.etikett-at_limit {
    background: var(--grenze-flaeche);
    color: var(--grenze);
}

.etikett-missed {
    background: var(--gerissen-flaeche);
    color: var(--gerissen);
}

/* --- Fortschritt des Tages -------------------------------------------------------------- */

/*
 * Ein Satz und ein Balken unter der Überschrift von „Heute". Das Bild ist ein SVG, weil eine
 * Breite in Prozent ein `style`-Attribut wäre und die CSP keines zulässt (partials/progress).
 * Die Höhe kommt von hier, die Länge des gefüllten Teils aus dem Blatt.
 *
 * Satz und Balken stehen in einer Zeile: auf der Ansicht, die mehrmals täglich aufgeht, ist
 * jede Zeile, die niemand bedient, eine Zeile, die die erste Karte nach unten schiebt.
 */
.fortschritt {
    margin-top: var(--raum-2);
    display: flex;
    align-items: center;
    gap: var(--raum-3);
}

.fortschritt-satz {
    flex: none;
    font-size: 17px;
    color: var(--text-leise);
}

/* Die Rundung sitzt am Rahmen und nicht an den Rechtecken darin: das Bild wird in der Breite
   gestreckt (preserveAspectRatio="none"), und eine mitgestreckte Ecke wäre eine Ellipse. */
.fortschritt-bild {
    flex: 1;
    min-width: 60px;
    height: 6px;
    border-radius: var(--rund-voll);
    overflow: hidden;
}

.fortschritt-spur {
    fill: var(--linie);
}

.fortschritt-wert {
    fill: var(--akzent);
}

/* Ist der Tag fertig, wechselt der Balken in dieselbe Farbe, die in dieser App „erfüllt" heißt.
   Getragen wird die Aussage vom Satz daneben, wie überall. */
.fortschritt-voll .fortschritt-wert {
    fill: var(--gut);
}

/* --- Tagesstreifen ---------------------------------------------------------------------- */

.tagesstreifen {
    margin-top: var(--raum-5);
    padding-top: var(--raum-4);
    border-top: 1px solid var(--linie);
}

.tagesstreifen h2 {
    font-size: 15px;
    font-weight: 620;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-leise);
}

.tage {
    margin-top: var(--raum-2);
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: var(--raum-1);
}

.tag {
    min-height: 56px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    border: 1px solid transparent;
    border-radius: var(--rund-2);
    font-size: 13px;
    color: var(--text-leise);
    text-decoration: none;
}

.tag .zahl {
    font-size: 17px;
    font-weight: 640;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.tag .punkt {
    width: 6px;
    height: 6px;
    border-radius: var(--rund-voll);
    background: var(--gut);
}

/* Der angezeigte Tag, nicht zwingend der heutige: beim Nachtragen wandert die Hervorhebung
   auf den Tag, für den gerade eingetragen wird. */
.tag-gewaehlt {
    background: var(--akzent);
    border-color: var(--akzent);
    color: var(--akzent-text);
}

.tag-gewaehlt .zahl {
    color: var(--akzent-text);
}

.tag-gewaehlt .punkt {
    background: var(--akzent-text);
}

.tag-kuenftig {
    color: var(--text-leise);
    opacity: 0.55;
}

/* --- Blättern zwischen Wochen ----------------------------------------------------------- */

.blaettern {
    display: flex;
    justify-content: space-between;
    gap: var(--raum-3);
    margin-bottom: var(--raum-4);
}

/* --- Wochengitter ----------------------------------------------------------------------- */

.wochengitter {
    width: 100%;
    border-collapse: collapse;
    background: var(--flaeche-erhoben);
    border: 1px solid var(--linie);
    border-radius: var(--rund-3);
    overflow: hidden;
}

.wochengitter th,
.wochengitter td {
    padding: var(--raum-2);
    border-bottom: 1px solid var(--linie);
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.wochengitter thead th {
    font-size: 15px;
    color: var(--text-leise);
}

.wochengitter th[scope="row"] {
    text-align: left;
    font-weight: 620;
}

.wochengitter .stand-zelle {
    text-align: left;
}

/* Eine Null ist keine Zahl, die jemand liest — sie ist die Abwesenheit einer. Sie steht im
   Markup, damit ein Vorlesegerät die Zelle nicht überspringt; zu sehen ist an ihrer Stelle ein
   Punkt, und der drängt sich nicht auf (docs/03, Schritt D). */
.wochengitter td.leer .menge {
    color: var(--text-leise);
}

.wochengitter .menge {
    font-variant-numeric: tabular-nums;
}

/* Das Häkchen einer abgehakten Kategorie ist grün wie überall in dieser Anwendung, und es steht
   nie allein: das Vorlesegerät hört die Zahl, die daneben im Markup steht. */
.wochengitter td:not(.leer) .menge {
    color: var(--gut);
    font-weight: 640;
}

.wochengitter .heute {
    background: var(--flaeche);
}

/*
 * Unter 700 px ist eine Tabelle mit sieben Spalten nicht lesbar, und Querscrollen ist keine
 * Antwort (docs/02). Das Gitter kippt dann in einen Block je Kategorie — aber die sieben Tage
 * bleiben **ein Streifen** und werden keine sieben Zeilen (docs/03, Schritt D).
 *
 * Sieben Zeilen waren die falsche Form, und zwar messbar: fünf Kategorien ergaben 2362 px, von
 * denen fünfunddreißig Zeilen „0" sagten. Eine Woche ist ein Muster — Montag gut, Dienstag
 * nichts, Mittwoch gut —, und ein Muster liest man in einer Reihe und nicht in einer Liste.
 *
 * Die Spaltenbeschriftung ist hier das Kürzel aus data-kurz; den ganzen Tag samt Zahl trägt
 * jede Zelle als nur-vorlesen-Text in sich, damit ein Vorlesegerät nicht „M 0" hört.
 */
@media (max-width: 699px) {
    .wochengitter,
    .wochengitter tbody,
    .wochengitter tr,
    .wochengitter th,
    .wochengitter td {
        display: block;
        width: 100%;
    }

    .wochengitter {
        border: 0;
        background: none;
    }

    .wochengitter thead {
        display: none;
    }

    .wochengitter tr {
        display: grid;
        grid-template-columns: repeat(7, 1fr);
        column-gap: var(--raum-1);
        margin-bottom: var(--raum-3);
        border: 1px solid var(--linie);
        border-radius: var(--rund-3);
        background: var(--flaeche-erhoben);
        padding: var(--raum-3);
    }

    .wochengitter th[scope="row"] {
        grid-column: 1 / -1;
        padding: 0 0 var(--raum-2);
        font-size: 19px;
        border-bottom: 1px solid var(--linie);
    }

    .wochengitter td {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 2px;
        padding: var(--raum-2) 0 0;
        border-bottom: 0;
        text-align: center;
    }

    .wochengitter td::before {
        content: attr(data-kurz);
        color: var(--text-leise);
        font-size: 13px;
    }

    .wochengitter .stand-zelle {
        grid-column: 1 / -1;
        align-items: flex-start;
        gap: var(--raum-2);
        margin-top: var(--raum-2);
        padding-top: var(--raum-3);
        border-top: 1px solid var(--linie);
        text-align: left;
    }

    .wochengitter .stand-zelle::before {
        content: attr(data-tag);
        font-size: 15px;
    }
}

/* --- Essensplan ------------------------------------------------------------------------- */

/* Sieben Tagesblöcke untereinander, je zwei Felder. Kein Gitter: vierzehn Eingabefelder in
   sieben Zeilen und zwei Spalten sind auf einem Handy nicht zu treffen, und der Daumen wandert
   ohnehin von oben nach unten durch die Woche. */
.essensplan {
    display: flex;
    flex-direction: column;
    gap: var(--raum-4);
}

.essenstag {
    border: 1px solid var(--linie);
    border-radius: var(--rund-2);
    padding: var(--raum-3);
    background: var(--flaeche-erhoben);
}

.essenstag > legend {
    display: flex;
    align-items: center;
    gap: var(--raum-2);
    padding: 0 var(--raum-2);
    font-weight: 660;
}

/* Der heutige Tag im Plan, in derselben Bedienfarbe wie der heutige Tag im Tagesstreifen — und
   seit docs/03 Schritt G auch mit Fläche: ein Rahmen allein war zwischen sechs anderen Rahmen
   kaum zu finden. */
.essenstag.heute {
    border-color: var(--akzent);
    background: var(--akzent-flaeche);
}

/* Das Etikett „Heute" ist kein Regelzustand. Es trug bis dahin die Farbe von „erfüllt", was
   nichts damit zu tun hat: heute ist ein Tag und kein Urteil. */
.etikett-heute {
    background: var(--akzent-flaeche);
    color: var(--akzent);
}

/* Die Speicherleiste des Essensplans: klebt über der Zielleiste, solange die Seite länger ist
   als der Bildschirm. Ohne sie liegt der einzige Knopf der Seite bei y = 1741 (docs/03). */
.speicherleiste {
    position: sticky;
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    z-index: 5;
    display: flex;
    flex-direction: column;
    gap: var(--raum-2);
    margin-top: var(--raum-2);
    padding: var(--raum-3);
    border: 1px solid var(--linie);
    border-radius: var(--rund-2);
    background: var(--flaeche-erhoben);
    box-shadow: var(--schatten);
}

.speicherleiste .knopf {
    align-self: flex-start;
}

/* Ab 700 px steht die Zielleiste oben, also klebt hier nichts mehr über ihr. */
@media (min-width: 700px) {
    .speicherleiste {
        bottom: var(--raum-4);
    }
}

.essensfeld + .essensfeld {
    margin-top: var(--raum-2);
}

.essensfeld label {
    display: block;
    font-size: 15px;
    color: var(--text-leise);
}

.essensfeld input {
    width: 100%;
}

/* Was heute auf dem Tisch steht, unter der Überschrift von „Heute". Eine Zeile, leise: es ist
   eine Auskunft und kein Bedienelement. */
.tagesessen {
    margin-top: var(--raum-2);
    display: flex;
    flex-wrap: wrap;
    gap: var(--raum-1) var(--raum-3);
    font-size: 17px;
    color: var(--text-leise);
}

/* --- Ausklappelement -------------------------------------------------------------------- */

/* <details> für ein Feld, das nicht jeder braucht: das Körperfett auf /gewicht. Ohne
   JavaScript, ohne Einstellung, und offen, sobald etwas drinsteht (docs/02). */
.ausklapp {
    border: 1px solid var(--linie);
    border-radius: var(--rund-1);
    padding: var(--raum-2) var(--raum-3);
}

.ausklapp > summary {
    min-height: var(--griff);
    display: flex;
    align-items: center;
    cursor: pointer;
    color: var(--akzent);
    font-size: 17px;
}

.ausklapp > summary:focus-visible {
    outline: 2px solid var(--akzent);
    outline-offset: 2px;
}

.ausklapp[open] > summary {
    margin-bottom: var(--raum-2);
}

/* --- Das Motiv auf der Anmeldeseite ------------------------------------------------------ */

/*
 * Der Haken, den auch die Icons tragen. Er steht auf der einen Seite, die jemand sieht, bevor er
 * angemeldet ist — bis dahin war das eine graue Seite mit zwei Feldern (docs/03, Schritt A).
 * Farbe über Klassen wie in jeder Zeichnung dieser Anwendung, also stimmt sie in beiden Schemata.
 */
.motiv {
    width: 64px;
    height: 64px;
    margin-bottom: var(--raum-4);
}

.motiv-flaeche {
    fill: var(--akzent);
}

.motiv-haken {
    stroke: var(--akzent-text);
}

/* --- Leerzustand ------------------------------------------------------------------------ */

.leerzustand {
    padding: var(--raum-6) var(--raum-4);
    border: 1px dashed var(--linie);
    border-radius: var(--rund-3);
    text-align: center;
    color: var(--text-leise);
}

.leerzustand p + p {
    margin-top: var(--raum-2);
}

/* --- Hinweise und Meldungen ------------------------------------------------------------- */

.hinweis {
    display: flex;
    gap: var(--raum-2);
    padding: var(--raum-3) var(--raum-4);
    border-radius: var(--rund-2);
    border: 1px solid var(--linie);
    background: var(--flaeche-erhoben);
    margin-bottom: var(--raum-4);
}

/* Ein Hinweis steht sonst über dem Inhalt; folgt er einem Formular, braucht er den Abstand
   nach oben statt nach unten. */
.formular + .hinweis {
    margin-top: var(--raum-5);
    margin-bottom: 0;
}

.hinweis-nachtrag {
    border-color: var(--grenze);
    background: var(--grenze-flaeche);
    color: var(--grenze);
}

.meldung {
    padding: var(--raum-3) var(--raum-4);
    border-radius: var(--rund-2);
    background: var(--gut-flaeche);
    color: var(--gut);
    margin-bottom: var(--raum-4);
}

.fehler {
    padding: var(--raum-3) var(--raum-4);
    border-radius: var(--rund-2);
    background: var(--gerissen-flaeche);
    color: var(--gerissen);
    margin-bottom: var(--raum-4);
}

/* --- Formulare -------------------------------------------------------------------------- */

.formular {
    display: flex;
    flex-direction: column;
    gap: var(--raum-4);
}

.formular > div {
    display: flex;
    flex-direction: column;
    gap: var(--raum-1);
}

.formular label {
    font-size: 15px;
    font-weight: 620;
    color: var(--text-leise);
}

.formular input[type="text"],
.formular input[type="email"],
.formular input[type="password"],
.formular input[type="number"],
.formular input[type="date"],
.formular input[type="time"],
.formular select {
    min-height: var(--griff);
    padding: 0 var(--raum-3);
    border: 1px solid var(--linie-stark);
    border-radius: var(--rund-1);
    background: var(--flaeche-erhoben);
}

/* `flex: none`, weil eine Ankreuzbox in einer Reihe sonst schrumpft: auf /ziele/kategorien war
   sie 13 px breit und 24 hoch, also kein Quadrat mehr und kaum zu treffen (docs/03, Schritt J). */
.formular input[type="checkbox"],
.formular input[type="radio"] {
    flex: none;
    width: 24px;
    height: 24px;
}

/* Eine Ankreuzbox und ihre Beschriftung sind gemeinsam ein Tap-Ziel; getrennt ist die Box
   24 px groß und damit zu klein für einen Daumen. */
.formular .ankreuz {
    flex-direction: row;
    align-items: center;
    gap: var(--raum-3);
    min-height: var(--griff);
}

.formular .ankreuz label {
    font-weight: 400;
    color: var(--text);
}

/* `.hilfe` ist unsere Klasse, `.help-text` die, die das Standard-Formularthema an die
   `help`-Option hängt. Beide sagen dasselbe und sehen deshalb gleich aus; ohne die zweite stand
   die Erläuterung unter einem Formularfeld in Fließtextfarbe und sah aus wie ein Absatz. */
.hilfe,
.formular .help-text {
    font-size: 15px;
    color: var(--text-leise);
}

.knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--griff);
    padding: 0 var(--raum-5);
    border: 1px solid transparent;
    border-radius: var(--rund-1);
    background: var(--akzent);
    color: var(--akzent-text);
    font-size: 17px;
    font-weight: 620;
    cursor: pointer;
}

.knopf-leise {
    background: var(--flaeche);
    border-color: var(--linie-stark);
    color: var(--text);
}

.textknopf {
    display: inline-flex;
    align-items: center;
    min-height: var(--griff);
    color: var(--akzent);
}

/* Feldfehler und Formularfehler kommen aus dem Standard-Formularthema als Liste. Ohne diese
   Regel stehen sie in Textfarbe unter dem Feld und sehen aus wie eine Erläuterung. */
.formular ul {
    display: flex;
    flex-direction: column;
    gap: var(--raum-1);
    font-size: 15px;
    color: var(--gerissen);
}

/* Eine Zeile, solange der Platz reicht: Feld und Knopf nebeneinander, am Handy untereinander.
   Für die kleinen Formulare der Zielseite und des Katalogs, wo jede Zeile ein Ziel ist. */
.formular-reihe {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: var(--raum-3);
}

.formular-reihe .wachsend {
    flex: 1;
    min-width: 12rem;
}

/* --- Ziele und Katalog ------------------------------------------------------------------ */

.ziel + .ziel,
.karte .frueher {
    margin-top: var(--raum-4);
    padding-top: var(--raum-4);
    border-top: 1px solid var(--linie);
}

.ziel {
    margin-top: var(--raum-3);
}

.ziel-satz {
    font-size: 19px;
    font-weight: 620;
}

.ziel .formular {
    margin-top: var(--raum-3);
}

/* Der Satz, der sagt, was das Speichern tun wird — er gehört zum Knopf darüber und nicht zum
   nächsten Formular darunter. */
.ziel .hilfe,
.karte .hilfe {
    margin-top: var(--raum-1);
}

.frueher h3 {
    font-size: 15px;
    font-weight: 620;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-leise);
}

.frueher ul {
    margin-top: var(--raum-2);
    display: flex;
    flex-direction: column;
    gap: var(--raum-1);
    font-size: 15px;
    color: var(--text-leise);
}

/* Eine stillgelegte Kategorie bleibt lesbar und tritt zurück: sie ist Geschichte, nicht Abfall. */
.karte-still {
    border-style: dashed;
    box-shadow: none;
}

/* --- Gewichtskurve ---------------------------------------------------------------------- */

/*
 * Die Geometrie kommt aus App\Chart\Sparkline über Attribute, die Farbe von hier über Klassen.
 * Kein style-Attribut, nirgends — die CSP verbietet es, und ein Browser verwirft es lautlos.
 */

.kurve-rahmen {
    padding: var(--raum-3);
}

.kurve {
    width: 100%;
    height: auto;
}

.kurve-linie {
    fill: none;
    stroke: var(--akzent);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.kurve-punkt {
    fill: var(--akzent);
}

/* Der Meilenstein, gestrichelt: eine Linie, die niemand gemessen hat, sieht anders aus als eine,
   die aus Messwerten besteht. */
.kurve-ziel {
    stroke: var(--linie-stark);
    stroke-width: 1.5;
    stroke-dasharray: 6 4;
}

.kurve-marke {
    fill: var(--text-leise);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

/* --- Wochenbalken im Verlauf ------------------------------------------------------------- */

/*
 * Die Punkte der letzten Wochen als Reihe. Geometrie kommt aus App\Chart\WeekBars über Attribute,
 * Farbe von hier über Klassen — kein style-Attribut, nirgends, wie bei der Kurve.
 *
 * Drei Farben für drei Aussagen, und alle drei benutzt diese Anwendung anderswo für dasselbe:
 * Grün heißt „erfüllt", die Bedienfarbe heißt „läuft noch und ist kein Urteil", und der
 * gewöhnliche Balken ist eine Linie in Textfarbe, weil eine gute Woche kein Alarm ist.
 */
.wochenbalken {
    width: 100%;
    height: 96px;
}

.wochenbalken-wert {
    fill: var(--linie-stark);
}

.wochenbalken-perfekt {
    fill: var(--gut);
}

/* Die laufende Woche ist noch kein Ergebnis: sie steht in der Bedienfarbe und nicht in der
   Farbe, mit der diese App etwas beurteilt. */
.wochenbalken-laufend {
    fill: var(--akzent);
}

.wochenbalken-grund {
    stroke: var(--linie);
    stroke-width: 1;
}

/* --- Liste der letzten Werte ------------------------------------------------------------ */

.werte {
    margin-top: var(--raum-4);
    display: flex;
    flex-direction: column;
}

.werte li {
    display: flex;
    justify-content: space-between;
    gap: var(--raum-3);
    padding: var(--raum-2) 0;
    border-bottom: 1px solid var(--linie);
}

.werte li:last-child {
    border-bottom: 0;
}

.wert-tag {
    color: var(--text-leise);
}

.wert-zahl {
    font-weight: 640;
    font-variant-numeric: tabular-nums;
}

/* --- QR-Code auf /konto ----------------------------------------------------------------- */

.qr {
    padding: var(--raum-3);
    border: 1px solid var(--linie);
    border-radius: var(--rund-2);
    background: var(--flaeche-erhoben);
    width: max-content;
}

.schluessel {
    display: inline-block;
    padding: var(--raum-1) var(--raum-2);
    border-radius: var(--rund-1);
    background: var(--flaeche);
    font-family: ui-monospace, "SFMono-Regular", "Consolas", monospace;
    font-size: 15px;
    letter-spacing: 0.08em;
}

/* --- Vergleichsgitter ------------------------------------------------------------------- */

/* Zwei Spalten mit Regelständen, eine je Person. Der Aufbau ist derselbe wie beim
   Wochengitter — echte Tabelle, echte Kopfzellen, unter 700 px in Blöcke gekippt (docs/02).
   Die Personenfarbe ist eine Klasse und kein Wert: sie kommt aus --person-a/--person-b und
   nicht aus der Datenbank (OFFENE-PUNKTE §7). Sie trägt nie eine Aussage allein — jede Spalte
   nennt den Namen, jeder Zustand ein Zeichen und ein Wort. */
.vergleichsgitter {
    width: 100%;
    border-collapse: collapse;
    background: var(--flaeche-erhoben);
    border: 1px solid var(--linie);
    border-radius: var(--rund-3);
    overflow: hidden;
}

.vergleichsgitter th,
.vergleichsgitter td {
    padding: var(--raum-3);
    border-bottom: 1px solid var(--linie);
    text-align: left;
    vertical-align: top;
    font-variant-numeric: tabular-nums;
}

.vergleichsgitter thead th {
    font-size: 15px;
    color: var(--text-leise);
}

.vergleichsgitter th[scope="row"] {
    font-weight: 620;
    width: 30%;
}

/* Die Farbe sitzt auf einem Streifen an der Spaltenkante und nicht auf der Schrift: ein
   ganzer Regelsatz in Personenfarbe wäre entweder zu blass zum Lesen oder zu laut, und die
   Zustandsetiketten darin haben ihre eigenen Farben. */
.vergleichsgitter .person {
    color: var(--text);
    font-weight: 620;
    font-size: 17px;
    border-top: 3px solid var(--linie);
}

.vergleichsgitter .person-a {
    border-top-color: var(--person-a);
}

.vergleichsgitter .person-b {
    border-top-color: var(--person-b);
}

.vergleichsgitter .du {
    color: var(--text-leise);
    font-weight: 400;
}

.vergleichsgitter .stand + .stand {
    margin-top: var(--raum-2);
}

.punkte {
    font-size: 25px;
    font-weight: 700;
}

/* --- Der Punktestand über dem Gitter ----------------------------------------------------- */

/*
 * Zwei Karten nebeneinander, eine je Person — auch am Handy. Zwei Zahlen, die man vergleichen
 * soll, dürfen nicht untereinander stehen; genau das war der Fehler der alten Fußzeile, und
 * darüber hinaus stand sie am Ende der Seite (docs/03, Schritt C).
 *
 * Die Personenfarbe trägt hier mehr als die drei Pixel im Gitter: den Streifen oben und den
 * Balken. Eine Aussage trägt sie weiterhin nie allein — der Name steht darüber, die Zahl
 * daneben, das Ergebnis darunter als Satz.
 */
.punktestand {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--raum-3);
}

.punktestand-person {
    padding: var(--raum-3);
    border: 1px solid var(--linie);
    border-top: 3px solid var(--linie);
    border-radius: var(--rund-2);
    background: var(--flaeche-erhoben);
}

.punktestand-person.person-a {
    border-top-color: var(--person-a);
}

.punktestand-person.person-b {
    border-top-color: var(--person-b);
}

.punktestand-name {
    font-size: 17px;
    font-weight: 620;
}

.punktestand-zahl {
    display: flex;
    align-items: baseline;
    gap: var(--raum-2);
    margin-top: var(--raum-1);
}

.punktestand-balken {
    width: 100%;
    height: 8px;
    margin-top: var(--raum-2);
    border-radius: var(--rund-voll);
    overflow: hidden;
}

.punktestand-spur {
    fill: var(--linie);
}

.person-a .punktestand-wert {
    fill: var(--person-a);
}

.person-b .punktestand-wert {
    fill: var(--person-b);
}

/* Das Ergebnis gehört zu den zwei Karten darüber und nicht zum Gitter darunter. */
.punktestand + .ergebnis {
    margin-top: var(--raum-3);
}

.abschnitt-eng {
    margin-bottom: var(--raum-5);
}

/* Das Ergebnis ist ein Satz und kein Etikett: „hat die Woche gewonnen", „Gleichstand — und
   dabei bleibt es". Punkte allein sagen nicht, ob schon gezählt wurde. */
.ergebnis {
    font-size: 19px;
}

.meilenstein-stand {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--raum-2);
    margin-top: var(--raum-3);
}

.meilenstein-stand .person {
    font-weight: 620;
}

/* Unter 700 px kippt auch dieses Gitter in Blöcke — aber die zwei Personen bleiben
   **nebeneinander** (docs/03, Schritt C). Untereinander gestapelt war es kein Vergleich mehr:
   das Auge kann zwei Zahlen nur vergleichen, wenn es sie zusammen sieht, und der Block einer
   Kategorie war 190 px hoch, was auf einem Telefon heißt: nie zusammen. Zwei Spalten à rund
   150 px tragen „✓ erfüllt“ und „noch 2 diese Woche“, und mehr steht dort nicht. */
@media (max-width: 699px) {
    .vergleichsgitter,
    .vergleichsgitter tbody,
    .vergleichsgitter tr,
    .vergleichsgitter th,
    .vergleichsgitter td {
        display: block;
        width: 100%;
    }

    .vergleichsgitter {
        border: 0;
        background: none;
    }

    .vergleichsgitter thead {
        display: none;
    }

    .vergleichsgitter tr {
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: var(--raum-3);
        margin-bottom: var(--raum-3);
        border: 1px solid var(--linie);
        border-radius: var(--rund-3);
        background: var(--flaeche-erhoben);
        padding: var(--raum-3);
    }

    .vergleichsgitter th[scope="row"] {
        grid-column: 1 / -1;
        width: 100%;
        padding: 0 0 var(--raum-2);
        font-size: 19px;
        border-bottom: 1px solid var(--linie);
    }

    .vergleichsgitter td {
        padding: var(--raum-3) 0 0;
        border-bottom: 0;
    }

    /* Jede Spalte sagt, wessen sie ist — der Name als Überschrift über der Spalte, der Streifen
       darunter in der Personenfarbe. */
    .vergleichsgitter td::before {
        content: attr(data-tag);
        display: block;
        margin-bottom: var(--raum-2);
        padding-bottom: var(--raum-1);
        color: var(--text-leise);
        font-size: 15px;
        border-bottom: 3px solid var(--linie);
    }

    .vergleichsgitter td.person-a::before {
        border-bottom-color: var(--person-a);
    }

    .vergleichsgitter td.person-b::before {
        border-bottom-color: var(--person-b);
    }

    /* Zwei schmale Spalten: Zeichen und Satz stehen untereinander statt nebeneinander, sonst
       bliebe für den Satz eine Spalte von drei Wörtern Breite. */
    .vergleichsgitter .stand {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--raum-1);
    }
}

/* --- Verlauf --------------------------------------------------------------------------- */

/* Zwei Tabellen: Wochen rückwärts mit Punkten, und je Ziel die Serie. Beide sind schmal genug
   für ein Handy, ohne zu kippen — drei Spalten passen. */
.verlauf {
    width: 100%;
    border-collapse: collapse;
    background: var(--flaeche-erhoben);
    border: 1px solid var(--linie);
    border-radius: var(--rund-3);
    overflow: hidden;
}

.verlauf th,
.verlauf td {
    padding: var(--raum-3);
    border-bottom: 1px solid var(--linie);
    text-align: left;
    font-variant-numeric: tabular-nums;
}

.verlauf thead th {
    font-size: 15px;
    color: var(--text-leise);
}

.verlauf tr:last-child th,
.verlauf tr:last-child td {
    border-bottom: 0;
}

.verlauf .zahl {
    text-align: right;
    white-space: nowrap;
}

/* Eine perfekte Woche ist die einzige Zeile, die sich hervorhebt — und sie trägt zusätzlich
   das Wort, nicht nur den Untergrund. */
.verlauf .perfekt {
    background: var(--gut-flaeche);
}

.verlauf .perfekt th[scope="row"] {
    color: var(--gut);
}

.serie {
    font-weight: 620;
}

/* Die Flammen in „Heute". Rechts am Ende der Standzeile, weil die Zeile links gelesen wird:
   erst was die Regel sagt, dann wie lange es schon gut geht. flex: none, damit sie nicht
   schrumpfen, wenn der Satz daneben lang wird — eine gequetschte Flamme ist ein Fleck. */
.serie-flammen {
    flex: none;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 1px;
}

.flamme {
    display: block;
    fill: var(--serie);
}

/* Die Zahl in der Flamme ab der vierten Woche. Sie sitzt im Bauch der Form, nicht in der
   Mitte des Feldes: oben ist die Spitze, und eine Ziffer darin hätte keinen Platz. */
.flamme-zahl {
    fill: var(--serie-text);
    font-size: 12px;
    font-weight: 700;
}

/* Zweistellig wird es ab zehn Wochen, und dann ist der Bauch der Flamme zu schmal für zwei
   Ziffern in voller Größe. */
.flamme-zahl-schmal {
    font-size: 10px;
}

.serie-null {
    color: var(--text-leise);
    font-weight: 400;
}

/* --- Berührung und Wechsel --------------------------------------------------------------- */

/*
 * Bis hierher war diese App vollkommen still: kein Knopf hat gezeigt, dass der Zeiger auf ihm
 * steht, keiner, dass er gedrückt wird, und die Zeile, die tally.js austauscht, sprang lautlos
 * um (docs/03, „Schönheit — die stille Stelle"). Nichts davon trägt eine Aussage — jede Aussage
 * steht weiterhin als Zeichen und Wort daneben —, aber ohne sie fühlt sich das Abhaken an wie
 * ein Formular und nicht wie ein Haken.
 *
 * Drei Regeln, die dieser Abschnitt einhält:
 *   Wechsel nur auf Farbe, Rahmen und Erhebung — nichts, was die Zeile verschiebt.
 *   Aufleuchten nur am Zeigergerät (`hover: hover`), sonst klebt es nach dem Antippen fest.
 *   Wer Bewegung abbestellt hat, bekommt keine — der Block dafür steht in app.css.
 */

.haken,
.zaehler-taste,
.knopf,
.textknopf,
.tag,
.ausklapp > summary {
    transition: background-color var(--wechsel), border-color var(--wechsel), color var(--wechsel), box-shadow var(--wechsel);
}

@media (hover: hover) {
    .haken:hover,
    .zaehler-taste:not([disabled]):hover {
        border-color: var(--akzent);
        background: var(--akzent-flaeche);
    }

    /* Das erfüllte Häkchen behält seine Farbe: es ist grün, weil es erfüllt ist, und nicht,
       weil niemand darauf zeigt. Es wird nur eine Spur tiefer gefasst. */
    .haken[aria-pressed="true"]:hover {
        background: var(--gut);
        border-color: var(--gut);
        box-shadow: var(--schatten);
    }

    .knopf:hover {
        background: var(--akzent-beruehrt);
        border-color: var(--akzent-beruehrt);
    }

    .knopf-leise:hover {
        background: var(--flaeche-beruehrt);
        border-color: var(--linie-stark);
        color: var(--text);
    }

    .textknopf:hover,
    .ausklapp > summary:hover {
        color: var(--akzent-beruehrt);
    }

    .tag:hover {
        background: var(--flaeche-beruehrt);
    }

    /* Der angezeigte Tag ist schon in der Bedienfarbe; unter dem Zeiger wird er nicht heller,
       sondern fester — sonst sähe der gewählte Tag beim Überfahren aus wie ein anderer. */
    .tag-gewaehlt:hover {
        background: var(--akzent-beruehrt);
        border-color: var(--akzent-beruehrt);
    }
}

/* Gedrückt: am Telefon die einzige Rückmeldung, die es gibt, und deshalb die wichtigere. */
.haken:active,
.zaehler-taste:not([disabled]):active,
.knopf-leise:active,
.tag:active {
    background: var(--flaeche-beruehrt);
}

/* Der volle Knopf hat seine eigene Fläche und bekommt deshalb die eigene Berührungsfarbe —
   grau unter einem blauen Knopf wäre nicht „gedrückt", sondern „ausgeschaltet". Der leise
   Knopf trägt beide Klassen, deshalb muss diese Regel ihn ausdrücklich auslassen. */
.knopf:not(.knopf-leise):active {
    background: var(--akzent-beruehrt);
    border-color: var(--akzent-beruehrt);
}

/* --- Die getauschte Zeile ---------------------------------------------------------------- */

/*
 * Setzt tally.js eine Zeile neu, leuchtet sie einmal auf. Das ist die Antwort auf den Griff:
 * ohne sie ist der einzige Unterschied nach dem Abhaken ein Wort, das sich irgendwo in der
 * Zeile geändert hat, und auf einem Telefon im Halbdunkel sieht das niemand.
 *
 * Als Animation und nicht als Übergang, weil der Zustand danach wieder derselbe sein soll —
 * ein Übergang bräuchte jemanden, der die Klasse wieder abnimmt. Die Klasse selbst nimmt
 * tally.js beim `animationend` ab, damit dieselbe Zeile beim nächsten Griff erneut aufleuchtet.
 */
@keyframes aufleuchten {
    from {
        background-color: var(--akzent-flaeche);
    }

    to {
        background-color: transparent;
    }
}

.staende.frisch {
    border-radius: var(--rund-1);
    animation: aufleuchten 700ms ease-out;
}
