/*
 * Gestaltungslinie ruhrcoder — Belegung für den Heizmonitor.
 *
 * Ein Satz Namen, zwei Belegungen. Die Werte gehören zur gemeinsamen Gestaltungslinie und
 * stammen nicht aus diesem Projekt; wer sie ändert, ändert sie zuerst dort.
 *
 * Zwei Rollen gehen bewusst über die Tabelle der Linie hinaus, weil deren Werte sonst
 * die eigene Kontrastvorgabe verfehlen:
 *
 *   --accent-text     Der Akzent als *Schrift*. `primary-light` (#2d7fa8) erreicht auf
 *                     dem hellen Grund nur 4,09:1 — gefordert sind 4,5:1. Als Fläche und
 *                     als Fokusring bleibt #2d7fa8, dort genügen 3:1.
 *   --control-border  Der Umriss eines Bedienelements. Die Haarlinie trennt, sie bedient
 *                     nicht: `border` mit 10 % Schwarz erreicht 1,26:1 und macht ein
 *                     Eingabefeld auf weißem Grund unsichtbar.
 *
 * Beide Belegungen führen denselben Satz Namen. Fehlt einer, bricht die Seite genau in
 * einer Belegung — und das fällt erst beim Nutzer auf. Ein Test hält das.
 */

/* ── Schriften ────────────────────────────────────────────────────────────
 *
 * Mitgeliefert, nicht nachgeladen: Ein Verweis auf ein fremdes Verteilnetz meldete
 * jeden Besucher dort an. Es sind Variable Fonts — eine Datei trägt alle Gewichte.
 * Geführt werden nur die Bereiche „latin" und „latin-ext"; mehr braucht eine
 * deutschsprachige Oberfläche nicht.
 */

@font-face {
    font-family: "Roboto Flex";
    font-style: normal;
    font-weight: 300 900;
    font-stretch: 100%;
    font-display: swap;
    src: url("../fonts/roboto-flex-latin-o_mNbu_.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
        U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Roboto Flex";
    font-style: normal;
    font-weight: 300 900;
    font-stretch: 100%;
    font-display: swap;
    src: url("../fonts/roboto-flex-latin-ext-c_otkH2.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
        U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
        U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Roboto Mono";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../fonts/roboto-mono-latin-gDELsEF.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
        U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Roboto Mono";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("../fonts/roboto-mono-latin-ext-SJsT-p8.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
        U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
        U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ── Farbrollen, helle Belegung ───────────────────────────────────────── */

:root {
    color-scheme: light;

    /* ── Marke ────────────────────────────────────────────────────────── */
    --primary: #2f4858;
    --primary-dark: #0d2b38;
    --primary-light: #2d7fa8;
    --on-primary: #ffffff;
    --accent-text: #276b8d;

    /* ── Flächen ──────────────────────────────────────────────────────── */
    --bg: #f5f5f5;
    --surface: #ffffff;
    --surface-raised: #ebebeb;
    --surface-hover: #e4e4e4;

    /* Der Grund hinter einer Überlagerung: dunkel genug zum Abheben, hell genug, um die
       Seite darunter noch erkennen zu lassen. */
    --overlay-backdrop: rgba(26, 26, 26, 0.5);

    /* ── Schrift ──────────────────────────────────────────────────────── */
    --text: #1a1a1a;
    --text-muted: #5a5a5a;

    /* ── Linien ───────────────────────────────────────────────────────── */
    --border: rgba(0, 0, 0, 0.1);
    --control-border: #8e8e8e;
    --focus: #2d7fa8;

    /* ── Zustände ─────────────────────────────────────────────────────── */
    /* Gedeckt gehalten; die Aussage tragen Wort und Zeichen, nie die Farbe allein. */
    --state-ok-text: #2c6b3f;
    --state-ok-bg: #e1efe4;
    --state-ok-border: #a9cdb4;

    --state-warn-text: #8a5a17;
    --state-warn-bg: #f6eddd;
    --state-warn-border: #e0c48d;

    --state-error-text: #96332f;
    --state-error-bg: #f5e3e3;
    --state-error-border: #dfafad;

    --state-neutral-text: #5a5a5a;
    --state-neutral-bg: #ebebeb;
    --state-neutral-border: #dcdcdc;

    /* ── Räume ────────────────────────────────────────────────────────── */
    /*
     * Sechs gedeckte Töne, die nebeneinander unterscheidbar bleiben. Sie stehen als
     * kleines Zeichen neben dem Namen des Raums und tragen die Aussage nie allein — wer
     * Farben nicht unterscheiden kann, liest den Namen.
     */
    --room-slate: #5c6b73;
    --room-teal: #2d7f77;
    --room-amber: #a97722;
    --room-rose: #a1545c;
    --room-violet: #6b5b95;
    --room-moss: #5c7a4a;

    /* ── Maße ─────────────────────────────────────────────────────────── */
    /* Grundraster 8 px, Ecken klein: Die Marke ist Industrie, nicht Spielzeug. */
    --space-1: 0.5rem;
    --space-2: 1rem;
    --space-3: 1.5rem;
    --space-4: 2rem;
    --radius: 0.375rem;
    --radius-pill: 999px;
    --hairline: 1px;
    --sidebar-width: 15rem;

    --font: "Roboto Flex", "Segoe UI Variable", "Segoe UI", system-ui, -apple-system, sans-serif;
    --font-mono: "Roboto Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
    --line-height: 1.65;
}

/* ── Farbrollen, dunkle Belegung ──────────────────────────────────────── */

[data-theme="dark"] {
    color-scheme: dark;

    --primary: #c5d0d6;
    --primary-dark: #94a3ab;
    --primary-light: #dde5e9;
    --on-primary: #0f1923;
    --accent-text: #dde5e9;

    --bg: #0f1923;
    --surface: #152030;
    --surface-raised: #1a2535;
    --surface-hover: #213048;
    --overlay-backdrop: rgba(0, 0, 0, 0.6);

    --text: #e4edf2;
    --text-muted: #8aa3b0;

    --border: rgba(255, 255, 255, 0.08);
    --control-border: #5a7288;
    --focus: #dde5e9;

    --state-ok-text: #8fd3a3;
    --state-ok-bg: #16301f;
    --state-ok-border: #2c6b3f;

    --state-warn-text: #e0bc7c;
    --state-warn-bg: #332612;
    --state-warn-border: #8a6a28;

    --state-error-text: #e8a29e;
    --state-error-bg: #341b1b;
    --state-error-border: #8a3a36;

    --state-neutral-text: #8aa3b0;
    --state-neutral-bg: #1a2535;
    --state-neutral-border: #2e3e50;

    /* ── Räume ────────────────────────────────────────────────────────── */
    /* Aufgehellt: Dieselben Töne auf dunklem Grund brauchen mehr Helligkeit. */
    --room-slate: #93a4ad;
    --room-teal: #6ac1b6;
    --room-amber: #d8ab5e;
    --room-rose: #d18d95;
    --room-violet: #a596cc;
    --room-moss: #97b884;
}

/*
 * **Ohne ausdrückliche Wahl bleibt die Seite hell.** Sie folgt nicht dem
 * Betriebssystem: Die Anwendung wird bei Tageslicht gelesen, und eine Messwarte, die
 * beim ersten Aufruf dunkel steht, weil irgendwo ein Schalter steht, überrascht mehr,
 * als sie nützt. Wer es dunkel will, schaltet um — die Wahl hängt am Bildschirm und
 * überlebt als Cookie.
 */

/* ── Grundlagen ───────────────────────────────────────────────────────── */

*,
*::before,
*::after {
    box-sizing: border-box;
}

body {
    margin: 0;
    background-color: var(--bg);
    color: var(--text);
    font-family: var(--font);
    line-height: var(--line-height);
}

/*
 * Der Fokus wird gezeichnet, nicht angedeutet. Wer einem Baustein den Rahmen abnimmt,
 * nimmt ihm auch die Fokusanzeige — deshalb steht sie hier einmal für alles.
 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
    border-radius: var(--radius);
}

a {
    color: var(--accent-text);
}

code,
.key {
    font-family: var(--font-mono);
    font-size: 0.9em;
}

/* Der Sprunglink ist unsichtbar, bis er den Fokus bekommt — dann steht er vorn. */
.skip-link {
    position: absolute;
    top: -3rem;
    left: var(--space-2);
    z-index: 10;
    padding: 0.5rem 1rem;
    border-radius: var(--radius);
    background-color: var(--primary);
    color: var(--on-primary);
    text-decoration: none;
    transition: top 0.1s;
}

.skip-link:focus {
    top: var(--space-1);
}

/* ── Gerüst ───────────────────────────────────────────────────────────── */

.shell {
    display: grid;
    grid-template-columns: var(--sidebar-width) 1fr;
    min-height: 100vh;
}

/*
 * Die Arbeitsfläche nutzt die Breite, die da ist.
 *
 * Eine Spalte in der Mitte lässt auf einem breiten Bildschirm die Hälfte leer, während die
 * Diagramme darin klein bleiben — und um die geht es hier. Der Fließtext bekommt sein
 * eigenes Maß (siehe unten): Eine Zeile über hundert Zeichen liest niemand gern.
 */
.page {
    width: 100%;
    padding: var(--space-4) var(--space-3);
}

/*
 * Lesbares Maß für Fließtext.
 *
 * Nur für Absätze und Aufzählungen, die für sich stehen — nicht für Tabellen, Raster und
 * Zeichnungen. Deshalb an der Karte und nicht an der Seite: In einer Kachel neben elf
 * anderen wäre die Begrenzung sinnlos, in einem Erklärabsatz ist sie der Unterschied
 * zwischen lesbar und nicht.
 */
.card > p,
.card > ul,
.card > ol {
    max-width: 68ch;
}

.page--narrow {
    max-width: 44rem;
    margin: 0 auto;
}

/* ── Seitenleiste ─────────────────────────────────────────────────────── */

.sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-2);
    border-right: var(--hairline) solid var(--border);
    background-color: var(--surface);
}

.sidebar__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    color: inherit;
    font-size: 1.05rem;
    font-weight: 700;
    text-decoration: none;
}

/*
 * Das Zeichen der Anwendung.
 *
 * Es steht auf einem hellen Plättchen — in beiden Belegungen demselben. Das Logo ist
 * dunkelblau auf hellem Grund gezeichnet; auf dunklem Grund stünde entweder ein weißer
 * Kasten oder ein dunkles Zeichen auf dunklem Grund. Der Rundungsradius beschneidet die
 * hellen Ecken der Zeichnung mit.
 */
.brand-mark {
    display: block;
    flex: none;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: var(--radius);
    background-color: #ffffff;
}

.sidebar__nav {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

/*
 * Das Menü in Gruppen.
 *
 * `<details>` erledigt das Auf- und Zuklappen ohne eine Zeile JavaScript, und eine
 * zugeklappte Gruppe bleibt für eine Sprachausgabe erreichbar. Die Gruppe der aufgerufenen
 * Seite steht offen — wer irgendwo ist, sieht seine Nachbarschaft.
 */
.sidebar__group {
    margin-bottom: 0.35rem;
}

.sidebar__group-title {
    padding: 0.35rem 0.65rem;
    border-radius: var(--radius);
    color: var(--text-muted);
    cursor: pointer;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.sidebar__group-title:hover {
    background-color: var(--surface-hover);
    color: var(--text);
}

/* Das Dreieck steht schon im Markup; ein zweites Zeichen daneben wäre Zierat. */
.sidebar__group-title::marker {
    color: var(--text-muted);
}

.sidebar__group[open] .sidebar__group-title {
    color: var(--text);
}

/* Der aktive Punkt ist gefüllt, nicht nur farbig beschriftet. */
.sidebar__link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.75rem;
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    font-size: 0.95rem;
    text-decoration: none;
}

.sidebar__link:hover {
    background-color: var(--surface-hover);
    color: var(--text);
}

.sidebar__link--active {
    background-color: var(--primary);
    color: var(--on-primary);
    font-weight: 600;
}

.sidebar__glyph {
    display: inline-flex;
    flex: none;
    justify-content: center;
    width: 1.25rem;
    color: var(--text-muted);
}

/* Im gefüllten Punkt trägt das Zeichen dessen Schriftfarbe, sonst verschwände es darin. */
.sidebar__link--active .sidebar__glyph {
    color: inherit;
}

/* Nebensächliches sitzt unten und abgesetzt. */
.sidebar__aside {
    margin-top: auto;
    padding-top: var(--space-2);
    border-top: var(--hairline) solid var(--border);
}

/*
 * Unter 60rem trägt die Leiste nicht mehr neben dem Inhalt. Sie legt sich quer über den
 * Kopf und behält dabei Reihenfolge und Aussehen ihrer Punkte.
 */
@media (max-width: 60rem) {
    .shell {
        grid-template-columns: 1fr;
    }

    .sidebar {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--space-2);
        border-right: 0;
        border-bottom: var(--hairline) solid var(--border);
    }

    .sidebar__nav {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .sidebar__aside {
        margin-top: 0;
        margin-left: auto;
        padding-top: 0;
        border-top: 0;
    }

    .page {
        padding: var(--space-3) var(--space-2);
    }
}

/* ── Seitenkopf ───────────────────────────────────────────────────────── */

.page-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.page-head__title {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 700;
}

.page-head__lead {
    margin: 0.25rem 0 0;
    color: var(--text-muted);
}

/* ── Reiter ────────────────────────────────────────────────── */

/*
 * Reiter für Seiten, die eine Seite bleiben.
 *
 * **Ein Reiter ist ein Verweis auf eine Sprungmarke.** Das Blatt dahinter steht über
 * `:target` offen; ohne diese Regeln stehen alle Blätter untereinander und die Seite
 * bleibt vollständig lesbar. Genau deshalb wird hier versteckt und nicht eingeblendet.
 *
 * Die Reihe steht in jedem Blatt — sichtbar ist nur die des offenen. So kommt die
 * Markierung ohne eine Regel je Thema aus.
 */
.tabs__panel {
    display: none;
}

.tabs__panel:target {
    display: block;
}

/*
 * Ohne Sprungmarke steht das erste Blatt offen. `:has()` ist der einzige Weg, das erste
 * wieder zuzuklappen, sobald ein anderes gewählt ist — CSS kennt keinen Blick zurück auf
 * ein früheres Geschwister.
 */
.tabs:not(:has(.tabs__panel:target)) .tabs__panel:first-of-type {
    display: block;
}

.tabs__list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-bottom: var(--space-3);
    border-bottom: var(--hairline) solid var(--border);
}

/*
 * Der offene Reiter sitzt auf einer kräftigen Kante und ist fett — nicht allein an der
 * Farbe zu erkennen. Die Kante liegt auf der Trennlinie der Reihe und ersetzt sie dort.
 */
.tabs__tab {
    padding: 0.45rem 0.9rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    color: var(--text-muted);
    font-size: 0.9rem;
    text-decoration: none;
}

.tabs__tab:hover {
    color: var(--text);
    background-color: var(--surface-hover);
}

.tabs__tab--active {
    border-bottom-color: var(--primary);
    color: var(--text);
    font-weight: 600;
}

/* ── Blätterung ────────────────────────────────────────────── */

/*
 * Sie steht unter der Liste und nennt die Stelle, an der man ist. Ohne die Angabe weiß
 * niemand, ob hinter „Nächste Seite" noch zwei Zeilen kommen oder zweitausend.
 */
.pagination {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    justify-content: space-between;
    margin-top: var(--space-2);
}

.pagination p {
    margin: 0;
}

/* ── Unterseiten eines Bereichs ────────────────────────────────── */

/*
 * Sie sitzt unter dem Seitenkopf und führt zwischen den Seiten eines Bereichs. Die Form
 * ist die der Filterpillen — zwei Bauformen für dieselbe Geste wären eine zu viel.
 *
 * Der aktive Punkt ist gefüllt und fett, nicht nur eingefärbt.
 */
.subnav {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-bottom: var(--space-3);
}

.subnav__link {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.75rem;
    border: var(--hairline) solid var(--control-border);
    border-radius: var(--radius-pill);
    background-color: var(--surface);
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
}

.subnav__link:hover {
    background-color: var(--surface-hover);
    color: var(--text);
}

.subnav__link--active {
    border-color: var(--primary);
    background-color: var(--primary);
    color: var(--on-primary);
    font-weight: 600;
}

/*
 * Abschnittsüberschrift: klein, gesperrt, in Großbuchstaben. Das auffälligste Merkmal
 * der Linie — es ersetzt große Zwischenüberschriften und hält die Seite ruhig.
 */
.section-label {
    margin: var(--space-4) 0 var(--space-2);
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* ── Suchfeld ─────────────────────────────────────────────────────────── */

.searchbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}

.searchbox {
    position: relative;
    flex: 1 1 18rem;
    min-width: 12rem;
}

.searchbox__icon {
    position: absolute;
    top: 50%;
    left: 0.75rem;
    transform: translateY(-50%);
    color: var(--text-muted);
    pointer-events: none;
}

.searchbox__input {
    width: 100%;
    padding: 0.55rem 2.25rem;
    border: var(--hairline) solid var(--control-border);
    border-radius: var(--radius);
    background-color: var(--surface);
    color: var(--text);
    font: inherit;
}

.searchbox__input::placeholder {
    color: var(--text-muted);
}

/* Der Löschen-Knopf über einem leeren Feld hätte nichts zu tun. */
.searchbox__clear {
    position: absolute;
    top: 50%;
    right: 0.4rem;
    transform: translateY(-50%);
    padding: 0.15rem 0.4rem;
    border: 0;
    border-radius: var(--radius);
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    cursor: pointer;
}

.searchbox__clear:hover {
    background-color: var(--surface-hover);
    color: var(--text);
}

/* ── Filterleiste ─────────────────────────────────────────────────────── */

.filterbar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

/*
 * Filter als Chips zum Umschalten: Was gewählt ist, sieht man ohne zu klicken. Der
 * aktive Zustand hängt nicht an der Farbe allein — er ist zusätzlich gefüllt, fett und
 * mit einem Haken versehen.
 */
.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.75rem;
    border: var(--hairline) solid var(--control-border);
    border-radius: var(--radius-pill);
    background-color: var(--surface);
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
}

.chip:hover {
    background-color: var(--surface-hover);
    color: var(--text);
}

/* Ein Ankreuzfeld in Pillenform: Die Wahl der Reihen steht über dem Raster, nicht in einem
   Formular auf einer anderen Seite. */
.chip input[type="checkbox"] {
    margin-right: 0.35rem;
}

.filterbar__label {
    color: var(--text-muted);
    font-size: 0.85rem;
    font-weight: 600;
}

.chip--active {
    border-color: var(--primary);
    background-color: var(--primary);
    color: var(--on-primary);
    font-weight: 600;
}

/* Ein Filter, der wirkt, aber nicht zu sehen ist, sieht aus wie fehlende Daten. */
.active-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
    margin-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: 0.85rem;
}

.chip--removable .chip__remove {
    font-weight: 700;
    line-height: 1;
}

/* ── Kachel ───────────────────────────────────────────────────────────── */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: var(--space-2);
}

/*
 * Kopf farbig, Körper hell — nie umgekehrt. Beim Überfahren wechselt der Rand die
 * Farbe; die Kachel hebt sich nicht an, denn Tiefe vorzutäuschen passt nicht zu einer
 * Marke, die direkt sein will.
 */
.tile {
    display: block;
    overflow: hidden;
    border: var(--hairline) solid var(--control-border);
    border-radius: var(--radius);
    background-color: var(--surface);
    color: inherit;
    text-decoration: none;
}

a.tile:hover {
    border-color: var(--primary-light);
    background-color: var(--surface-hover);
}

.tile__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-1);
    padding: 0.6rem 0.9rem;
    /* Ohne Raumfarbe die Grundfarbe: Kacheln außerhalb der Räume bleiben, wie sie waren. */
    background-color: var(--room-accent, var(--primary));
    color: var(--on-primary);
    font-weight: 600;
}

.tile__title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
 * Zeichen als eingebettetes SVG.
 *
 * Sie erben die Schriftfarbe ihrer Umgebung und passen sich damit beiden Belegungen an,
 * ohne dass es eine zweite Datei gäbe. Die Größe folgt der Schrift daneben — ein Zeichen,
 * das nicht mitwächst, steht bei großer Schrift verloren da.
 */
.icon {
    width: 1em;
    height: 1em;
    flex: none;
    vertical-align: -0.125em;
}

/*
 * Das Zeichen vor einer Abschnittsüberschrift: etwas größer, in der Farbe des Bereichs.
 *
 * Über den Zusammenhang gesetzt und nicht über eine zweite Klasse am Aufruf: Eine Klasse,
 * die in der Vorlage steht, ist eine Zeichenkette in der Vorlage — und der Prüfschritt
 * gegen Text ohne Übersetzung kann sie nicht von einem Satz unterscheiden.
 */
.section-label .icon,
.metric__label .icon {
    width: 1.15em;
    height: 1.15em;
    margin-right: 0.45rem;
    color: var(--room-accent, var(--primary));
}

/* Das Zeichen schmückt; die Aussage trägt die Beschriftung daneben. */
.tile__glyph {
    flex: none;
    font-size: 1.5rem;
    opacity: 0.28;
}

.tile__body {
    padding: 0.75rem 0.9rem;
}

.tile__badge {
    margin-top: var(--space-1);
    color: var(--accent-text);
    font-size: 0.85rem;
    font-weight: 600;
}

/* Bei Kennzahl-Kacheln steht die Zahl groß im Körper, die Beschriftung klein darüber. */
.metric {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.2;
}

.metric__label {
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* ── Beschriftete Angabe ──────────────────────────────────────────────── */

.detail-rows {
    display: grid;
    grid-template-columns: minmax(8rem, auto) 1fr;
    gap: 0.3rem var(--space-2);
    margin: 0;
}

.detail-rows dt {
    color: var(--text-muted);
    font-size: 0.85rem;
}

.detail-rows dd {
    margin: 0;
}

/* ── Karte ────────────────────────────────────────────────────────────── */

.card {
    padding: var(--space-2) var(--space-3);
    border: var(--hairline) solid var(--border);
    border-radius: var(--radius);
    background-color: var(--surface);
}

.card + .card {
    margin-top: var(--space-2);
}

.card p:last-child {
    margin-bottom: 0;
}

/* ── Leerzustand ──────────────────────────────────────────────────────── */

/*
 * Eine leere Fläche ohne Erklärung sieht aus wie ein Fehler. „Nichts vorhanden" und
 * „nichts gefunden" sind zwei Lagen und brauchen zwei Sätze.
 */
.empty-state {
    padding: var(--space-4) var(--space-3);
    border: var(--hairline) solid var(--border);
    border-radius: var(--radius);
    background-color: var(--surface);
    text-align: center;
}

.empty-state__title {
    margin: 0 0 0.35rem;
    font-size: 1.05rem;
    font-weight: 600;
}

.empty-state__text {
    margin: 0 0 var(--space-2);
    color: var(--text-muted);
    font-size: 0.9rem;
}

/* ── Zustandsabzeichen ────────────────────────────────────────────────── */

/*
 * Zeichen und Wort tragen die Aussage, die Farbe unterstützt sie nur. So bleibt der
 * Zustand auch bei einer Rot-Grün-Schwäche ablesbar.
 */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.1rem 0.6rem;
    border: var(--hairline) solid var(--state-neutral-border);
    border-radius: var(--radius-pill);
    background-color: var(--state-neutral-bg);
    color: var(--state-neutral-text);
    font-size: 0.8rem;
    font-weight: 600;
    white-space: nowrap;
}

.badge--ok {
    border-color: var(--state-ok-border);
    background-color: var(--state-ok-bg);
    color: var(--state-ok-text);
}

.badge--warn {
    border-color: var(--state-warn-border);
    background-color: var(--state-warn-bg);
    color: var(--state-warn-text);
}

.badge--error {
    border-color: var(--state-error-border);
    background-color: var(--state-error-bg);
    color: var(--state-error-text);
}

/* ── Schaltflächen ────────────────────────────────────────────────────── */

.button {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 1rem;
    border: var(--hairline) solid transparent;
    border-radius: var(--radius);
    background-color: var(--primary);
    color: var(--on-primary);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.button:hover {
    background-color: var(--primary-dark);
}

.button--secondary {
    border-color: var(--control-border);
    background-color: var(--surface);
    color: var(--text);
}

.button--secondary:hover {
    background-color: var(--surface-hover);
}

/* ── Formulare ────────────────────────────────────────────────────────── */

form label {
    display: block;
    margin-bottom: 0.35rem;
    font-weight: 500;
}

form input,
form textarea,
form select {
    display: block;
    width: 100%;
    margin-bottom: var(--space-2);
    padding: 0.55rem 0.75rem;
    border: var(--hairline) solid var(--control-border);
    border-radius: var(--radius);
    background-color: var(--surface);
    color: var(--text);
    font: inherit;
}

/* Ein fehlerhaftes Feld ist am Rand zu erkennen, nicht nur am Text darunter. */
form input[aria-invalid="true"],
form textarea[aria-invalid="true"],
form select[aria-invalid="true"] {
    border-color: var(--state-error-border);
}

/*
 * Die Fehlermeldung eines Feldes — unter ihm, nicht über ihm.
 *
 * Über dem Feld steht sie da, bevor jemand weiß, worauf sie sich bezieht. Darunter liest
 * sie sich als Antwort auf die eigene Eingabe. Das Zeichen davor trägt die Aussage nicht,
 * es macht die Zeile auf einen Blick als Fehler erkennbar — auch für den, der Rot nicht
 * von Grau unterscheidet.
 */
.field-error {
    margin: -0.65rem 0 var(--space-2);
    color: var(--state-error-text);
    font-size: 0.85rem;
}

.field-error p {
    margin: 0;
}

.field-error p + p {
    margin-top: 0.2rem;
}

.field-error .icon {
    margin-right: 0.35rem;
}

/* ── Hinweise ─────────────────────────────────────────────────────────── */

.notice {
    margin-bottom: var(--space-3);
    padding: 0.6rem 0.9rem;
    border: var(--hairline) solid var(--state-neutral-border);
    border-left-width: 3px;
    border-radius: var(--radius);
    background-color: var(--state-neutral-bg);
    color: var(--state-neutral-text);
}

.notice--error {
    border-color: var(--state-error-border);
    background-color: var(--state-error-bg);
    color: var(--state-error-text);
}

.notice--success {
    border-color: var(--state-ok-border);
    background-color: var(--state-ok-bg);
    color: var(--state-ok-text);
}

.notice--warn {
    border-color: var(--state-warn-border);
    background-color: var(--state-warn-bg);
    color: var(--state-warn-text);
}

/*
    Das Band des Demo-Bestands. Es steht über allem und bleibt beim Blättern stehen: Wer
    einen erfundenen Wert für einen gemessenen hält, hat die Kennzeichnung übersehen — sie
    darf sich also nicht wegscrollen lassen.
*/
.notice--demo {
    position: sticky;
    top: 0;
    z-index: 5;
    border-color: var(--state-warn-border);
    background-color: var(--state-warn-bg);
    color: var(--state-warn-text);
    font-weight: 600;
}

/* ── Tabellen ─────────────────────────────────────────────────────────── */

.table-scroll {
    overflow-x: auto;
}

table {
    width: 100%;
    border-collapse: collapse;
}

th,
td {
    padding: 0.5rem 0.75rem;
    border-bottom: var(--hairline) solid var(--border);
    text-align: left;
}

th {
    color: var(--text-muted);
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

tbody tr:hover {
    background-color: var(--surface-hover);
}

/* ── Erscheinungsbild umschalten ──────────────────────────────────────── */

.theme-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border: var(--hairline) solid var(--control-border);
    border-radius: var(--radius-pill);
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: none;
}

.theme-switch:hover {
    background-color: var(--surface-hover);
    color: var(--text);
}

/* ── Kleinkram ────────────────────────────────────────────────────────── */

.muted,
.hint {
    color: var(--text-muted);
}

.hint {
    font-size: 0.9rem;
}

.list {
    display: grid;
    gap: var(--space-2);
    padding: 0;
    list-style: none;
}

/* ── Für die Sprachausgabe, nicht fürs Auge ───────────────────────────── */

/*
 * Sichtbar für die Sprachausgabe, unsichtbar auf dem Bildschirm. Nicht
 * `display: none` — das nähme das Element auch aus dem Automation-Baum.
 */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ── Zweiter Faktor ───────────────────────────────────────────────────── */

/*
 * Der QR-Code bringt seine eigene helle Fläche mit — ein Lesegerät braucht den Kontrast,
 * unabhängig davon, welches Erscheinungsbild gerade gilt. Der Rahmen setzt ihn deshalb
 * bewusst ab, statt ihn in die Fläche der Karte übergehen zu lassen.
 */
.qr-code {
    display: block;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.code-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: var(--space-1);
    margin: var(--space-2) 0 0;
    padding: 0;
    font-family: var(--font-mono);
    list-style: none;
}

/*
 * Die Meldung des Passkey-Ablaufs steht schon in der Seite, bevor es etwas zu melden gibt.
 * Ohne Inhalt bleibt sie unsichtbar — sonst stünde dort ein leerer roter Kasten.
 */
.notice:empty {
    display: none;
}

.passkey {
    display: grid;
    gap: var(--space-1);
    padding: var(--space-2) 0;
    border-top: 1px solid var(--border);
}

.passkey__name {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: center;
}

.passkey__name input[type="text"] {
    flex: 1 1 14rem;
}

/* ── Einstellungen ────────────────────────────────────────────────────── */

/*
 * Ein Eintrag besteht aus Beschriftung, Feld und zwei Zeilen Erklärung. Der Abstand
 * zwischen den Einträgen trennt sie deutlicher als eine Linie, weil die Erklärungen
 * unterschiedlich lang sind.
 */
.setting {
    display: grid;
    gap: var(--space-1);
    padding: var(--space-2) 0;
}

.setting + .setting {
    border-top: 1px solid var(--border);
}

.setting p {
    margin: 0;
}

/*
 * Herkunft des Werts und das Zurückstellen in einer Zeile: Die Schaltfläche gehört an
 * die Einstellung, die sie betrifft, und nicht in eine Sammelliste am Fuß der Seite.
 */
.setting__origin {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    justify-content: space-between;
}

/* ── Herkunft eines Werts ─────────────────────────────────────────────── */

/*
 * Sie steht neben dem Wert und soll ihn nicht überstimmen: kleiner, ruhiger, umbruchfähig.
 * Die Marke einer Hochrechnung bleibt davon unberührt — sie soll auffallen.
 */
.source {
    display: inline-flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: baseline;
    font-size: 0.85em;
    color: var(--text-muted);
}

.source__reference,
.source__original {
    font-family: var(--font-mono);
}

/* ── Struktur: Objekte, Gebäude, Einheiten, Räume ─────────────────────── */

.structure-unit {
    display: grid;
    gap: var(--space-2);
    padding: var(--space-2) 0;
}

.structure-unit + .structure-unit {
    border-top: 1px solid var(--border);
}

.structure-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: center;
}

/*
 * Die Liste der Räume. Beim Ziehen zeigt der Zeiger an, dass sich hier etwas verschieben
 * lässt; ohne JavaScript bleibt die Liste eine gewöhnliche Liste.
 */
.room-list {
    display: grid;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

.room {
    display: flex;
    gap: var(--space-1);
    align-items: center;
    padding: var(--space-1);
    background: var(--surface-raised);
    border-radius: var(--radius);
}

.room--dragging {
    opacity: 0.5;
}

.room--inactive {
    opacity: 0.6;
}

.room__handle {
    cursor: grab;
}

/*
 * Der Farbtupfer des Raums. Er steht neben dem Namen, nicht an seiner Stelle: Die Farbe
 * ordnet, der Name benennt.
 */
.room__color {
    width: 0.75rem;
    height: 0.75rem;
    border-radius: var(--radius-pill);
    flex: 0 0 auto;
}

/*
 * Die Farbe eines Raums, weitergereicht an alles, was zu ihm gehört.
 *
 * Ein Element mit dieser Klasse setzt `--room-accent`; Kachelkopf, Verlaufslinie und Rand
 * lesen von dort. So trägt ein Raum überall dieselbe Farbe, ohne dass jede Stelle die
 * sechs Farbnamen einzeln kennt.
 *
 * **Die Farbe trägt nie die Aussage allein.** Der Name des Raums steht daneben.
 */
.room-tint--slate { --room-accent: var(--room-slate); }
.room-tint--teal { --room-accent: var(--room-teal); }
.room-tint--amber { --room-accent: var(--room-amber); }
.room-tint--rose { --room-accent: var(--room-rose); }
.room-tint--violet { --room-accent: var(--room-violet); }
.room-tint--moss { --room-accent: var(--room-moss); }

.room__color--slate { background: var(--room-slate); }
.room__color--teal { background: var(--room-teal); }
.room__color--amber { background: var(--room-amber); }
.room__color--rose { background: var(--room-rose); }
.room__color--violet { background: var(--room-violet); }
.room__color--moss { background: var(--room-moss); }

.room__name {
    flex: 1 1 auto;
}

/*
 * Der Umschalter zwischen Objekten. Er steht über der Navigation, weil alles darunter sich
 * auf das gewählte Objekt bezieht — und er erscheint erst, wenn es mehr als eines gibt.
 */
.sidebar__property {
    display: grid;
    gap: var(--space-1);
    padding: 0 var(--space-2) var(--space-2);
}

/*
 * Die Zeitleiste eines Heiztages.
 *
 * Eine Zeichnung und keine Reihe von Kästen: Ein Balken müsste sonst über einen Stil am
 * Element positioniert werden, und feste Maße in einer Vorlage entziehen sich dieser
 * Datei. Die Zeichnung rechnet in Minuten, hier steht nur, wie sie aussieht.
 *
 * Die Balken tragen die Farbe der Marke — die Aussage steht aber in der Tabelle darunter,
 * nicht in der Farbe.
 */
.timeline {
    display: block;
    width: 100%;
    height: 1.5rem;
    margin-bottom: var(--space-1);
}

.timeline__ground {
    fill: var(--surface-hover);
}

.timeline__mark {
    fill: var(--border);
}

.timeline__bar {
    fill: var(--primary);
}

/* Unterbrochen heißt: Hier fehlen Werte. Der Balken bleibt, wird aber blasser. */
.timeline__bar--interrupted {
    fill: var(--state-warn-border);
}

/*
 * Der Vergleich der Räume als Balken.
 *
 * Wie die Zeitleiste eine Zeichnung: Maße gehören nicht als Stil an ein Element. Die
 * Zahlen stehen zusätzlich als Liste darunter — ein Balken allein ist für eine
 * Sprachausgabe keine Auskunft.
 */
.chart {
    display: block;
    width: 100%;
    height: auto;
    margin-bottom: var(--space-2);
}

.chart__bar {
    fill: var(--primary);
}

/*
 * Der Verlauf eines Raums.
 *
 * Die Linien sind auch ohne Farbe zu unterscheiden: Jede trägt ein eigenes Strichmuster.
 * Wer Farben nicht trennen kann, liest die Muster; wer gar nichts sieht, die Tabelle
 * darunter.
 */
.chart--course {
    height: 12rem;
}

.chart__interval {
    fill: var(--state-warn-bg);
}

.chart__line {
    fill: none;
    stroke: var(--primary);
    stroke-width: 1.5;
    vector-effect: non-scaling-stroke;
}

.chart__line--1 { stroke-dasharray: none; }
.chart__line--2 { stroke-dasharray: 6 3; }
.chart__line--3 { stroke-dasharray: 2 2; }
.chart__line--0 { stroke-dasharray: 8 2 2 2; }

/* Der Sollwert ist eine Vorgabe und keine Messung: dünner und zurückgenommen. */
.chart__line--target {
    stroke: var(--text-muted);
    stroke-width: 1;
    stroke-dasharray: 6 3;
}

/*
 * Die Reihen des Raumrasters.
 *
 * Jede trägt ihr eigenes Muster. Die gemessene Temperatur ist durchgezogen und in der Farbe
 * des Raums — sie ist die Aussage. Alles andere ordnet ein und tritt zurück.
 */
.chart__line--temperature {
    stroke: var(--room-accent, var(--primary));
    stroke-width: 1.75;
}

/* Draußen: fein gestrichelt, damit es sich von der Vorgabe unterscheidet. */
.chart__line--outside {
    stroke: var(--state-neutral-border);
    stroke-width: 1;
    stroke-dasharray: 2 2;
}

/* Die Ventilstellung liegt im eigenen Band unten und ist kräftig genug, um dort gesehen zu
   werden — aber nie so kräftig wie die Temperatur darüber. */
.chart__line--valve {
    stroke: var(--accent-text);
    stroke-width: 1.25;
    stroke-dasharray: 8 2 2 2;
}

/* Eine Steueraktion auf der Zeitachse: schmal, kräftig, ohne die Kurve zu verdecken. */
.chart__action {
    fill: var(--state-error-border);
}

/*
 * Die Wochenansicht eines Zeitplans.
 *
 * Wie die übrigen Zeichnungen: Maße gehören nicht als Stil an ein Element. Die
 * Umschaltpunkte stehen zusätzlich als Liste darunter — eine Zeichnung allein ist für eine
 * Sprachausgabe keine Auskunft.
 */
.schedule-week {
    display: block;
    width: 100%;
    height: auto;
    margin-bottom: var(--space-2);
    touch-action: none;
}

.schedule-week__rule {
    stroke: var(--hairline);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.schedule-week__hour,
.schedule-week__day {
    fill: var(--text-muted);
    font-size: 10px;
}

.schedule-week__day {
    font-weight: 600;
}

.schedule-week__point {
    cursor: grab;
}

/* Beim Ziehen halbdurchsichtig: Der Punkt darunter bleibt sichtbar, das Ziel auch. */
.schedule-week__point--dragging {
    cursor: grabbing;
    opacity: 0.6;
}

.schedule-week__body {
    fill: var(--state-warn-bg);
    stroke: var(--state-warn-border);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.schedule-week__caption {
    fill: var(--state-warn-text);
    font-size: 9px;
}

/* Eine Zeile der Umschaltpunkte im Formular: Felder nebeneinander, Schaltfläche daneben. */
.collection-item {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: flex-end;
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--hairline);
}

/*
 * Die Schnellaktionsleiste der Startseite.
 *
 * Sie bleibt beim Blättern stehen: Wer unten eine Kachel ankreuzt, soll nicht wieder nach
 * oben scrollen müssen, um zu handeln. Der Rand nach unten trennt sie von den Kacheln,
 * damit sie im Schwebezustand nicht auf ihnen zu liegen scheint.
 */
.quick-bar {
    position: sticky;
    top: 0;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    margin-bottom: var(--space-3);
    padding: var(--space-2);
    background: var(--surface-raised);
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
}

.quick-bar__scope {
    margin: 0;
    font-weight: 600;
}

.quick-bar__group {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

/* Das Ankreuzfeld sitzt im Kopf der Kachel, links vor dem Namen. */
.tile__choice {
    display: inline-flex;
    align-items: center;
    margin-right: var(--space-1);
}

/*
 * Die Überlagerung.
 *
 * Ein `dialog` bringt Fokusfalle, Esc und die Rückgabe des Fokus selbst mit. Gestaltet wird
 * nur, was die Linie ohnehin vorgibt — Fläche, Haarlinie, Ecke.
 */
.overlay {
    max-width: 48rem;
    width: calc(100% - 2 * var(--space-2));
    padding: var(--space-3);
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
}

.overlay::backdrop {
    background: var(--overlay-backdrop);
}

.overlay__body > :first-child {
    margin-top: 0;
}

/*
 * Die Prüfmaske eines Abrechnungsdokuments.
 *
 * Links die Seite des Originals, rechts die Angaben, die auf ihr gefunden wurden. Die
 * Gegenüberstellung ist der ganze Zweck: Wer eine Zahl bestätigt, soll sie im selben
 * Blickfeld im Original sehen. Auf schmalen Anzeigen rutscht das Original nach oben — dort
 * ist Nebeneinander keine Hilfe mehr, sondern zwei zu enge Spalten.
 */
.review {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-2);
}

@media (min-width: 60rem) {
    .review {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }
}

.review__original {
    width: 100%;
    min-height: 32rem;
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    background: var(--surface-raised);
}

/* Ein Wert mit allem, was ihn belegt: Rohtext, Deutung, Fundstelle, Schaltflächen. */
.review__value {
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--hairline);
}

.review__value:last-child {
    border-bottom: 0;
}

.review__value--open {
    border-left: 3px solid var(--state-warn-border);
    padding-left: var(--space-2);
}

.review__value--discarded {
    color: var(--text-muted);
}

/* Eine fehlende Pflichtangabe wird hervorgehoben und nicht verschwiegen. */
.review__missing {
    padding: var(--space-2);
    color: var(--state-warn-text);
    background: var(--state-warn-bg);
    border: 1px solid var(--state-warn-border);
    border-radius: var(--radius);
}

.review__correction {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: center;
    margin-top: var(--space-1);
}

/*
 * Die Kette der Erfassungsgeräte eines Raums.
 *
 * Eine Liste und keine Zeichnung: Ein Zeitstrahl mit Balken bräuchte Maße am Element, und
 * die Aussage — welches Gerät wann gezählt hat — steht ohnehin im Text. Die senkrechte
 * Linie links macht aus der Liste eine Abfolge, ohne eine Genauigkeit zu behaupten, die
 * eine tagesgenaue Angabe nicht in Pixel überträgt.
 */
.device-chain {
    margin: 0 0 var(--space-2);
    padding-left: var(--space-2);
    list-style: none;
    border-left: 2px solid var(--border);
}

.device-chain__item {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    align-items: baseline;
    padding: 0.4rem 0;
    border-bottom: var(--hairline) solid var(--border);
}

.device-chain__item:last-child {
    border-bottom: 0;
}

.device-chain__kind {
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* Der Zeitraum steht rechts und rückt bei schmalem Fenster unter den Namen. */
.device-chain__range {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 0.9rem;
}

/*
 * Der Verbrauchsvergleich als Balkengruppen.
 *
 * Höher als die Raumvergleichs-Zeichnung: Hier stehen mehrere Perioden je Raum
 * nebeneinander, und bei drei Abrechnungsjahren wären 1,5 rem eine Reihe von Strichen.
 *
 * Ein Schätzwert trägt eine Schraffur und nicht bloß eine andere Farbe. Wer Farben nicht
 * unterscheidet, sähe sonst denselben Balken — und die Aussage steht ohnehin in der
 * Tabelle, nicht in der Zeichnung.
 */
.chart--tall {
    height: 12rem;
}

.chart__bar--estimate {
    fill: url(#estimate-hatch);
}

.chart__bar--estimate-ground {
    fill: var(--surface-hover);
}

.chart__hatch {
    stroke: var(--primary);
    stroke-width: 2;
}

/*
 * Die Punkte der Verbrauchslinie.
 *
 * Ein Schätzwert ist offen gezeichnet, ein abgelesener gefüllt. Die Unterscheidung liegt in
 * der Form und nicht in der Farbe — wer Farben nicht unterscheidet, sähe sonst dieselben
 * Punkte.
 */
.chart__point {
    fill: var(--primary);
}

.chart__point--estimate {
    fill: var(--surface);
    stroke: var(--primary);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

/*
 * Ein Raum in der Gegenüberstellung.
 *
 * Die beiden Reihen stehen untereinander und nicht in zwei Spalten: Nebeneinander wären
 * zwei Zahlen mit verschiedenen Einheiten, die zum Verrechnen einladen. Untereinander, jede
 * mit ihrer Einheit und ihrer eigenen Veränderungsrate, liest sich der Vergleich als das,
 * was er ist — zwei Reihen, die je für sich betrachtet werden.
 */
.divergence-room + .divergence-room {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--hairline) solid var(--border);
}

/*
/*
 * Die Beschriftung unter einem Diagramm.
 *
 * Sie steht im Textfluss und nicht im SVG: Ein Text im Diagramm skaliert mit dem Raster mit
 * und wird bei schmaler Anzeige unleserlich. Läuft sie nicht in eine Zeile, bricht sie um —
 * eine abgeschnittene Beschriftung ordnet nichts mehr ein.
 */
.chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin: 0 0 var(--space-2);
    padding: 0;
    color: var(--text-muted);
    font-size: 0.75rem;
    list-style: none;
}

.chart-legend li {
    flex: 1 1 0;
    min-width: 3rem;
    text-align: center;
}

/* Ein Balken, der nur einordnet und nicht die Aussage trägt. */
.chart__bar--muted {
    fill: var(--surface-hover);
    stroke: var(--primary);
    stroke-width: 0.5;
    vector-effect: non-scaling-stroke;
}

 * Anteile als Balken.
 *
 * Nebeneinander lassen sie sich vergleichen, Kreissegmente nicht — und ein Kreis lügt bei
 * kleinen Anteilen über die Fläche. Der Balken bleibt flach: Er steht in einer Tabellenzelle
 * neben der Zahl und ersetzt sie nicht.
 */
.chart--bar {
    height: 0.5rem;
    margin-bottom: 0;
}

/* Warm und kalt untereinander: eine Trennlinie statt eines Abstands. */
.water-block + .water-block {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--hairline) solid var(--border);
}

/*
 * Ein Befund der Abrechnungsprüfung.
 *
 * Untereinander mit Trennlinie: Befunde sind einzeln zu lesen, und einer, der optisch im
 * vorigen aufgeht, wird überlesen. Der Schweregrad steht als Abzeichen mit Wort davor und
 * nicht als Farbe allein.
 */
.finding + .finding {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--hairline) solid var(--border);
}

.finding__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
    margin-bottom: var(--space-1);
}

.finding__rule {
    font-weight: 600;
}

/*
 * Die Schaltflächen unter einer Auffälligkeit, mit dem Bemerkungsfeld in derselben Zeile.
 *
 * Die Bemerkung gehört zur Handlung und nicht auf eine eigene Seite: Wer erst blättern
 * muss, um zu schreiben, warum er etwas verworfen hat, schreibt es nicht.
 */
.finding__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
    margin-top: var(--space-2);
}

.finding__actions input[type='text'] {
    flex: 1 1 14rem;
    min-width: 0;
}

/*
 * Ein Filter über mehrere Auswahlfelder.
 *
 * Beschriftung über dem Feld und nicht davor: Nebeneinander bricht die Zeile auf einem
 * schmalen Gerät an der falschen Stelle, und dann steht das Wort über dem nächsten Feld.
 */
/*
 * Die kurze Liste der Auffälligkeiten auf der Startseite.
 *
 * Abzeichen, Text und Zeitpunkt in einer Zeile, die auf schmalen Geräten umbricht: Drei
 * Zeilen je Hinweis machten aus fünf Hinweisen eine Seite.
 */
.anomaly-brief {
    display: grid;
    gap: var(--space-1);
    margin: 0 0 var(--space-2);
    padding: 0;
    list-style: none;
}

.anomaly-brief li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
}

.filter-form {
    display: flex;
    flex-wrap: wrap;
    align-items: end;
    gap: var(--space-1) var(--space-2);
}

.filter-form label {
    flex: 0 0 100%;
    margin-bottom: calc(-1 * var(--space-1));
    font-size: 0.85rem;
    font-weight: 600;
}

@media (min-width: 40rem) {
    .filter-form label {
        flex: 0 0 auto;
        align-self: center;
        margin-bottom: 0;
    }
}

 * Die Hochrechnung.
 *
 * Die Spannweite steht groß, die Kennzeichnung unmittelbar daneben — in derselben Zeile und
 * nicht als Fußnote darunter. Wer nur die Zahl liest, hat das Wort schon mitgelesen.
 */
.forecast-headline {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1);
}

/* Mehrere Räume untereinander: eine Trennlinie statt eines Abstands, damit erkennbar
   bleibt, wo ein Raum aufhört. */
.forecast-block + .forecast-block {
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: var(--hairline) solid var(--border);
}

/*
 * Die Kennzahlenreihe der Übersicht.
 *
 * Vier gleich gebaute Kacheln nebeneinander, auf schmaler Anzeige untereinander. Die Zahl
 * trägt die Kachel, die Veränderung steht klein darunter — und als Wort, nicht nur als
 * Vorzeichen: „mehr" und „weniger" liest auch, wer die Farbe nicht unterscheidet.
 */
.metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: var(--space-2);
    margin-bottom: var(--space-2);
}

.metric-card {
    margin-bottom: 0;
}

/* Auf einer Kachel neben drei weiteren wäre die Zahl in voller Größe erschlagend. */
.metric--small {
    font-size: 1.6rem;
}

.metric__unit {
    color: var(--text-muted);
    font-size: 1rem;
    font-weight: 400;
}

.metric__change {
    margin: 0 0 var(--space-1);
    font-size: 0.9rem;
}

/* Eine Verlaufslinie in einer Kachel: flach, ohne Achsen, nur die Form. */
.chart--spark {
    height: 3rem;
    margin-bottom: var(--space-1);
}

/*
 * Das Raster der Räume.
 *
 * Alle Kacheln gleich groß und mit derselben Skala: Der Zweck des Rasters ist der
 * Vergleich. Der auffällige Raum trägt einen kräftigeren Rand *und* ein Wort im Kopf — ein
 * Rand allein unterscheidet für manche gar nichts.
 */
.courses {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--space-2);
    margin-bottom: var(--space-1);
}

.course {
    margin-bottom: 0;
}

/* Der Raum färbt seinen Rand — und über `--room-accent` auch seine Linie. */
.course {
    border-left: 3px solid var(--room-accent, var(--border));
}

.course--outlier {
    border-color: var(--state-warn-border);
    border-left-color: var(--room-accent, var(--state-warn-border));
}

.course .chart__line {
    stroke: var(--room-accent, var(--primary));
}

.course__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-1);
    margin: 0 0 var(--space-1);
    font-weight: 600;
}

/* Der Verlauf in einer Kachel: hoch genug, um eine Form zu zeigen, flach genug für ein Raster. */
.chart--mini {
    height: 4rem;
    margin-bottom: var(--space-1);
}

/*
 * Die Ausreißer.
 *
 * Wie die Hinweise darüber gebaut, aber getrennt davon: Das eine ist ein Befund mit einer
 * Regel dahinter, das andere eine Beobachtung in den Zahlen. Zusammengeworfen sähe beides
 * gleich verbindlich aus.
 */
.outliers {
    display: grid;
    gap: var(--space-1);
    margin: 0 0 var(--space-2);
    padding: 0;
    list-style: none;
}

.outlier {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1);
}

/*
 * Die Hilfe.
 *
 * Das Fragezeichen steht am Titel und nicht am Fuß der Seite: Wer nicht weiterkommt, sucht
 * es dort, wo er gerade liest. Es ist zurückgenommen — es soll auffindbar sein, nicht um
 * Aufmerksamkeit mit dem Inhalt streiten.
 */
/* Titel und Fragezeichen in einer Zeile, damit beides auf derselben Höhe steht. */
.page-head__line {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.page-head__help {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    margin-left: var(--space-1);
    border: var(--hairline) solid var(--control-border);
    border-radius: 50%;
    color: var(--text-muted);
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    vertical-align: middle;
}

.page-head__help:hover {
    border-color: var(--primary-light);
    color: var(--accent-text);
}

/*
 * Die Fußzeile.
 *
 * Sie steht unter jeder Seite, abgesetzt durch eine Linie statt durch einen Kasten: Sie ist
 * Beiwerk und soll den Inhalt nicht noch einmal einrahmen. Auf schmaler Anzeige brechen die
 * Verweise um, statt aus dem Bild zu laufen.
 */
.footer {
    margin-top: var(--space-4);
    padding-top: var(--space-2);
    border-top: var(--hairline) solid var(--border);
    color: var(--text-muted);
    font-size: 0.85rem;
}

.footer__name {
    margin: 0 0 var(--space-1);
}

.footer__links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-2);
    margin: 0;
    padding: 0;
    list-style: none;
}

/*
 * Der Ausdruck.
 *
 * Der Bericht der Gegenüberstellung ist die Grundlage für eine Rückfrage beim Abrechner.
 * Auf Papier haben Schaltflächen und Umschalter nichts verloren, und die dunkle Belegung
 * verbraucht Toner ohne Gewinn: Gedruckt wird auf Weiß.
 *
 * Eine Karte bleibt zusammen. Ein Raum, dessen Befund auf der nächsten Seite steht, ist im
 * Gespräch mit dem Abrechner genau die Stelle, an der jemand blättern muss.
 */
@media print {
    .no-print,
    .sidebar,
    .theme-switch {
        display: none !important;
    }

    body {
        background: #ffffff;
        color: #000000;
    }

    .card {
        break-inside: avoid;
        border: 1px solid #999999;
        background: #ffffff;
        box-shadow: none;
    }

    .divergence-room,
    .finding {
        break-inside: avoid;
    }

    a {
        color: inherit;
        text-decoration: none;
    }
}
