/* =============================================================================
 * Komponenten. Zwei Behälter, mehr gibt es hier nicht: das Feld gruppiert, die
 * Zeile listet (ADR-0024, design/brain-shell-preview.html, „Bausteine").
 *
 * Lädt nach shell.css und vor dem Inline-Blatt in views.tsx. Farbliterale sind
 * rot (Guard A), Maße kommen aus der Skala in tokens.css.
 * ========================================================================== */

/* =============================================================================
 * Feld — gruppiert Zeilen oder Inhalt.
 * ========================================================================== */

.panel {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-10);
  /* Damit die Haarlinie der letzten Zeile nicht über die Rundung hinausläuft. */
  overflow: hidden;
}

.panel + .panel {
  margin-top: var(--space-12);
}

/* Ein Feld, das auffallen soll — heute die Spalte, die die Domäne selbst als
   `prominent` markiert (KANBAN_COLUMNS). Kante und Kopf, nicht die ganze
   Fläche: die Zeilen darin sollen lesbar bleiben. */
.panel-prominent {
  border-color: var(--state-attention);
}

.panel-prominent .panel-head {
  background: var(--state-attention-weak);
}

.panel-head {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--bg-surface);
}

/* Versalien in Mono, gedämpft: die Kopfzeile benennt die Gruppe, sie ist keine
   Überschrift im Text. Die Ebene bleibt trotzdem eine echte <h2> — was hier
   klein aussieht, ist im Inhaltsverzeichnis eines Screenreaders eine Ebene. */
.panel-title {
  margin: 0;
  font-family: var(--font-code);
  font-size: var(--text-13);
  font-weight: 400;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.panel-count {
  margin-left: auto;
  font-family: var(--font-code);
  font-size: var(--text-13);
  color: var(--fg-muted);
}

/* Inhalt statt Zeilen — Fließtext, ein leerer Zustand, ein Formular. */
.panel-body {
  padding: var(--space-12);
}

/* =============================================================================
 * Zeile — der Standard für alles Aufzählbare.
 *
 * Feste Spalten statt Fluss, damit die Zeilen einer Liste untereinander
 * fluchten: Schiene, Typ-Icon, Titel, typabhängige Mitte, Anhang. Getrennt wird
 * durch eine Haarlinie, nie durch Abstand — bei fünfhundert Einträgen ist
 * Abstand nur Scrollweg.
 *
 * Die Schiene ist der Zustandskanal und bleibt vorerst auf `/` und `/trash`
 * leer: die Listenabfrage liefert keinen Status (BUILD-PLAN, M12.4 B). Sie steht
 * trotzdem, weil sie die Spalte ist, an der jede Liste links beginnt.
 * ========================================================================== */

.entries {
  margin: 0;
  padding: 0;
  list-style: none;
}

.entry {
  display: grid;
  grid-template-columns: 3px var(--space-20) minmax(0, 1fr) auto auto auto auto;
  align-items: center;
  min-height: var(--row-h);
  padding-right: var(--space-12);
  border-bottom: 1px solid var(--border-subtle);
}

/* Der Abstand steht in den Zellen, nicht als `gap` zwischen den Spuren: eine
   Liste, die Achse und Herkunft nicht füllt, zahlt sonst zweimal zwölf Pixel
   für Spalten, die nichts zeigen. Jede Zeile rendert alle sieben Zellen — nur
   so fluchten sie —, und die leeren kosten nichts.

   Nach Klasse und nicht als `> * + *`, weil die vier Meta-Zellen in einer Hülle
   stecken, die im breiten Fall `display: contents` ist: ein Kindselektor träfe
   dann die Hülle statt der Zellen. */
.entry-icon,
.entry-title,
.entry-mid,
.entry-axis,
.entry-prov,
.entry-tail {
  padding-left: var(--space-12);
}

.entry :empty {
  padding-left: 0;
}

/* Im breiten Fall gibt es die Hülle nicht: ihre vier Kinder sind selbst Zellen
   des Rasters und fluchten deshalb über die ganze Liste. */
.entry-meta {
  display: contents;
}

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

.entry-rail {
  align-self: stretch;
  background: transparent;
}

/* Achsen sind Oberfläche, nicht Farbe (ADR-0022, ADR-0023, und der Farbkanal
   gehört dem Zustand): weggelegt ist eine gestrichelte Schiene, kein roter Text.
   Gelöscht und archiviert sind zwei Achsen mit derselben Aussage über die
   Zeile — sie ist nicht mehr im Fluss —, also sehen sie gleich aus. */
.entry-deleted .entry-rail,
.entry-archived .entry-rail {
  background: repeating-linear-gradient(
    180deg,
    var(--border-subtle) 0 4px,
    transparent 4px 8px
  );
}

/* Die dritte Achse. Der Token stammt aus M12.1 und hat hier seinen ersten
   Verbraucher: schlafend ist gedämpft, nicht eingefärbt. */
.entry-asleep {
  opacity: var(--axis-snoozed-opacity);
}

/* Der Ausgang, aus der Domäne abgeleitet (taskOutcome), nie aus einem Status
   verglichen: erledigt tritt zurück, abgebrochen ebenso, und nur Erledigtes
   bekommt das Häkchen in der Markenfarbe. */
.entry-done .entry-title,
.entry-abandoned .entry-title {
  color: var(--fg-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.entry-done .entry-icon {
  color: var(--brand-accent);
}

.entry-icon {
  display: flex;
  color: var(--fg-muted);
}

/* Der Titel ist ein Link, sieht aber keiner: fünfzig unterstrichene Akzentzeilen
   sind eine Wand. Die Unterstreichung kommt beim Zeigen zurück. */
.entry-title {
  overflow: hidden;
  color: var(--fg-default);
  text-overflow: ellipsis;
  text-decoration: none;
  white-space: nowrap;
}

.entry-title:hover {
  text-decoration: underline;
}

.entry-mid {
  font-family: var(--font-code);
  font-size: var(--text-13);
  color: var(--fg-muted);
  white-space: nowrap;
}

/* Achse und Herkunft: die zwei Zellen, die eine Liste füllt, wenn sie mehr zu
   sagen hat als Titel und Datum. Beide gedämpft und in Mono — sie werden
   überflogen, nicht gelesen. */
.entry-axis {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-family: var(--font-code);
  font-size: var(--text-13);
  color: var(--fg-muted);
  white-space: nowrap;
}

.entry-axis .icon {
  width: 13px;
  height: 13px;
}

.entry-prov {
  font-family: var(--font-code);
  font-size: var(--text-13);
  color: var(--fg-muted);
  text-align: right;
  white-space: nowrap;
}

.entry-tail {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

/* =============================================================================
 * Die aufklappbare Zeile — Lesen und Bearbeiten getrennt (M17c, /settings/tokens).
 *
 * Kein dritter Behälter: das <summary> IST die Zeile, mit denselben Zellen und
 * demselben Umbruch unter 30rem. Aufgeklappt steht darunter, was die Zeile zu
 * bearbeiten hat; zugeklappt trägt sie nichts davon mit.
 *
 * Natives <details>, keine Zeile Skript. Ohne Unterstützung wäre es offen — der
 * Zustand der Seite vor dieser Änderung, also eine Degradierung und kein kaputtes
 * Layout: die `light-dark()`-Kategorie aus ADR-0024, nicht die `popover`-Kategorie.
 *
 * Die Haarlinie wandert vom <summary> an das <li>, sonst stünde sie zwischen der
 * Zeile und ihrem eigenen aufgeklappten Inhalt.
 * ========================================================================== */

.entries-expandable > li {
  border-bottom: 1px solid var(--border-subtle);
}

.entries-expandable > li:last-child {
  border-bottom: 0;
}

.entries-expandable summary.entry {
  border-bottom: 0;
  cursor: pointer;
  list-style: none;
}

.entries-expandable summary.entry::-webkit-details-marker {
  display: none;
}

.entries-expandable summary.entry::marker {
  content: "";
}

/* Der Hinweis, dass sich die Zeile öffnet — ohne ihn sieht ein Telefon eine
   Zeile, die nichts tut. Text statt Symbol: der Sprite hat keinen Pfeil, und
   für ein Zeichen ein Symbol einzuführen wäre mehr als diese Änderung.

   In der Icon-Spalte, die eine Token-Zeile sonst leer lässt: dort steht er neben
   dem Namen und bricht nie um. Gemessen im Anhang (`entry-tail`) rutschte er bei
   375px in eine dritte Flex-Zeile und ragte halb über die Zeile hinaus. */
.entry-toggle::before {
  content: "▸";
  color: var(--fg-muted);
}

details[open] > summary .entry-toggle::before {
  content: "▾";
}

/* Links bündig mit dem Titel: Schiene, Icon-Spalte, Zellabstand. */
.entry-detail {
  padding: var(--space-4) var(--space-12) var(--space-12)
    calc(3px + var(--space-20) + var(--space-12));
}

/* Beendet ist eine Achse, keine Farbe — dieselbe gestrichelte Schiene wie
   gelöscht und archiviert: die Zeile ist nicht mehr im Fluss. */
.entry-ended .entry-rail {
  background: repeating-linear-gradient(
    180deg,
    var(--border-subtle) 0 4px,
    transparent 4px 8px
  );
}

/* =============================================================================
 * Die schmale Zeile — umbrechen statt kürzen.
 *
 * Eine Zeile trägt neben dem Titel rund 270–400px feste Möblierung. Über die
 * volle Breite ist das kein Problem; in einer schmalen Liste — einer
 * Kanban-Spalte, einem Telefon — frisst sie den Titel auf, und ein auf zwölf
 * Pixel gekürzter Titel ist kein Titel mehr, sondern ein Präfix.
 *
 * Also: Titel auf die erste Zeile, Meta und Bedienelemente darunter. Es ist
 * dieselbe Zeile und dasselbe Markup, nur ein anderes Raster.
 *
 * Eine **Container**-Abfrage, keine Media-Abfrage: was zählt, ist die Breite der
 * Liste, nicht die des Fensters. Eine schmale Spalte in einem breiten Fenster
 * ist genau der Fall, den eine Media-Abfrage nicht sieht — und der Fall, um den
 * es hier geht.
 *
 * Die Schwelle ist gemessen, nicht gewählt: unterhalb von 30rem bleibt vom Titel
 * weniger als ein Drittel der Zeile.
 * ========================================================================== */

.entries {
  container-type: inline-size;
}

@container (max-width: 30rem) {
  .entry {
    grid-template-columns: 3px var(--space-20) minmax(0, 1fr);
  }

  /* Die Schiene bleibt die linke Kante der ganzen Zeile, über beide Zeilen. */
  .entry-rail {
    grid-row: 1 / -1;
  }

  /* Aus der Hülle wird eine eigene Zeile: die vier Zellen fluchten hier nicht
     mehr untereinander, sondern reihen sich. Bei dieser Breite ist Fluchten
     ohnehin keine Hilfe mehr — es gibt keine zweite Spalte, an der etwas
     ausgerichtet wäre. */
  .entry-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-8);
    grid-column: 2 / -1;
    padding-left: var(--space-12);
    padding-bottom: var(--space-4);
  }

  .entry-meta > * {
    padding-left: 0;
  }

  /* Der Titel darf jetzt umbrechen: er hat die Zeile für sich. */
  .entry-title {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  /* Zwei Zeilen brauchen Luft an der Oberkante, sonst klebt der Titel an der
     Haarlinie darüber — und die Zellen richten sich oben aus statt in der Mitte:
     ein Icon, das neben der Mitte eines zweizeiligen Titels schwebt, gehört zu
     nichts Sichtbarem. Die drei Pixel sind die halbe Differenz aus Zeilenhöhe
     und Icongröße, damit es auf der ersten Textzeile sitzt. */
  .entry {
    align-items: start;
    padding-top: var(--space-4);
  }

  .entry-icon {
    padding-top: 3px;
  }
}

/* =============================================================================
 * Icons — ein Symbol pro Bedeutung, aus dem ausgelieferten Sprite (icons.svg).
 *
 * Strich statt Fläche, und die Farbe kommt von der Umgebung: fill und stroke
 * erben in den Shadow-Tree, den <use> aufspannt. Ein CSS-Selektor kommt dort
 * nicht hinein — Vererbung ist der einzige Weg, und deshalb steht sie hier und
 * nicht im Sprite.
 * ========================================================================== */

.icon {
  width: var(--space-16);
  height: var(--space-16);
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Die Kartenregion der Tagesansicht (ADR-0030). Sie sitzt oberhalb des
   htmx-Tauschziels, damit ein Tausch sie nicht neu zeichnet — die Begründung
   steht bei der Stelle, die sie rendert (views-day.tsx).

   Ein Raster und keine Spalte, weil die Zahl der Karten die Zahl der Module ist
   und nicht eine Entscheidung dieser Datei. Keine Farbe und kein Schatten: eine
   Karte ist ein `.panel` und erbt beides von dort. */
.dashboard {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--space-12);
  margin-bottom: var(--space-16);
}

/* =============================================================================
 * Zielkontext einer Erfassung (Folge zu M17b, #195).
 *
 * Ein Auswahlfeld vor dem Anlegen-Knopf, sobald mehr als ein Kontext im Scope
 * ist. Gegen den Inline-Block in views.tsx, dessen `label` fett und als Block mit
 * Außenabstand gesetzt ist und dessen `select` volle Breite hat: in einer
 * Zeilen-Erfassung ist das Feld so breit wie sein längster Name, bis zur Grenze.
 * ========================================================================== */

.write-target {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  margin: 0;
  font-weight: inherit;
}

.write-target select {
  width: auto;
  max-width: 12rem;
  padding: var(--space-4);
}

/* Mit Auswahlfeld darf die Erfassungszeile umbrechen, und nur dann. Gemessen bei
   375px und grobem Zeiger: das Formular brauchte 429,4px in 327px und schob die
   Seite seitwärts. Pauschal auf `.add-task` brach auch die Zeile mit genau einem
   Kontext um (43,2px → 75,4px), und die sollte bleiben, wie sie war.

   Eine Klasse, die das Formular beim Zeichnen setzt, und kein `:has(.write-target)`:
   Der Client soll nicht herleiten, was der Server beim Zeichnen schon wusste. Es
   wäre auch die erste Verwendung von `:has()` gewesen, und nach ADR-0024 in der
   Kategorie von `popover`, nicht von `light-dark()` — ohne Unterstützung fiele die
   Regel still weg und die Zeile liefe über, ein kaputtes Layout statt einer
   harmlosen Verschlechterung. */
.add-task.with-target {
  flex-wrap: wrap;
}

/* =============================================================================
 * Ein Geheimnis, das einmal gezeigt wird
 * ========================================================================== */

/* Ein frisch geprägter Token (M17c) ist 56 Zeichen ohne ein einziges Leerzeichen
   und damit das Einzige auf diesen Seiten, das von sich aus nicht umbricht. Er
   muss vollständig lesbar sein, um abgeschrieben zu werden — auch auf 375px, und
   ohne die Seite seitwärts zu schieben. Kein dritter Behälter: eine Eigenschaft
   an <code>, dort wo sie gebraucht wird.

   **Umbruch ausschließlich über overflow-wrap, und das ist der ganze Zweck.**
   Der Wert wird einmal gezeigt und in eine Konfiguration kopiert, also muss er
   in einer Geste markierbar sein: ein einziger Textknoten im Markup, kein
   <wbr>, kein eingefügtes Zeichen, kein Eingriff in user-select. Ein Token,
   bei dem das Markieren die Hälfte mitnimmt, ist praktisch kaputt. Die
   Ununterbrochenheit prüft integration/web-settings.test.ts am gelieferten
   HTML. */
.secret {
  font-family: var(--font-code);
  overflow-wrap: anywhere;
}

/* =============================================================================
 * Eine Markierung, die Aufmerksamkeit verlangt (M20 Schnitt 3): ein abgelaufenes
 * Ziel, eine offene Metrik. Beides ist ein Zustand, also der Zustandskanal —
 * Aufmerksamkeit, nicht Überfälligkeit: nichts davon ist ein Fehler, beides ist
 * etwas, das jemand noch tun kann. Sitzt in `.badges` wie die Priorität.
 * ========================================================================== */

.badge-attention {
  color: var(--state-attention);
  border-color: var(--state-attention);
}

/* =============================================================================
 * Die Verknüpfungen auf der Item-Seite. Seit M3 gerendert, ohne Überschrift und
 * ohne Stil — und deshalb vom ersten Nutzer übersehen, der danach gesucht hat.
 * Ein eigener Abschnitt mit Haarlinie und Überschrift; die Relation vorn in Mono,
 * gedämpft, damit das Auge an ihr die Richtung liest und am Titel das Ziel.
 * ========================================================================== */

.item-links {
  margin-top: var(--space-24);
  padding-top: var(--space-12);
  border-top: 1px solid var(--border-subtle);
}

.item-links h2 {
  margin: 0 0 var(--space-8);
  font-size: var(--text-13);
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.item-links ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.item-links li {
  padding: var(--space-4) 0;
}

.item-link-relation {
  font-family: var(--font-code);
  font-size: var(--text-13);
  color: var(--fg-muted);
}

/* =============================================================================
 * Die Metrikpflege (M20 Schnitt 3, PR 2): drei kleine Formulare in der
 * aufgeklappten Zeile, und die Ablehnung mit ihrer Überschreib-Checkbox. Die
 * globalen Regeln für label und input machen aus einer Checkbox eine volle
 * Zeile — hier steht sie neben ihrem Satz.
 * ========================================================================== */

.metric-edit form + form {
  margin-top: var(--space-12);
}

/* Der Weg zur Metrikseite — für eine Metrik ohne Zielmarke der einzige. Als
   Textlink war er 20px hoch, gemessen bei 375px (M20 Schnitt 3, PR 3a); die
   Trefferfläche folgt jetzt der Navigation: 36px fein, 48,6px am groben Zeiger. */
.metric-page-link {
  display: inline-flex;
  align-items: center;
  min-height: calc((var(--space-32) + var(--space-4)) * var(--density));
}

/* Die aufgeklappte Metrikzeile (M21 Schnitt A): die neuesten Messwerte unter dem
   Eingabefeld, und die Pflege hinter einem eigenen Griff. */
.metric-recent {
  margin: var(--space-8) 0;
  padding-left: var(--space-20);
  color: var(--fg-muted);
}

.metric-maintain {
  margin-top: var(--space-12);
}

/* Die angesprungene Zeile (`#metric-<id>` nach dem Erfassen oder Speichern) steht
   nicht bündig oben: darüber bleibt ein Stück Liste im Bild, die nächste Metrik ist
   ohne Scrollen erreichbar (M21 Schnitt A2). Die Bestätigung steht in der Zeile. */
details[id^="metric-"] {
  scroll-margin-top: calc(var(--space-48) * 3);
}

.metric-collisions {
  margin: var(--space-8) 0;
  padding-left: var(--space-20);
}

.inline-check {
  display: flex;
  align-items: baseline;
  gap: var(--space-8);
  font-weight: normal;
}

.inline-check input {
  width: auto;
}
