/* Taskboard — Light/Dark über data-theme am <html>.
   Label-Farben stehen NICHT hier: sie sind Nutzerdaten und kommen als nonce-signierter
   <style>-Block aus App\Services\LabelStil (die CSP verbietet style="…"-Attribute). */

:root {
    --bg: #f7f8fb;
    --surface: #ffffff;
    --surface-2: #f1f3f8;
    --text: #1a1d24;
    --muted: #5b6472;
    --border: #e2e6ee;
    --accent: #2f6df6;
    --accent-text: #ffffff;
    --error-bg: #fdecec;
    --error-text: #a11919;
    --flash-bg: #eaf3ff;
    --flash-text: #1c4bb0;
    --radius: 10px;

    --prio-niedrig: #9aa4b4;
    --prio-normal: #cbd3e1;
    --prio-hoch: #e08a1e;
    --prio-dringend: #e05252;

    --frist-offen-bg: #eef1f7;
    --frist-offen-text: #4b5565;
    --frist-bald-bg: #fff4e0;
    --frist-bald-text: #92600b;
    --frist-heute-bg: #ffe9cc;
    --frist-heute-text: #8a4b00;
    --frist-ueberfaellig-bg: #fdecec;
    --frist-ueberfaellig-text: #a11919;

    --gefahr: #c53030;

    /* Platzhalter — der Text, der sagt, was in ein Feld gehört, solange es leer ist: das
       Blasseste im Blatt. Er ist eine Beschriftung, kein Inhalt, und darf nie mit einem
       eingetippten Wert zu verwechseln sein. Eigene Farbe statt `--muted`: Die trägt Werte
       (Zeiten, „Normal", eine Kategorie) und muss dafür lesbar bleiben. */
    --platzhalter: #a3abba;

    /* Abstandsmaß. Zwei Werte statt verstreuter Einzelentscheidungen: --raum trennt die
       großen Bereiche voneinander und vom Fensterrand, --raum-innen gilt innerhalb einer
       Fläche (Spalte, Notizbereich) und zwischen den Kacheln darin. Maßstab ist die
       Zeiterfassung, die 22 px zwischen ihren Bereichen hält. */
    --raum: 1.375rem;
    --raum-innen: 0.7rem;

    /* Die Spaltenbreiten der Aufgabenliste. Sie stehen hier und nicht bei der Tabelle, weil
       zwei Bausteine dieselben Zahlen brauchen: die <col> der Tabelle und die Zeile zum
       Anlegen darüber, deren Felder genau über „ihren" Spalten stehen. Läge jede Zahl an
       ihrem Ort, liefen die beiden beim ersten Nachjustieren auseinander.

       Gemessen ist an den Spaltenköpfen, nicht am Inhalt („KENNUNG" braucht mehr Platz als
       „#a7f"); die Summe ist knapp 67 rem. In rem, damit sie mit der Schriftgröße mitgehen. */
    /* Der feste Zeichensatz. Er gilt für `code` **und** für jede Kennung: `#a7f` ist eine
       Kennung, kein Wort — in einer Proportionalschrift liest man sie Zeichen für Zeichen, in
       einer festen als Block, und zwei Kennungen untereinander sind auf einen Blick zu
       vergleichen. Eine Variable, weil die Liste sonst an sieben Stellen einzeln stünde und beim
       ersten Nachjustieren auseinanderlief. */
    --schrift-fest: ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Die Schriftgröße der Liste. Auch sie ist geteilt: Die Zeile zum Anlegen schreibt in
       derselben Größe wie die Zeilen darunter — sie ist eine von ihnen. */
    --liste-schrift: 0.88rem;

    --liste-haken: 2.2rem;
    --liste-titel: 25rem;
    --liste-labels: 12rem;
    --liste-kennung: 5rem;
    --liste-kategorie: 9rem;
    --liste-prioritaet: 6.2rem;
    --liste-frist: 7.5rem;

    /* Eigene Werte statt --border: der Rahmen ist zu blass, um als Griff zu taugen. */
    --scroll-griff: #cdd4e2;
    --scroll-griff-aktiv: #adb6c8;

}

:root[data-theme="dark"] {
    --platzhalter: #5d6675;

    --bg: #0e1119;
    --surface: #161b26;
    --surface-2: #1c222f;
    --text: #e7ebf3;
    --muted: #9aa4b4;
    --border: #262d3b;
    --accent: #4d82ff;
    --accent-text: #ffffff;
    --error-bg: #3a1d1d;
    --error-text: #ff9d9d;
    --flash-bg: #14243f;
    --flash-text: #a9c8ff;

    --prio-niedrig: #5b6472;
    --prio-normal: #333c4d;
    --prio-hoch: #d99420;
    --prio-dringend: #e26a6a;

    --frist-offen-bg: #1f2634;
    --frist-offen-text: #a7b1c2;
    --frist-bald-bg: #3a2d14;
    --frist-bald-text: #f0c274;
    --frist-heute-bg: #46300f;
    --frist-heute-text: #ffc98a;
    --frist-ueberfaellig-bg: #3a1d1d;
    --frist-ueberfaellig-text: #ff9d9d;

    --gefahr: #f08a8a;

    --scroll-griff: #333c4d;
    --scroll-griff-aktiv: #4a5568;

}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    color: var(--text);
    line-height: 1.5;
}

/* Konturen liegen grundsätzlich INNERHALB der Elementkante (negativer outline-offset).
   Eine Kontur wird außerhalb der Box gezeichnet, und jeder Bereich mit eigenem Scroll —
   Brett, Spaltenliste, Notizstrom, Fenster — beschneidet, was über seine Kante hinausragt.
   Außen liegende Ringe waren deshalb an der ersten und letzten Karte einer Spalte nur zur
   Hälfte zu sehen. Innen liegend sind sie überall vollständig. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

/* Scrollbalken: auf dem Arbeitsbildschirm scrollen Brett, Spaltenlisten und Notizstrom
   jeweils für sich — vier Balken gleichzeitig, die nicht lauter sein sollen als der
   Inhalt. Firefox über die Standardeigenschaften, Chromium/WebKit über ::-webkit-*.
   Der Griff bekommt einen durchsichtigen Rand statt Innenabstand (den es nicht gibt);
   background-clip sorgt dafür, dass die Farbe hinter dem Rand aufhört. */
html {
    scrollbar-width: thin;
    scrollbar-color: var(--scroll-griff) transparent;
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--scroll-griff);
    background-clip: padding-box;
    border: 3px solid transparent;
    border-radius: 8px;
}
::-webkit-scrollbar-thumb:hover {
    background: var(--scroll-griff-aktiv);
    background-clip: padding-box;
}
::-webkit-scrollbar-corner { background: transparent; }

/* ---------- Kopfleiste & Navigation ---------- */

/* Die App-Leiste liegt im Inhaltsfluss und ist deshalb genau so breit wie der Inhalt
   darunter — sie sieht aus wie eine Karte, nicht wie ein Balken über die Fensterbreite.
   Links steht am Board der Filter, auf allen anderen Seiten der Seitentitel. */
.appbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    padding: 0.5rem 0.7rem;
    margin-bottom: var(--raum);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
/* Ein aktiver Filter färbt die Kante der Leiste. Das ist der ganze Hinweis — er braucht
   keine eigene Zeile unter der Leiste, und die Leiste sieht man ohnehin an. */
.appbar-gefiltert { border-color: var(--accent); }
.filter-treffer {
    font-size: 0.78rem;
    color: var(--accent);
    white-space: nowrap;
    cursor: help;
}

/* Der linke Block nimmt den Platz, die Icons bleiben rechts. */
.appbar-links { flex: 1 1 16rem; min-width: 0; }
.appbar-titel {
    display: inline-block;
    padding: 0.2rem 0.15rem;
    font-weight: 600;
    text-decoration: none;
    color: var(--text);
}

/* Meldungen sitzen klein in der Leiste, links neben den Icons, und schieben nichts
   umher: der Platz ist auch leer vorhanden. Dieselbe kleine Pille zeigt das überlagerte
   Fenster bei sich (.fenster-meldung) — ein Aussehen, an einer Stelle beschrieben. */
.appbar-meldung { margin-left: auto; min-width: 0; }
.appbar-meldung .flash,
.fenster-meldung .flash {
    margin: 0;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: opacity 0.4s ease;
}
.appbar-meldung .flash.vergeht,
.fenster-meldung .flash.vergeht { opacity: 0; }

/* Einstellungsmenü hinter dem Zahnrad: Labels, Spalten, Protokoll. */
.menu { position: relative; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu[open] > summary { border-color: var(--accent); }

.menu-inhalt {
    position: absolute;
    right: 0;
    top: calc(100% + 0.4rem);
    min-width: 12.5rem;
    z-index: 60; /* über der gezogenen Karte (z-index 50) */
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.35rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 14px 30px rgba(0, 0, 0, 0.18);
}
.menu-inhalt hr { margin: 0.35rem 0.2rem; }
.menu-inhalt form { display: contents; }

/* Zwei Klassen tief, damit die Punkte die allgemeinen Knopf-Regeln (blauer Submit,
   quadratischer .theme-toggle) sicher schlagen — unabhängig von der Reihenfolge. */
.menu-inhalt .menu-punkt {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    min-width: 0;
    height: auto;
    align-self: stretch;
    padding: 0.45rem 0.6rem;
    border: none;
    border-radius: 7px;
    background: none;
    color: var(--text);
    font: inherit;
    font-weight: 400;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}
.menu-inhalt .menu-punkt:hover { background: var(--surface-2); }
.menu-inhalt .menu-punkt[aria-current="page"] { color: var(--accent); font-weight: 600; }
.menu-inhalt .menu-punkt svg { width: 1.05rem; height: 1.05rem; flex: 0 0 auto; }

.theme-toggle, .icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 0.35rem;
    border: 1px solid var(--border);
    border-radius: 7px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-weight: 400;
    cursor: pointer;
}
.icon-btn[disabled] { opacity: 0.4; cursor: not-allowed; }
.theme-toggle svg, .icon-btn svg { width: 1.15rem; height: 1.15rem; }

:root[data-theme="light"] .ic-dark { display: none; }
:root[data-theme="dark"] .ic-light { display: none; }

/* ---------- Layout ---------- */

.container {
    max-width: 720px;
    margin: 0 auto;
    padding: var(--raum);
}
/* Gilt für die breiten *Seiten* (Kalender). Der Arbeitsbildschirm hat seine Obergrenze
   ohnehin nicht: body.vollhoehe .container setzt max-width: none — er füllt immer das ganze
   Fenster. Diese Zahl hier zu erhöhen ändert an der Tabelle deshalb nichts. */
.container-wide { max-width: 1600px; }

/* Arbeitsbildschirm: die Seite füllt das Fenster, gescrollt wird nur INNERHALB der
   Bereiche. Damit bleibt das Board neben der eigentlichen Arbeit stehen, ohne dass die
   Kopfleiste weggescrollt wird. Schmale Bildschirme fallen unten auf normalen
   Seitenfluss zurück. */
body.vollhoehe {
    height: 100vh; /* Rückfall für Browser ohne dvh */
    height: 100dvh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
/* Die Leiste behält ihre Höhe; nur die Arbeitsfläche darunter gibt nach. Den Abstand
   macht hier der gap des Containers. */
body.vollhoehe .appbar { flex: 0 0 auto; margin-bottom: 0; }
body.vollhoehe .container {
    flex: 1 1 auto;
    min-height: 0;
    max-width: none;
    display: flex;
    flex-direction: column;
    gap: var(--raum);
    padding: var(--raum);
}

.arbeitsflaeche {
    flex: 1 1 auto;
    min-height: 0;
    display: grid;
    /* Die Tabelle bekommt allen Platz, den der Notizstrom nicht braucht. Er ist schmaler
       als früher (bis 2026-08-18: 19–25 rem): Ein Notizeintrag sind zwei bis drei Zeilen
       Text, die Tabelle hat sieben Spalten zu zeigen. */
    grid-template-columns: minmax(0, 1fr) clamp(16rem, 19vw, 22rem);
    gap: var(--raum);
}
/* Links die Aufgabenliste, rechts der Notizstrom. Beide füllen die Höhe und scrollen für
   sich; die weichen Kanten des früheren Bretts sind mit ihm weggefallen — eine Liste
   scrollt senkrecht, und dafür genügt der Scrollbalken. */
.liste-bereich {
    display: flex;
    flex-direction: column;
    gap: var(--raum-innen);
    min-width: 0;
    min-height: 0;
}

h1 { font-size: 1.5rem; margin: 0 0 0.75rem; }
h2 { font-size: 1.1rem; }

.abschnitt { margin: 0 0 0.75rem; font-size: 1rem; text-transform: none; }
.muted { color: var(--muted); }
.klein { font-size: 0.85rem; }
.brotkrumen { margin: 0 0 0.75rem; font-size: 0.9rem; }
.brotkrumen a { color: var(--muted); text-decoration: none; }
.brotkrumen a:hover { color: var(--text); }

/* Kompakt in sich, luftig zueinander: weniger Polsterung innen, klarer Abstand außen. */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 0.85rem 1rem;
    margin: var(--raum) 0;
}

.flash { background: var(--flash-bg); color: var(--flash-text); padding: 0.7rem 1rem; border-radius: 8px; }
.error { background: var(--error-bg); color: var(--error-text); padding: 0.7rem 1rem; border-radius: 8px; }
.hinweis {
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--muted);
    padding: 0.55rem 0.9rem;
    border-radius: 8px;
    font-size: 0.9rem;
}

code {
    font-family: var(--schrift-fest);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0.05rem 0.35rem;
    font-size: 0.9em;
}

hr { border: none; border-top: 1px solid var(--border); margin: 1rem 0; }

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

label { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.88rem; color: var(--muted); }

input, select, textarea {
    font: inherit;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 7px;
    padding: 0.32rem 0.55rem;
    max-width: 100%;
}
textarea { resize: vertical; }
/* Ein Platzhalter tritt zurück: Er sagt nur, was hier hingehört. `opacity: 1` muss dastehen —
   Firefox dämpft Platzhalter von sich aus zusätzlich, und dann wäre die Farbe hier nur die halbe
   Wahrheit. */
::placeholder { color: var(--platzhalter); opacity: 1; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
input[type="color"] { padding: 0.15rem; width: 2.8rem; height: 2rem; }

/* Abgeschaltet heißt lesbar, aber nicht bedienbar: Der Wert muss zu sehen sein — an einer
   erledigten Aufgabe stehen dort Kategorie, Priorität und Frist, und die will man nachlesen. Nur
   die Einladung zum Tippen fällt weg. Bis heute trug das allein der Browser-Standard (der
   abgeschaltete Löschen-Knopf unter /spalten etwa); jetzt sagt es das Blatt selbst. */
:disabled { cursor: not-allowed; }
input:disabled, select:disabled, textarea:disabled {
    background: var(--surface-2);
    color: var(--muted);
}
.btn:disabled, .knopf-link:disabled { opacity: 0.5; }
.labelwahl-punkt input:disabled + .label-pille { opacity: 0.55; }
.labelwahl-punkt:has(input:disabled) { cursor: not-allowed; }

/* Eine Gruppe **ohne eigenes Aussehen**: Sie ist nur da, um mit einem `disabled` alles darin
   abzuschalten — auch über mehrere Formulare hinweg, denn das Attribut wirkt auf jeden Nachkommen.
   `display: contents` nimmt ihre Box aus dem Layout, sonst zerschnitte das <fieldset> das Raster,
   in dem seine Kinder stehen (siehe .karte-meta). */
.feldgruppe { display: contents; border: 0; margin: 0; padding: 0; min-width: 0; }
input[type="checkbox"] { width: auto; }

/* Nur .btn, nicht button[type="submit"]: Ein Elementselektor für ein Aussehen schlägt
   jede einfache Klasse und hat wiederholt Knöpfe blau gefärbt, die längst eine eigene
   Gestalt hatten (Abmelden, Icons, Textlinks). Wer wie ein Knopf aussehen soll, sagt es. */
.btn {
    display: inline-block;
    align-self: start;
    font: inherit;
    font-weight: 600;
    color: var(--accent-text);
    background: var(--accent);
    border: none;
    border-radius: 7px;
    padding: 0.28rem 0.7rem;
    font-size: 0.92rem;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
}
.btn-klein { padding: 0.18rem 0.5rem; font-size: 0.84rem; }
.btn-still { background: var(--surface-2); color: var(--text); border: 1px solid var(--border); }
.btn-gefahr { background: var(--gefahr); }
.knopf-link {
    font: inherit;
    font-size: 0.85rem;
    background: none;
    border: none;
    padding: 0;
    color: var(--muted);
    cursor: pointer;
    text-decoration: underline;
}
.knopf-link:hover { color: var(--text); }
.knopf-gefahr { color: var(--gefahr); }
.knopf-link[disabled] { opacity: 0.45; cursor: not-allowed; text-decoration: none; }

/* Die Kennung ist zum Mitnehmen: ein Klick legt sie in die Ablage (kennung.js). Der Knopf
   erbt sein Aussehen von der Stelle, an der er steht (.karte-nummer auf der Kachel,
   .karte-meta-wert auf der Kartenseite) — deshalb steht dieser Rückbau hier oben und
   nicht dort: Was später im Blatt steht, behält das Wort über Schriftgröße und Farbe.
   Die Fläche bleibt das kurze Wort; der kleine Innenabstand ist nur da, damit der innen
   liegende Fokusring nicht in der Schrift steht. */
.kennung-kopieren {
    padding: 0.05rem 0.25rem;
    border: 0;
    border-radius: 5px;
    background: none;
    color: inherit;
    font: inherit;
    cursor: copy;
}
.kennung-kopieren:hover,
.kennung-kopieren.kopiert { color: var(--accent); background: var(--surface-2); }

/* ---------- Verfassen (neue Karte, neue Notiz) ---------- */

/* Das Feld ist im Ruhezustand eine Zeile hoch und wächst beim Tippen mit. Gemessen wird
   über einen unsichtbaren Zwilling im selben Rasterfeld (::after), der denselben Text
   trägt — die Höhe kommt damit aus dem Layout und nicht aus einem style-Attribut, das
   die CSP ohnehin verbietet. app.js pflegt nur data-spiegel. */
.verfassen { position: relative; display: grid; }

.verfassen > textarea,
.verfassen::after {
    grid-area: 1 / 1 / 2 / 2;
    font: inherit;
    /* Dieselbe Größe wie der Kartentitel, den das Feld gleich erzeugt. Sie muss auf Feld
       und Zwilling identisch stehen, sonst misst der Zwilling eine andere Höhe. */
    font-size: 0.9rem;
    line-height: 1.4;
    min-height: 2rem;
    padding: 0.35rem 2rem 0.35rem 0.55rem;
    border: 1px solid var(--border);
    border-radius: 7px;
}
.verfassen::after { content: none; }

html.js .verfassen > textarea { resize: none; overflow: hidden; }
html.js .verfassen::after {
    content: attr(data-spiegel) " ";
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    visibility: hidden;
}
/* Ohne JavaScript wächst nichts mit — dann lieber gleich Platz für ein paar Zeilen. */
html:not(.js) .verfassen > textarea { min-height: 4.5rem; }

.verfassen .verfassen-knopf {
    position: absolute;
    right: 0.3rem;
    bottom: 0.3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: none;
    color: var(--muted);
    opacity: 0.5;
    cursor: pointer;
}
.verfassen .verfassen-knopf svg { width: 0.95rem; height: 0.95rem; }
.verfassen .verfassen-knopf:hover { color: var(--text); opacity: 1; }
/* Sobald etwas im Feld steht, tritt das Symbol hervor. */
.verfassen > textarea:not(:placeholder-shown) ~ .verfassen-knopf {
    color: var(--accent);
    opacity: 1;
}

.formular { display: flex; flex-direction: column; gap: 0.7rem; }
.formular-reihe { display: flex; flex-wrap: wrap; gap: 0.7rem; }
.formular-reihe label { flex: 1 1 10rem; }

.labelwahl { display: flex; flex-wrap: wrap; align-items: center; gap: 0.1rem; min-width: 0; }

/* Geschaltet wird die Pille selbst. Das Ankreuzfeld bleibt bedienbar, ist aber nur für
   Vorlesewerkzeuge sichtbar — deshalb kein display:none. */
.labelwahl-punkt {
    display: inline-flex;
    align-items: center;
    margin: 0.15rem 0.35rem 0.15rem 0;
    cursor: pointer;
}
/* Das Ankreuzfeld dahinter versteckt die Filterleiste mit (.prio-punkt input). */
/* Nicht gesetzt: nur Kontur. Gesetzt: die Farbe des Labels. */
.labelwahl-punkt .label-pille {
    background: none;
    border-color: var(--border);
    color: var(--muted);
}
.labelwahl-punkt input:checked + .label-pille {
    background: color-mix(in srgb, var(--label-farbe, var(--surface-2)) 14%, transparent);
    border-color: color-mix(in srgb, var(--label-farbe, var(--border)) 45%, transparent);
    color: color-mix(in srgb, var(--label-farbe, var(--text)) 60%, var(--text));
}
.labelwahl-punkt input:focus-visible + .label-pille { outline: 2px solid var(--accent); outline-offset: -1px; }
.labelwahl-punkt:hover .label-pille { border-color: var(--accent); }

/* ---------- Bearbeiten direkt im Feld ---------- */

/* Ohne JavaScript trägt jedes Feld seinen Speichern-Knopf; mit JavaScript speichert
   es beim Verlassen und der Knopf ist überflüssig. */
html.js .feld-form > button[type="submit"] { display: none; }

.feld-form { display: flex; align-items: flex-end; gap: 0.5rem; margin: 0; }

/* Titel: sieht aus wie eine Überschrift, wird beim Hineinklicken zum Feld. */
.feld-titel { flex: 1 1 auto; min-width: 0; }
/* Das h1 ist selbst ein Flex-Element (neben dem Speichern-Knopf) und bliebe sonst auf
   Inhaltsbreite stehen — das width:100% des Feldes darin hätte dann nichts zu füllen. */
.feld-titel h1 { flex: 1 1 auto; min-width: 0; margin: 0; }
.feld-titel input {
    width: 100%;
    padding: 0.1rem 0.35rem;
    font: inherit;
    font-size: 1.5rem;
    font-weight: 600;
    background: none;
    border-color: transparent;
}
.feld-titel input:hover { border-color: var(--border); }
.feld-titel input:focus { background: var(--bg); border-color: var(--border); }

/* Der Fristzustand färbt nicht mehr das Eingabefeld: er steht als dieselbe Marke wie auf
   der Kachel unter dem Feld (.karte-meta-fuss). Ein Datumsfeld mit rotem Rahmen sah aus
   wie ein Eingabefehler, nicht wie eine überfällige Aufgabe. */

/* Beschreibung: gerendertes Markdown, das auf Klick zum Eingabefeld wird. */
.feld-anzeige { cursor: text; border-radius: 8px; padding: 0.2rem 0.35rem; margin: -0.2rem -0.35rem; }
html.js .feld-anzeige:hover { background: var(--surface-2); }
.feld-editor { display: block; margin-top: 0.6rem; }
.feld-editor textarea { width: 100%; }
html.js .feld-editor { display: none; }
html.js .feld.bearbeitet .feld-anzeige { display: none; }
html.js .feld.bearbeitet .feld-editor { display: block; margin-top: 0; }

.karte-loeschen { margin: 1.25rem 0 0.5rem; }

/* ---------- Kartenansicht: Aufbau ---------- */

/* Die Beschreibung ist die Fläche, auf der das Auge landen soll: direkt unter dem Titel,
   ohne Überschrift, ohne Rahmen — und mit Platz, damit sie auch leer als Fläche wirkt. */
.karte-text { margin: 0.9rem 0 var(--raum); }
.karte-text .feld-anzeige { min-height: 4.5rem; }

/* Alles Beiwerk in einem Block, klein gesetzt und leicht abgesetzt: es soll auffindbar
   sein, aber nicht mit Titel und Beschreibung um Aufmerksamkeit ringen. */
.karte-meta {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    align-items: start;
    gap: 0.75rem 1.1rem;
    padding: 0.8rem 0.9rem;
    background: var(--surface-2);
    border-radius: var(--radius);
    font-size: 0.85rem;
}

/* Zelle, Formular und Beschriftung sind derselbe schmale Stapel: Etikett oben, Steuerung
   darunter, Hinweis ganz unten. Weil alle Zellen oben beginnen (align-items: start),
   stehen die Steuerungen auf einer Linie — vorher richtete sich die Reihe unten aus und
   der Hinweis unter der Frist hob ihr Datumsfeld nach oben. */
.karte-meta-feld,
.karte-meta .feld-form,
.karte-meta .feld-form > label {
    display: grid;
    align-content: start;
    gap: 0.25rem;
    min-width: 0;
}
.karte-meta .feld-form > button[type="submit"] { justify-self: start; }

/* Die Beschriftung ist ein Etikett, kein Wort im Satz — dasselbe Zeichen wie die
   Blocktitel der Abschnitte darunter, damit die Seite eine Sprache spricht. */
.karte-meta-name {
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
}
.karte-meta select,
.karte-meta input[type="date"] { width: 100%; font-size: 0.85rem; padding: 0.2rem 0.4rem; }
/* justify-self: Die Zelle ist ein Raster, ein Knopf darin würde sonst über die ganze
   Spaltenbreite gehen — die Fläche soll aber nur das kurze Wort sein. */
.karte-meta-wert { justify-self: start; font-variant-numeric: tabular-nums; }

/* Unter der Steuerung: Fristzustand, „beim Abhaken neu“, „entfernen“. Klein und leise. */
.karte-meta-fuss {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.72rem;
}
.karte-meta-fuss form { margin: 0; }
.karte-meta-fuss .knopf-link { font-size: 0.72rem; }

/* Die Labels bekommen ihre eigene Zeile über die volle Breite: als Zelle im Raster
   würden sie in eine schmale Spalte gezwungen und dort umbrechen. */
.karte-meta-labels {
    grid-column: 1 / -1;
    padding-top: 0.7rem;
    border-top: 1px solid var(--border);
    min-width: 0;
}

/* Kommentare, Rückverweise und Verlauf: gegliedert durch eine feine Linie und eine
   kleine Überschrift, nicht durch je einen eigenen Kasten. */
.karte-block { margin-top: var(--raum); padding-top: 0.8rem; border-top: 1px solid var(--border); }
.karte-block-titel {
    margin: 0 0 0.6rem;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
}

/* Der Verlauf beginnt zugeklappt; die Zusammenfassung trägt schon die beiden Zeitangaben,
   nach denen man meistens sucht. */
.karte-verlauf > summary {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem;
    cursor: pointer;
    list-style: none;
}
.karte-verlauf > summary::-webkit-details-marker { display: none; }
.karte-verlauf > summary .karte-block-titel { margin: 0; }
.karte-verlauf > summary:hover .karte-block-titel { color: var(--text); }
.karte-verlauf[open] > summary { margin-bottom: 0.6rem; }

/* Archivieren ist der stillste Weg von der Karte weg — ein Textlink, kein Knopf. */
.karte-aktionen { margin: var(--raum) 0 0.25rem; }

/* ---------- Seitenkopf mit Filter ---------- */

.seiten-kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1rem;
    margin-bottom: 0.75rem;
}
.seiten-kopf h1 { margin: 0; }
.filter {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
}
/* Die Leiste steht den ganzen Tag da — sie darf klein sein. */
.filter input, .filter select {
    font-size: 0.85rem;
    padding: 0.2rem 0.45rem;
}
/* Schmal halten: das Feld ist für ein Stichwort oder eine Kennung da, nicht für Sätze. */
.filter input[type="search"] { flex: 0 1 10rem; min-width: 0; }
.filter select { max-width: 10rem; }
/* Mit JavaScript wirkt die Leiste von selbst — der Knopf ist dann überflüssig. */
html.js .filter button[type="submit"] { display: none; }

/* Label und Priorität stehen offen nebeneinander, statt in einem Auswahlfeld zu warten.
   Eine Gruppe bleibt als Block zusammen und bricht als Ganzes um. */
.pillen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem;
}
/* Ein feiner Strich trennt die Gruppen — dicht beieinander liest man sonst Labels und
   Prioritäten als eine einzige Reihe. Der Strich läuft über die volle Zeilenhöhe. */
.filter .pillen {
    align-self: stretch;
    padding-left: 0.6rem;
    border-left: 1px solid var(--border);
}

/* Prioritätspille: gleiche Mechanik wie die Labelwahl (echtes Ankreuzfeld dahinter),
   nur ohne Nutzerfarbe — die Prioritätsfarben stehen fest. */
/* „Nur offene“ (.zustand-*) benutzt dieselbe Mechanik: Es ist wieder eine Pille mit einem
   echten Ankreuzfeld dahinter, nur fragt sie nach dem Zustand der Karte und nicht nach einer
   ihrer Eigenschaften — daher die eigene Klasse und das eigene Gesetzt-Aussehen. */
.prio-punkt,
.zustand-punkt { display: inline-flex; align-items: center; cursor: pointer; }
.prio-punkt input,
.zustand-punkt input,
.labelwahl-punkt input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
}
.prio-pille,
.zustand-pille {
    display: inline-block;
    padding: 0.02rem 0.45rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.72rem;
    white-space: nowrap;
    color: var(--muted);
}
.prio-punkt input:checked + .prio-pille,
.zustand-punkt input:checked + .zustand-pille {
    border-color: currentColor;
    background: color-mix(in srgb, currentColor 12%, transparent);
}
.zustand-punkt input:checked + .zustand-pille { color: var(--text); }
.prio-punkt input:checked + .prio-pille.prio-niedrig { color: var(--prio-niedrig); }
.prio-punkt input:checked + .prio-pille.prio-normal { color: var(--text); }
.prio-punkt input:checked + .prio-pille.prio-hoch { color: var(--prio-hoch); }
.prio-punkt input:checked + .prio-pille.prio-dringend { color: var(--prio-dringend); }
.prio-punkt input:focus-visible + .prio-pille,
.zustand-punkt input:focus-visible + .zustand-pille { outline: 2px solid var(--accent); outline-offset: -1px; }
.prio-punkt:hover .prio-pille,
.zustand-punkt:hover .zustand-pille { border-color: var(--accent); }

/* ---------- Marken, Pillen und kleine Zeichen ---------- */

/* Der Rest des früheren Bretts: Was hier steht, brauchen die Aufgabenliste, die
   Kartenansicht, der Kalender und das Archiv weiterhin. Alles Übrige (Brett, Spalten,
   Kacheln, Drag & Drop) ist am 2026-08-18 mit dem Brett gegangen. */

/* Nur für Vorlesewerkzeuge sichtbar. */
.nur-vorlesen {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Alle Marken sehen gleich aus und halten sich zurück: kleine, stille Schrift.
   Farbfläche bekommt nur die Frist — das ist das eine Signal, das auffallen soll. */
.marke {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0;
    font-size: 0.73rem;
    color: var(--muted);
    background: none;
    white-space: nowrap;
}
/* Wiederholung: der Kreispfeil sagt „kommt wieder", die Regel steht im Tooltip. */
.marke-wiederholung svg { width: 0.8rem; height: 0.8rem; }

/* Label als blasse Pille: die Farbe kommt als --label-farbe aus LabelStil, gemischt
   für die Fläche und in Richtung Textfarbe gezogen für die Schrift — sonst wären helle
   Labels auf hellem Grund nicht lesbar. Browser ohne color-mix behalten die volle
   Fläche aus den ersten beiden Zeilen. */
.label-pille {
    display: inline-block;
    padding: 0.02rem 0.45rem;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 0.72rem;
    white-space: nowrap;
    background: var(--label-farbe, var(--surface-2));
    color: var(--label-text, var(--text));
    background: color-mix(in srgb, var(--label-farbe, var(--surface-2)) 14%, transparent);
    border-color: color-mix(in srgb, var(--label-farbe, var(--border)) 30%, transparent);
    color: color-mix(in srgb, var(--label-farbe, var(--text)) 60%, var(--text));
}

.marke-frist { padding: 0.02rem 0.4rem; border-radius: 999px; }
.frist-offen { background: var(--frist-offen-bg); color: var(--frist-offen-text); }
.frist-bald { background: var(--frist-bald-bg); color: var(--frist-bald-text); }
.frist-heute { background: var(--frist-heute-bg); color: var(--frist-heute-text); font-weight: 600; }
.frist-ueberfaellig { background: var(--frist-ueberfaellig-bg); color: var(--frist-ueberfaellig-text); font-weight: 600; }

/* **Jede Kennung steht in fester Schrift und in Großbuchstaben** — hier zusammen, weil es
   dieselbe Aussage an sechs Orten ist: der Knopf zum Kopieren (Liste und Kartenseite), die Nummer
   im Archiv, die Marke an einer Notiz, eine Erwähnung im Text, ein Vorschlag der Kartensuche, der
   Eintrag im Protokoll. Stünde die Regel je Ort dabei, fehlte sie beim siebten.

   **Groß ist reine Darstellung** (Nutzerwunsch vom 2026-08-19): Gespeichert, adressiert und in
   Notizen geschrieben wird weiter klein (`a7f`) — `text-transform` färbt nur die Anzeige, keine
   Migration muss Nutzertext anfassen. Damit das nach außen stimmt, legt der Kopierknopf die
   Kennung groß in die Ablage (kennung.js) und alles, was Eingaben liest, normalisiert sie zurück
   (`Kennung::normalisiere`, `Kennung::ZEICHEN_EINGABE`).

   Nicht dabei: Kennungen im Fließtext einer Meldung („Karte #a7f angelegt.") — dort ist sie Teil
   eines Satzes, und ein Wechsel von Schrift und Größe mitten im Satz stört mehr, als er ordnet.

   Bei einer Erwähnung im Text trägt nur die **Kennung** die Regel, nicht der Kartentitel daneben
   im selben Link — sonst stünde auch er groß und in fester Schrift (`Markdown::erwaehnung` gibt
   ihr dafür eine eigene Hülle). */
.kennung-kopieren,
.karte-nummer,
.notiz-karte a,
.md .erwaehnung .erwaehnung-kennung,
.vorschlag-kennung,
code.kennung {
    font-family: var(--schrift-fest);
    /* Die feste Schrift läuft breiter als die Proportionalschrift daneben; etwas kleiner gesetzt
       bleibt die Kennung im Maß ihrer Umgebung (dasselbe Verhältnis wie bei `code`). */
    font-size: 0.9em;
    text-transform: uppercase;
}

/* Die Kennung in einer Zeile — im Archiv steht sie als Text, in der Liste als Knopf zum
   Kopieren (siehe .kennung-kopieren). */
.karte-nummer {
    flex: 0 0 auto;
    margin-left: auto;
    color: var(--muted);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}

/* ---------- Kartenansicht: Kopf mit Häkchen ---------- */

/* Das Häkchen „erledigt": ein blankes Symbol, das erst beim Überfahren oder mit dem
   Tastaturfokus hervortritt. Ohne Hover-Gerät bleibt es sichtbar. */
.karte-haken { display: flex; align-self: flex-start; margin-top: 0.15rem; }
.karte-haken button {
    display: grid;
    place-items: center;
    padding: 0;
    border: 0;
    background: none;
    color: var(--muted);
    opacity: 0.45;
    cursor: pointer;
    transition: opacity 0.15s ease, color 0.15s ease;
}
.karte-haken svg { width: 15px; height: 15px; display: block; }
.karte-haken button:focus-visible { opacity: 1; }
.karte-haken button:hover { color: var(--accent); opacity: 1; }
@media (hover: none) { .karte-haken button { opacity: 1; } }

/* Kartenansicht: links das Häkchen, daneben der Titel über die restliche Breite. */
.karte-kopf { display: flex; align-items: flex-start; gap: 0.5rem; }
.karte-kopf h1 { margin: 0; }
/* Das Kästchen ist so hoch wie die Titelzeile — kleiner sähe es aus, als wäre es an den
   Titel angeheftet, statt neben ihm zu stehen. */
.karte-haken.gross { margin-top: 0; }
.karte-haken.gross button { width: 2.15rem; height: 2.15rem; opacity: 0.6; }
.karte-haken.gross svg { width: 1.55rem; height: 1.55rem; }
.karte-haken.gross button:hover, .karte-haken.gross button:focus-visible { opacity: 1; }

/* ---------- Überlagertes Fenster ---------- */

/* Inhalt kommt aus der echten Seite (siehe fenster.js); ohne JavaScript bleibt das
   <dialog> leer und die Seiten öffnen wie gewohnt. */
.fenster {
    position: relative;
    width: min(60rem, 94vw);
    max-height: 88dvh;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
    overflow: hidden;
}
.fenster::backdrop {
    background: rgba(9, 11, 17, 0.5);
    backdrop-filter: blur(6px);
}

.fenster-inhalt {
    max-height: 88dvh;
    overflow-y: auto;
    padding: 1.1rem 1.25rem 1.35rem;
}
/* Im Fenster führt kein Weg "zurück zum Board" — dafür gibt es das Kreuz. */
.fenster-inhalt .brotkrumen { display: none; }
.fenster-inhalt > :first-child { margin-top: 0; }
/* Platz für das Schließen-Kreuz, damit die Überschrift nicht darunter läuft. */
.fenster-inhalt > h1, .fenster-inhalt > .karte-kopf, .fenster-inhalt > .seiten-kopf { padding-right: 2.6rem; }

.fenster-schliessen {
    position: absolute;
    top: 0.7rem;
    right: 0.7rem;
    z-index: 1;
}

/* Meldungen aus dem Fenster stehen im Fenster: oben rechts, links neben dem Kreuz. Sie
   schwebt über dem Inhalt, statt ihn nach unten zu schieben — und lässt sich nicht
   anklicken, damit sie dem Titel darunter nichts wegnimmt. Zu lang wird sie beschnitten
   (nowrap + ellipsis aus der Regel für die Leiste). */
.fenster-meldung {
    position: absolute;
    top: 0.7rem;
    right: 3.1rem;
    z-index: 1;
    max-width: calc(100% - 4.4rem);
    pointer-events: none;
}
.fenster-meldung:empty { display: none; }

/* ---------- Rückfrage ---------- */

/* Dieselbe Bauart wie das Fenster, nur schmal: Sie kann über einem offenen Fenster
   liegen (etwa beim Löschen aus dem Archiv) und gehört dann sichtbar darüber. */
.frage {
    width: min(26rem, 92vw);
    padding: 1.15rem 1.3rem 1.1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.frage::backdrop {
    background: rgba(9, 11, 17, 0.5);
    backdrop-filter: blur(6px);
}
.frage-text { margin: 0 0 1.1rem; }
.frage-knoepfe { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem; }

/* ---------- Markdown-Ausgabe ---------- */

.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md h2 { font-size: 1.15rem; margin: 1.2rem 0 0.5rem; }
.md h3 { font-size: 1.02rem; margin: 1.1rem 0 0.4rem; }
.md h4 { font-size: 0.95rem; margin: 1rem 0 0.4rem; }
.md p { margin: 0.6rem 0; overflow-wrap: anywhere; }
.md ul, .md ol { margin: 0.6rem 0; padding-left: 1.4rem; }
.md li { margin: 0.2rem 0; }
.md li.md-aufgabe { list-style: none; margin-left: -1.2rem; }
.md .md-erledigt { color: var(--muted); text-decoration: line-through; }
.md blockquote {
    margin: 0.7rem 0;
    padding: 0.2rem 0.9rem;
    border-left: 3px solid var(--border);
    color: var(--muted);
}
.md pre {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.7rem 0.9rem;
    overflow-x: auto;
}
.md pre code { background: none; border: none; padding: 0; }
.md a { color: var(--accent); }
.md .erwaehnung {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 0 0.3rem;
    text-decoration: none;
    font-size: 0.92em;
}
.md .erwaehnung:hover { border-color: var(--accent); }
.md hr { margin: 1rem 0; }

/* ---------- Listen (Spalten-/Label-Verwaltung, Protokoll, Kommentare) ---------- */

.zeilenliste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; }
.zeilenliste > li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}
.zeilenliste > li:last-child { border-bottom: none; }
.zeile-form { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.zeile-aktionen { display: flex; gap: 0.4rem; align-items: center; margin-left: auto; }

/* Labels: feste Spalten statt einer Flex-Reihe. In einer Reihe beginnt jedes Feld dort, wo
   der Text davor endet — bei unterschiedlich langen Namen fluchtet dann keine Zeile mit der
   nächsten. Das Formular ist selbst ein Raster mit derselben Aufteilung in jeder Zeile. */
.label-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.label-liste > li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 0.5rem 1rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--border);
}
.label-liste > li:last-child { border-bottom: none; }

/* Das Namensfeld bekommt eine Obergrenze und dehnt sich nicht über die freie Breite:
   Ein Labelname ist ein Wort, kein Satz. justify-content hält das Raster zusammen, damit
   der Speichern-Knopf am Feld bleibt statt am rechten Rand zu kleben. */
.label-form {
    display: grid;
    grid-template-columns: auto minmax(6rem, 15rem) auto;
    justify-content: start;
    align-items: center;
    gap: 0.5rem;
}
.label-form input[type="text"] { min-width: 0; }
/* Die Zahl steht rechtsbündig, damit die Ziffern untereinander stehen. */
.label-verwendung { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Archiv: Kennung, Karte, Herkunft, Aktionen — jede in ihrer Spur. */
.archiv-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.archiv-liste > li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: start;
    gap: 0.4rem 1rem;
    padding: 0.6rem 0;
    border-bottom: 1px solid var(--border);
}
.archiv-liste > li:last-child { border-bottom: none; }
.archiv-liste .karte-nummer { margin: 0; padding-top: 0.15rem; }

/* Titel und Labels teilen sich eine Spur: Die Labels sollen den Titel nicht verschieben. */
.archiv-karte { display: flex; flex-direction: column; gap: 0.25rem; min-width: 0; }
.archiv-karte > a { color: var(--text); overflow-wrap: anywhere; }
.archiv-labels { display: flex; flex-wrap: wrap; gap: 0.2rem; }

.archiv-herkunft { text-align: right; white-space: nowrap; line-height: 1.35; }
.archiv-aktionen { display: flex; flex-direction: column; align-items: flex-end; gap: 0.3rem; }

/* Kommentare tragen mit, sind aber nicht der Grund, warum man die Karte öffnet: eine
   feine Kante statt eines Balkens, etwas kleinerer Text als die Beschreibung. */
.kommentarliste { list-style: none; margin: 0 0 0.8rem; padding: 0; display: flex; flex-direction: column; gap: 0.7rem; }
.kommentarliste > li { border-left: 1px solid var(--border); padding-left: 0.7rem; }
.kommentarliste .md { font-size: 0.9rem; }
.kommentar-kopf {
    display: flex;
    gap: 0.75rem;
    align-items: baseline;
    margin: 0 0 0.2rem;
    font-size: 0.75rem;
    color: var(--muted);
}
/* Das Löschen erscheint erst, wenn man den Kommentar anfasst. */
.kommentar-kopf .knopf-link { opacity: 0; transition: opacity 0.15s ease; }
.kommentarliste > li:hover .kommentar-kopf .knopf-link,
.kommentar-kopf .knopf-link:focus-visible { opacity: 1; }
@media (hover: none) { .kommentar-kopf .knopf-link { opacity: 1; } }

/* Was eine Sicherung umfasst — eine stille Zeile aus Tabelle und Anzahl. */
.sicherung-inhalt { display: flex; flex-wrap: wrap; gap: 0.2rem 0.75rem; margin: 0.6rem 0 1rem; }

.verweisliste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; font-size: 0.85rem; }
.verweisliste a { color: var(--accent); }

/* ---------- Notizen (Bereich neben der Aufgabenliste) ---------- */

.notiz-bereich {
    display: flex;
    flex-direction: column;
    gap: var(--raum-innen);
    min-width: 0;
    min-height: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--raum-innen);
}

.bereich-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; }
.bereich-kopf h2 { margin: 0; font-size: 1rem; }

.notiz-bereich .verfassen > textarea { background: var(--surface); }

/* Ein Scrollbereich für Eingabefeld und Strom zusammen. Damit reserviert der Balken seinen
   Platz genau einmal, und beide sind auf das Pixel gleich breit — ein Ausgleich an zwei
   Stellen wäre eine Schätzung, die je nach Browser danebenliegt. */
.notiz-scroll {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: var(--raum-innen);
    overflow-y: auto;
    scrollbar-gutter: stable;
}
/* Das Feld bleibt beim Scrollen oben stehen — es ist der Grund, warum der Bereich offen ist. */
.notiz-scroll > .verfassen {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--surface-2);
}

/* Gescrollt wird der Bereich darum (.notiz-scroll), nicht die Liste selbst. */
.notiz-strom {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--raum-innen);
}

.notiz-eintrag {
    position: relative;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 7px;
    padding: 0.45rem 0.6rem;
}
/* Ziel eines Rückverweises von einer Karte (/?notiz=12#notiz-12). Eine Fläche statt einer
   Kontur: Der Strom hat seinen eigenen Scroll, an dessen Kanten eine Kontur angeschnitten
   wird — die Fläche bleibt auch dann erkennbar, wenn nur ein Teil des Eintrags zu sehen ist. */
.notiz-eintrag.notiz-fokus {
    background: var(--flash-bg);
    border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}
/* Die Zeit hält sich zurück, damit der Text der Notiz trägt. */
.notiz-zeit {
    margin: 0 0 0.2rem;
    padding-right: 1.4rem;
    color: var(--muted);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
/* Notiz und Kartentitel stehen nebeneinander auf demselben Bildschirm — sie setzen gleich. */
.notiz-eintrag .md { font-size: 0.9rem; }

/* Bearbeitet wird durch einen Klick in den Text; die Anzeige zeigt das beim Überfahren.
   Ohne JavaScript stehen Anzeige und Eingabefeld untereinander (siehe html.js-Regeln). */
html.js .notiz-eintrag .feld-anzeige { cursor: text; }
html.js .notiz-eintrag .feld-anzeige:hover { background: var(--surface-2); }

/* Löschen still in der Ecke: blass, bis der Eintrag überfahren wird oder der Knopf den
   Tastaturfokus hat. Ohne Hover-Gerät (Touch) bleibt es sichtbar — sonst käme man dort
   nie heran. */
.notiz-weg {
    position: absolute;
    top: 0.25rem;
    right: 0.3rem;
    opacity: 0;
    transition: opacity 0.15s ease;
}
.notiz-eintrag:hover .notiz-weg,
.notiz-weg:focus-within { opacity: 1; }
@media (hover: none) { .notiz-weg { opacity: 1; } }

/* Beim Bearbeiten soll die Notiz so aussehen wie danach — gleiche Größe wie die Anzeige. */
.notiz-form { gap: 0.4rem; margin: 0 0 0.3rem; }
.notiz-form textarea { font-size: 0.9rem; width: 100%; }

/* Das Verknüpfen-Feld ist still, bis man es braucht: Es erscheint mit dem Editor **und** beim
   Überfahren des Eintrags — dasselbe Muster wie das Löschsymbol darüber. Nur am Editor zu
   hängen war zu wenig: Wer eine Karte anhängen wollte, musste erst in den Text klicken, und der
   Klick vom Textfeld in dieses Feld ist genau der Weg, der bisher nicht ankam (siehe feld.js,
   focusout). Ohne JavaScript gibt es keinen Bearbeiten-Zustand — dann steht es immer da. */
html.js .notiz-eintrag .feld:not(.bearbeitet) .notiz-verknuepfen { display: none; }
html.js .notiz-eintrag:hover .feld .notiz-verknuepfen,
html.js .notiz-eintrag .feld .notiz-verknuepfen:focus-within { display: flex; }
/* Ohne Hover-Gerät (Touch) käme man sonst nie heran. */
@media (hover: none) {
    html.js .notiz-eintrag .feld:not(.bearbeitet) .notiz-verknuepfen { display: flex; }
}
/* Die Karten an einer Notiz: kleine Marken unter dem Text. Eine Erwähnung aus dem Text
   steht nur da; eine von Hand gesetzte Verknüpfung trägt zusätzlich ihr × zum Lösen. */
.notiz-karten {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin: 0.3rem 0 0;
}
.notiz-karte {
    display: inline-flex;
    align-items: center;
    gap: 0.1rem;
    padding: 0.02rem 0.4rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-size: 0.72rem;
}
.notiz-karte a { color: var(--muted); text-decoration: none; }
.notiz-karte a:hover { color: var(--accent); }
/* Von Hand gesetzt: etwas fester umrissen als die abgeleitete Erwähnung. */
.notiz-karte-manuell { border-color: var(--muted); }
.notiz-karte-weg {
    display: inline-flex;
    align-items: center;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    color: var(--muted);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 400;
    line-height: 1;
    cursor: pointer;
}
.notiz-karte-weg:hover, .notiz-karte-weg:focus-visible { color: var(--gefahr); }

/* Karte anhängen, ohne sie im Text zu erwähnen. */
.notiz-verknuepfen { display: flex; gap: 0.35rem; align-items: center; margin-top: 0.4rem; }
.notiz-verknuepfen input { width: 100%; min-width: 0; font-size: 0.82rem; padding: 0.2rem 0.45rem; }

/* Die Vorschlagsliste legt sich über die Notizen, statt den Strom auseinanderzuschieben.
   Sie hängt am Fenster, nicht am Feld: Der Notizstrom scrollt für sich, und in ihm verankert
   wäre die Liste an seiner unteren Kante abgeschnitten. Ort und Breite rechnet kartensuche.js
   — hier steht nur, was gleich bleibt. Ohne JavaScript wird die Liste nie gezeigt. */
.kartensuche { flex: 1 1 auto; min-width: 0; }
.vorschlaege {
    position: fixed;
    z-index: 40;
    max-height: 14rem;
    overflow-y: auto;
    margin: 0;
    padding: 0.2rem;
    list-style: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 7px;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.16);
}
.vorschlag {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    width: 100%;
    padding: 0.25rem 0.4rem;
    border: 0;
    border-radius: 5px;
    background: none;
    color: var(--text);
    font: inherit;
    font-size: 0.8rem;
    text-align: left;
    cursor: pointer;
}
.vorschlag:hover, .vorschlag:focus-visible { background: var(--surface-2); }
.vorschlag-kennung { color: var(--muted); font-size: 0.72rem; flex: 0 0 auto; }
.vorschlag-titel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Löschen und Verknüpfen sind blanke Symbole ohne Kästchen — sie sollen nicht mehr
   wiegen als die Notiz selbst. */
.icon-still {
    display: inline-grid;
    place-items: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: 0;
    border-radius: 5px;
    background: none;
    color: var(--muted);
    opacity: 0.75;
    cursor: pointer;
    transition: opacity 0.15s ease, color 0.15s ease;
}
.icon-still svg { width: 1rem; height: 1rem; display: block; }
.icon-still:hover,
.icon-still:focus-visible { color: var(--accent); opacity: 1; }
.icon-still-gefahr:hover,
.icon-still-gefahr:focus-visible { color: var(--gefahr); }

.notiz-leer, .notiz-mehr { margin: 0.2rem 0 0; }
.notiz-mehr { color: var(--muted); }

.protokoll { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.88rem; }
.protokoll > li { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: baseline; }
.protokoll time { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.protokoll-art {
    background: var(--surface-2);
    border-radius: 5px;
    padding: 0 0.35rem;
    font-size: 0.8rem;
    color: var(--muted);
}
.protokoll-gross { font-size: 0.92rem; }
.protokoll-karte a { color: var(--text); }

/* ---------- Anhänge ---------- */

/* Drei Spuren je Zeile: Vorschau, Name mit Angaben, Löschen. Wie die Archivliste ein Raster
   und keine Flex-Reihe — dort verschob jeder längere Name alles Folgende. */
.anhangliste { list-style: none; margin: 0 0 var(--raum-innen); padding: 0; }
.anhangliste > li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.4rem 0.35rem;
    border-top: 1px solid var(--border);
    border-radius: 7px;
}
.anhangliste > li:first-child { border-top: 0; }
.anhangliste > li:hover { background: var(--surface-2); }

/* Die Vorschau ist ein festes Quadrat: Bilder werden beschnitten, statt die Zeile zu dehnen. */
.anhang-vorschau {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    overflow: hidden;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface-2);
    color: var(--muted);
}
.anhang-vorschau img { width: 100%; height: 100%; object-fit: cover; display: block; }
.anhang-vorschau:hover { border-color: var(--accent); }
/* Die Zeile hebt sich beim Überfahren mit --surface-2 heraus — dieselbe Fläche, die das
   Vorschauquadrat trägt. Es bekäme sonst keine Kante mehr. */
.anhangliste > li:hover .anhang-vorschau { background: var(--surface); }
.anhang-symbol svg { width: 1.4rem; height: 1.4rem; }

.anhang-name { display: flex; flex-direction: column; gap: 0.05rem; min-width: 0; }
.anhang-name > a { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.anhang-angaben { color: var(--muted); font-size: 0.72rem; font-variant-numeric: tabular-nums; }

/* Löschen still in der Zeile, wie am Notizeintrag: blass, bis die Zeile überfahren wird
   oder der Knopf den Tastaturfokus hat. Ohne Hover-Gerät bleibt es sichtbar. */
.anhang-weg { margin: 0; opacity: 0; transition: opacity 0.15s ease; }
.anhangliste > li:hover .anhang-weg,
.anhang-weg:focus-within { opacity: 1; }
@media (hover: none) { .anhang-weg { opacity: 1; } }

/* Hochladen in zwei Zeilen: oben Auswahl und Knopf, darunter die Schranken. In einer
   Zeile drängte die lange Endungsliste den Knopf aus dem Blick. */
.anhang-neu {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.4rem 0.6rem;
}
.anhang-neu input[type="file"] { min-width: 0; max-width: 100%; font-size: 0.82rem; }
.anhang-schranken {
    grid-column: 1 / -1;
    margin: 0;
    color: var(--muted);
    font-size: 0.72rem;
}

/* ---------- Aufgabenliste ---------- */

/* Die Liste hat am 2026-08-18 das Brett ersetzt: alles, was dort über die Kacheln verteilt
   war, steht hier in einer Zeile, und die Spalte einer Aufgabe ist eine Spalte der Tabelle
   unter anderen. Der Rahmen scrollt waagerecht für sich, damit eine schmale Anzeige nicht
   die ganze Seite verschiebt — und senkrecht, damit der Kopf stehen bleibt und die Leiste
   oben nicht weggescrollt wird. */
.liste-rahmen {
    flex: 1 1 auto;
    min-height: 0;
    /* Der Rahmen ist so breit wie die Tabelle, nicht wie der Bereich: Sonst zieht er einen
       Kasten um leere Fläche. Breiter als der Bereich wird er nie — dann scrollt er. */
    align-self: flex-start;
    max-width: 100%;
    overflow: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

/* **Feste Spaltenbreiten.** Ohne sie rechnet der Browser die Breiten aus dem Inhalt: Eine
   gefilterte Ansicht hat kürzere Titel und weniger Labels als die ungefilterte, und die ganze
   Tabelle springt bei jedem Filterwechsel. `table-layout: fixed` nimmt die Breiten aus dem
   Kopf; zu langer Inhalt bricht um oder wird beschnitten, statt seine Spalte zu dehnen.
   Die Titelspalte hat keine Breite — sie bekommt, was übrig bleibt.
   `min-width` hält die Spalten lesbar: Ist der Bereich schmaler, scrollt der Rahmen
   waagerecht, statt alles zusammenzuquetschen. */
/* `width: auto` statt `100%`: Die Tabelle ist so breit wie die Summe ihrer Spalten und wird
   nicht auf die Breite des Bereichs gezogen. Vorher bekam die Titelspalte allen Platz, der
   übrig war — auf einem großen Bildschirm wurde sie absurd breit, und die Tabelle sah bei
   jeder Fenstergröße anders aus. Jetzt hat jede Spalte ihr Maß, auch der Titel; bleibt Platz,
   bleibt er rechts frei, und reicht er nicht, scrollt der Rahmen. */
.liste {
    width: auto;
    table-layout: fixed;
    border-collapse: collapse;
    font-size: var(--liste-schrift);
}

/* Die Breiten stehen auf den <col> der Tabelle und nicht auf ihren Zellen: Bei
   `table-layout: fixed` liest der Browser sie aus der ersten Zeile — hing die Breite an der
   Klasse der Kopfzelle, war sie weg, sobald die Kopfzelle anders heißt als die Spalte. Genau
   das war zwei Runden lang der Fall (Kopf „…-spalte", Regel „…-kategorie").

   Die Zahlen selbst stehen als Variablen in :root — die Zeile zum Anlegen richtet ihre Felder
   an denselben Maßen aus (siehe .liste-neu). Die schmalen Spalten bekommen genau, was ihr
   Inhalt braucht; er ist dort immer ähnlich lang: ein Häkchen, „#a7f", eine Pille
   („Dringend" ist die längste), eine Fristangabe („3 Tage überfällig" ist die längste). */
.liste-col-haken { width: var(--liste-haken); }
.liste-col-kennung { width: var(--liste-kennung); }
.liste-col-kategorie { width: var(--liste-kategorie); }
.liste-col-prioritaet { width: var(--liste-prioritaet); }
.liste-col-frist { width: var(--liste-frist); }

/* Titel und Labels sind die beiden, deren Inhalt wirklich schwankt — sie bekommen den
   großzügigen Teil, aber auch sie ein festes Maß. Zusammen mit den schmalen Spalten ergibt
   das knapp 67 rem: Auf einem üblichen Fenster passt das ohne Scrollbalken, auf einem großen
   bleibt rechts Luft. Ein längerer Titel bricht um, statt seine Spalte zu dehnen.

   Gemessen ist an den *Köpfen*, nicht am Inhalt: „KENNUNG" braucht mehr Platz als „#a7f",
   „PRIORITÄT" mehr als die Pille darunter. Der Kopf bricht nicht um (nowrap), also gibt er
   das Mindestmaß vor. */
.liste-col-titel { width: var(--liste-titel); }
.liste-col-labels { width: var(--liste-labels); }

/* Der Kopf bleibt beim Scrollen stehen — ohne ihn weiß man in einer langen Liste nicht
   mehr, welche Spalte man liest. */
.liste thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    padding: 0.4rem 0.6rem;
    text-align: left;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
}
.liste thead a { color: inherit; text-decoration: none; }
.liste thead a:hover { color: var(--accent); }
.liste-pfeil { color: var(--accent); }
.liste thead th[aria-sort] { color: var(--text); }

.liste tbody td { padding: 0.35rem 0.6rem; border-top: 1px solid var(--border); vertical-align: top; }
/* Der Hover färbt nur, wo etwas zu tun ist: die offenen Aufgaben. Eine erledigte Zeile ist
   abgeschlossen (nichts darin lässt sich mehr bearbeiten), und die Grenzzeile „Erledigt" ist eine
   Beschriftung, keine Aufgabe — ein Hinweis auf Bedienbarkeit wäre dort ein falsches Versprechen.
   Das Häkchen bleibt davon unberührt: Es ist der Weg zurück und zeigt seinen eigenen Hover. */
.liste tbody tr:not(.liste-erledigt):not(.liste-grenze):hover { background: var(--surface-2); }

/* Der Titel darf umbrechen — die Zeile wird dann höher, aber es geht nichts verloren.
   Ein sehr langes Wort (eine URL) bricht mitten durch, statt die Spalte zu sprengen. */
.liste-spalte-titel { overflow-wrap: anywhere; }
.liste-spalte-kennung,
.liste-spalte-prioritaet,
.liste-spalte-frist { white-space: nowrap; }
/* Labels brechen in mehrere Zeilen, statt ihre Spalte zu dehnen. */
.liste-spalte-labels > .label-pille { margin: 0.05rem 0.15rem 0.05rem 0; }

.liste-titel { color: var(--text); text-decoration: none; font-weight: 500; }
.liste-titel:hover { text-decoration: underline; }

.liste-spalte-kennung { color: var(--muted); font-size: 0.78rem; font-variant-numeric: tabular-nums; }
/* Ein langer Kategoriename wird beschnitten, nicht umgebrochen: Er ist eine Einordnung,
   kein Text — und im Tooltip steht er ganz. */
.liste-spalte-kategorie {
    color: var(--muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Die Priorität steht immer da, auch „Normal" — eine leere Zelle sah aus wie ein fehlender
   Wert. Farbe bekommen nur Hoch und Dringend; Normal und Niedrig bleiben still, sonst wäre
   jede Zeile bunt und keine Priorität mehr auffällig. */
.liste .prio-pille.prio-hoch,
.liste .prio-pille.prio-dringend {
    border-color: currentColor;
    background: color-mix(in srgb, currentColor 10%, transparent);
}
.liste .prio-pille.prio-hoch { color: var(--prio-hoch); }
.liste .prio-pille.prio-dringend { color: var(--prio-dringend); }

/* Erledigt: gedämpft und durchgestrichen, aber sichtbar.

   `grayscale` nimmt den Zeilen ihre Farben — die Labelpille und eine Priorität „Dringend"
   leuchteten sonst unter der Grenze weiter, obwohl an einer fertigen Aufgabe nichts mehr dringend
   ist. Farbe heißt in dieser Liste „beachte mich"; das gilt nur oberhalb der Grenze. Zusammen mit
   der geringeren Deckkraft ist das die Rücknahme, die vorher der graue Grund leisten sollte. */
.liste-erledigt .liste-titel { text-decoration: line-through; text-decoration-thickness: 1px; }
.liste-erledigt td { opacity: 0.55; filter: grayscale(1); }
/* Das Häkchen bleibt voll und farbig: Es ist der Weg zurück, wenn etwas zu früh abgehakt war. */
.liste-erledigt .liste-spalte-haken { opacity: 1; filter: none; }

/* Der Erledigt-Bereich am Fuß der Tabelle: eine beschriftete Grenze, dieselbe Aussage wie
   früher die Linie „Erledigt" in einer Brettspalte, nur jetzt für die ganze Liste. Es bleibt
   dieselbe Tabelle, damit die Spalten auf einer Linie stehen.

   **Kein eigener Grund mehr.** Er war `--surface-2` — genau die Farbe des Tabellenkopfs, und
   damit sah der halbe Fuß der Tabelle aus wie ein zweiter Kopf. Der Bereich braucht keine
   Fläche: Getrennt wird jetzt durch Luft über der Grenze und die Beschriftung, und die Zeilen
   darunter sagen selbst, dass sie fertig sind (grau, blass, durchgestrichen). `--surface-2`
   bleibt dem Kopf allein — eine Farbe, eine Bedeutung. */
/* `.liste tbody tr.liste-grenze > td` und nicht `.liste-grenze > td`: Padding und Rahmen stellt
   für jede Zelle schon `.liste tbody td` (eine Klasse, zwei Elemente). Der kürzere Selektor hat
   ein Element weniger und verliert damit — gleich, wie weit unten er steht. Aufgefallen ist das
   erst jetzt: Solange hier dieselben Werte standen wie dort, machte es keinen Unterschied. */
.liste tbody tr.liste-grenze > td {
    /* Luft statt Fläche: Der Abstand über der Grenze ist es, der den Bereich abtrennt. Die
       Zeilenlinie muss dafür weg (jedes td in der Tabelle bringt eine mit) — sonst stünde die
       Beschriftung zwischen zwei Linien, und die Luft darüber wäre eingeklammert statt offen. */
    border-top: 0;
    /* Der Abstand nach oben ist bewusst groß: Er ist das Einzige, was den erledigten Teil vom
       offenen trennt (der graue Grund ist am 2026-08-19 gefallen, er sah wie ein zweiter
       Tabellenkopf aus). Nach unten dagegen dicht — die Beschriftung gehört zu dem, was folgt. */
    padding: 2.2rem 0.6rem 0.3rem;
    color: var(--muted);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
/* Die Linie zieht die Grenze über die ganze Breite — schmal, aber ohne Lücke: Sie sitzt unter
   der Beschriftung, nicht über ihr, damit die Luft darüber zum offenen Teil gehört. */
.liste tbody .liste-grenze + tr > td { border-top-color: var(--muted); }
.liste-grenze-zahl { font-weight: 400; letter-spacing: 0; }
.liste-leer { color: var(--muted); font-size: 0.85rem; }

/* ---------- Felder in der Zeile: Labels, Kategorie, Priorität, Frist ändern ----------

   Jede dieser Zellen ist ein `<details>`. Zu sehen ist die Anzeige (Pille, Name, Fristmarke);
   ein Klick klappt die Steuerung darunter auf, in der Zelle. Das Aufklappen macht der Browser —
   ohne JavaScript wählt man und drückt Speichern, mit JavaScript speichert schon die Auswahl.

   Warum in der Zelle und nicht darüber: Der Listenrahmen scrollt für sich und schnitte ein
   überlagerndes Menü ab (dieselbe Falle, die `kartensuche.js` mit `position: fixed` umgeht). So
   wächst nur die Zeile, und das nur, solange etwas offen ist. */
.liste-feld { min-width: 0; }

/* Die Anzeige zeigt beim Überfahren die Kante eines Feldes: „hier lässt sich etwas ändern". Ein
   Grund wäre hier blind — die Zeile färbt sich beim Überfahren selbst (tr:hover), und zwei Gründe
   übereinander unterscheidet niemand. Der Rahmen liegt in negativen Rändern, damit die Anzeige an
   derselben Stelle steht wie vorher der nackte Text. */
.liste-feld > summary {
    display: block;
    margin: -0.1rem -0.35rem;
    padding: 0.1rem 0.35rem;
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
    list-style: none;
}
.liste-feld > summary::-webkit-details-marker { display: none; }
.liste-feld > summary:hover,
.liste-feld[open] > summary { border-color: var(--border); }
.liste-feld > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* Noch nichts gesetzt: Die Zelle wäre leer und damit unauffindbar — ein Hinweis sagt, dass hier
   etwas zu holen ist. Er ist ein Platzhalter wie der in einem Eingabefeld und trägt dieselbe,
   blasseste Farbe: Was dort steht, ist kein Wert der Aufgabe. */
.liste-feld-leer { color: var(--platzhalter); font-size: 0.78rem; }

/* Die Steuerung sitzt in einer Tabellenspalte und hat deshalb nur deren Breite. Kleineres Maß
   als sonst im Blatt: Ein Datumsfeld in voller Größe passt nicht in 7,5 rem. */
.liste-feld-form {
    display: block;
    margin-top: 0.3rem;
}
.liste-feld-form select,
.liste-feld-form input[type="date"] {
    width: 100%;
    min-width: 0;
    font-size: 0.78rem;
    padding: 0.12rem 0.25rem;
}
.liste-feld-form .labelwahl { gap: 0; }
.liste-feld-form .labelwahl-punkt { margin: 0.1rem 0.2rem 0.1rem 0; }
/* Der Speichern-Knopf der drei Einzelwert-Felder ist nur für den Fall ohne JavaScript da (html.js
   blendet ihn über .feld-form aus) — er soll die Zelle nicht sprengen. */
.liste-feld-form > button[type="submit"] { margin-top: 0.25rem; font-size: 0.75rem; }
/* Die Labelwahl behält ihren Knopf **immer**: Sie ist eine Mehrfachauswahl und braucht einen
   Abschluss — sonst müsste man nach jedem Haken neu aufklappen. */
.liste-feld-fertig { display: inline-block; }

.liste-haken { display: flex; margin: 0; }
.liste-haken button {
    display: grid;
    place-items: center;
    width: 1.4rem;
    height: 1.4rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--muted);
    opacity: 0.6;
    cursor: pointer;
}
.liste-haken svg { width: 1.05rem; height: 1.05rem; display: block; }
.liste tbody tr:hover .liste-haken button,
.liste-haken button:focus-visible { opacity: 1; }
.liste-haken button:hover { color: var(--accent); opacity: 1; }
@media (hover: none) { .liste-haken button { opacity: 1; } }

/* Anlegen sitzt oben, wie das Feld im Notizstrom daneben: Beide Bereiche fangen gleich an,
   und frisch Erfasstes soll im Blick sein.

   Die Fläche liest sich als **Eingabezeile der Tabelle**: Ihre Felder stehen genau über den
   Spalten, zu denen sie gehören — der Titel über TITEL, die Kategorie über KATEGORIE. Das
   Raster kommt aus denselben Variablen wie die <col> der Tabelle (:root), damit die beiden
   nicht auseinanderlaufen.

   Sie ist so breit wie die **Tabelle** — dieselbe linke und dieselbe rechte Kante. Am Bereich
   ausrichten wäre falsch: Der ist auf einem großen Bildschirm breiter als die Tabelle, und zwei
   verschiedene rechte Kanten waren der Grund, hier überhaupt anzufassen. Eine Spalte früher zu
   enden (Stand 2026-08-19, an der Grenze zu „Frist") war dem Nutzer zu wenig: Die Zeile gehört
   zur Tabelle, also nimmt sie deren Breite.

   Vier Spuren aus sieben Spalten: Der Titel nimmt Titel + Labels + Kennung mit, weil Labels
   und Kennung beim Anlegen nichts zu sagen haben (Labels vergibt die Kartenseite, die Kennung
   der Server) — stünde dort nichts, klaffte ein Loch in der Zeile. Der Knopf schließt über
   Priorität + Frist rechts ab. Jedes Feld nennt seine Spur selbst: Ohne Kategorien fehlt das
   Auswahlfeld, und der Knopf soll dann nicht eine Spur nach links rutschen. */
.liste-neu {
    display: grid;
    grid-template-columns:
        var(--liste-haken)
        minmax(0, calc(var(--liste-titel) + var(--liste-labels) + var(--liste-kennung)))
        minmax(0, var(--liste-kategorie))
        minmax(0, calc(var(--liste-prioritaet) + var(--liste-frist)));
    align-items: center;
    /* Kein Innenabstand links und rechts: Er würde jedes Feld um sein Maß aus der Spur
       schieben, und die Bündigkeit mit den Spalten ist der ganze Punkt dieser Zeile. Den
       Abstand zur Kante halten die Felder selbst, mit dem Maß einer Tabellenzelle (0.6rem). */
    padding: 0.2rem 0;
    width: fit-content;
    max-width: 100%;
    flex: 0 0 auto;
    align-self: flex-start;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
/* Die Fläche zeigt, dass in ihr gearbeitet wird — den Fokus selbst zeigt weiterhin der Ring
   am Feld (siehe :focus-visible), Farbe allein wäre kein Hinweis. */
.liste-neu:focus-within { border-color: var(--accent); }

/* Das stille „+" steht in der Spur des Häkchens: dort, wo die Zeile später ihr Kästchen trägt.
   Es ist ein Zeichen, kein Bedienteil — angelegt wird über den Knopf rechts. */
.liste-neu-plus {
    grid-column: 1;
    justify-self: center;
    color: var(--muted);
    font-size: 1.05rem;
    line-height: 1;
}

/* Titel und Kategorie sind randlos: Der Rahmen der Fläche ist schon da, ein zweiter darin
   wirkte verschachtelt. Ihr Innenabstand ist der einer Tabellenzelle, damit ihr Text auf
   derselben senkrechten Linie beginnt wie der Text der Spalte darunter.

   Der Grund ist nicht `none`, sondern die Farbe der Fläche: Ein Auswahlfeld ohne Grund erbt
   für seine aufgeklappte Liste die Systemfarben, und dunkle Schrift auf hellem Grund (oder
   umgekehrt) trifft dann nicht mehr das Blatt. */
.liste-neu > input[type="text"],
.liste-neu-kategorie {
    min-width: 0;
    padding: 0.3rem 0.6rem;
    /* Dieselbe Schrift wie die Zeilen darunter: Was hier getippt wird, steht danach in der
       Tabelle — in einer anderen Größe zu schreiben als zu lesen liest sich wie ein anderes
       Blatt. */
    font-size: var(--liste-schrift);
    background: var(--surface);
    border: 0;
    border-radius: 5px;
}
.liste-neu > input[type="text"] { grid-column: 2; }

/* Die Kategorie tritt hinter den Titel zurück: kleinere, blasse Schrift. Sie trägt nur den
   Pfeil als Hinweis, dass sie zu bedienen ist — deshalb bekommt sie unter dem Zeiger einen
   Grund. Was sie bedeutet, sagt die Spalte darunter; ihr Name steht für Vorlesewerkzeuge im
   aria-label. */
.liste-neu-kategorie {
    grid-column: 3;
    color: var(--muted);
}
.liste-neu-kategorie:hover { background: var(--surface-2); color: var(--text); }

/* Der Knopf schließt die Fläche rechts ab, mit demselben Abstand zur Kante wie die Felder
   links zu ihrer.

   Er ist zurückgenommen (`.btn-still` im Markup, dazu normales Schriftgewicht): In dieser Zeile
   ist das Titelfeld das Ziel des Blicks, nicht der Knopf — angelegt wird ohnehin meist mit der
   Eingabetaste. Ein voll gefärbter Knopf war das Lauteste auf dem ganzen Bildschirm.

   `align-self: center` muss dastehen: `.btn` bringt `align-self: start` mit (es steht dort für
   Knöpfe in Formularspalten, die sich nicht auf Feldbreite ziehen sollen) und schlägt damit das
   `align-items: center` der Fläche — der Knopf hing oben in der Zeile. */
.liste-neu > button[type="submit"] {
    grid-column: 4;
    justify-self: end;
    align-self: center;
    margin-right: 0.6rem;
    font-weight: 500;
}

/* ---------- Kalender (Fristen als Monatsblatt) ---------- */

.kalender-kopf {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: var(--raum-innen);
}
.kalender-kopf h1 { margin: 0; }
.kalender-nav { display: flex; gap: 0.3rem; margin-left: auto; }

.kalender-rueckstand { margin-bottom: var(--raum); }
.kalender-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }

/* Ein Gitter aus ganzen Wochen. Die Zeilen wachsen mit ihrem Inhalt, haben aber ein Mindest-
   maß — ein Kalender, in dem eine leere Woche zur Linie zusammenfällt, ist keiner mehr. */
.kalender { display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.kalender-wochentage,
.kalender-woche { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px; }
.kalender-wochentage {
    background: var(--surface-2);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--muted);
}
.kalender-wochentage > span { padding: 0.3rem 0.45rem; background: var(--surface-2); }

.kalender-tag {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-height: 5.5rem;
    padding: 0.3rem;
    background: var(--surface);
}
.kalender-tag-wochenende { background: var(--surface-2); }
/* Die Randtage der Nachbarmonate stehen mit, treten aber zurück. */
.kalender-tag-fremd { opacity: 0.5; }
.kalender-tag-heute { box-shadow: inset 0 0 0 2px var(--accent); }
.kalender-tag-zahl { margin: 0; font-size: 0.72rem; color: var(--muted); font-variant-numeric: tabular-nums; }
/* Im Gitter steht nur die Zahl — welcher Wochentag das ist, sagt die Spalte. Fällt das
   Gitter auf schmalen Bildschirmen zur Tagesliste zusammen, tauschen die beiden. */
.kalender-tag-lang { display: none; }
.kalender-tag-heute .kalender-tag-zahl { color: var(--accent); font-weight: 600; }

/* Ein Eintrag ist ein Link auf seine Karte: knapp, einzeilig, mit Labelpunkten davor.
   Der ganze Titel steht im title-Attribut — in einer Tagesspalte ist kein Platz dafür. */
.kalender-eintrag {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.1rem 0.3rem;
    border: 1px solid var(--border);
    border-radius: 5px;
    background: var(--surface-2);
    color: var(--text);
    font-size: 0.74rem;
    line-height: 1.35;
    text-decoration: none;
}
.kalender-eintrag:hover { border-color: var(--accent); }
.kalender-eintrag-titel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kalender-eintrag-frist { flex: 0 0 auto; font-variant-numeric: tabular-nums; opacity: 0.8; }
/* Erledigt: dieselbe Aussage wie in der Aufgabenliste — lesbar, aber zurückgetreten. */
.kalender-eintrag-erledigt { opacity: 0.55; text-decoration: line-through; }
/* Labelfarbe als Punkt: In dieser Zeile ist für eine Pille kein Platz. */
.kalender-punkt {
    flex: 0 0 auto;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--label-farbe, var(--muted));
}

/* ---------- Schmale Bildschirme ---------- */

/* Nebeneinander lohnt sich nur ab einer gewissen Breite. Darunter fällt der
   Arbeitsbildschirm auf normalen Seitenfluss zurück: die Aufgabenliste, darunter die
   Notizen — gescrollt wird dann wieder die Seite, nicht die einzelnen Bereiche. */
@media (max-width: 900px) {
    body.vollhoehe { height: auto; display: block; overflow: visible; }
    body.vollhoehe .container { display: block; min-height: 0; }
    /* Ohne Flex-Container gibt es keinen gap mehr — den Abstand macht wieder die Leiste. */
    body.vollhoehe .appbar { margin-bottom: var(--raum); }
    body.vollhoehe .flash { margin-bottom: 0.75rem; }
    .arbeitsflaeche { display: block; }
    .liste-rahmen { overflow-x: auto; overflow-y: visible; }
    .notiz-bereich { margin-top: var(--raum); }
    /* Auf dem Telefon scrollt wieder die Seite, nicht der Notizbereich für sich. */
    .notiz-scroll { overflow-y: visible; scrollbar-gutter: auto; }
    .notiz-scroll > .verfassen { position: static; }
}

/* Schmal: Die Raster fallen auf einzelne Zeilen zurück, sonst wird jede Spur zu eng. */
@media (max-width: 700px) {
    .label-liste > li,
    .archiv-liste > li { grid-template-columns: minmax(0, 1fr); }
    .label-verwendung,
    .archiv-herkunft { text-align: left; }
    .archiv-aktionen { flex-direction: row; align-items: center; }
    .archiv-liste .karte-nummer { padding-top: 0; }

    /* Sieben Spalten sind auf dem Telefon nicht zu lesen. Der Kalender wird deshalb zu einer
       Liste der Tage, an denen etwas fällig ist — leere Tage entfallen; ihre Zahl ohne Inhalt
       würde die Liste füllen, ohne etwas zu sagen. Das Datum trägt dann seinen Wochentag. */
    .kalender-wochentage { display: none; }
    .kalender-woche { display: contents; }
    .kalender-tag { min-height: 0; }
    .kalender-tag:not(.kalender-tag-voll) { display: none; }
    .kalender-tag-fremd { opacity: 1; }
    .kalender-tag-kurz { display: none; }
    .kalender-tag-lang { display: inline; }
}

@media (max-width: 700px) {
    /* Unter der Tabellenbreite hat das Spaltenraster nichts mehr, worauf es sich ausrichten
       könnte — die Tabelle scrollt dort für sich. Die Zeile fällt deshalb auf einen Fluss
       zurück: der Titel über die ganze Breite, Kategorie und Knopf darunter. */
    .liste-neu {
        grid-template-columns: var(--liste-haken) minmax(0, 1fr) auto;
        row-gap: 0.25rem;
    }
    .liste-neu-plus { grid-area: 1 / 1; }
    .liste-neu > input[type="text"] { grid-area: 1 / 2 / 2 / 4; }
    .liste-neu-kategorie { grid-area: 2 / 2; justify-self: start; }
    .liste-neu > button[type="submit"] { grid-area: 2 / 3; }
}

@media (max-width: 640px) {
    /* Auf dem Telefon ist Platz das knappere Gut als Ruhe: das Maß schrumpft, und alles,
       was daran hängt (Seitenrand, Bereichsabstand, Spaltenabstand), zieht mit. */
    :root { --raum: 0.9rem; }
    .filter { margin-left: 0; }
    .filter input[type="search"], .filter select { flex: 1 1 100%; max-width: none; }
}
