/* =============================================================================
 * 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 gestapelte Liste (/settings/tokens): Name und Zweck in der ersten Zeile,
   Reichweite und Zustand darunter — auf jeder Breite, nicht erst unter 30rem.
   „active, expires in 291 days" und „all contexts" ließen dem Namen sonst ein
   Drittel der Zeile, und ein Token-Name ist das, woran man ihn erkennt. Dasselbe
   Raster wie die schmale Zeile unten, als Klasse statt als Container-Abfrage. */
.entries-stacked .entry {
  grid-template-columns: 3px var(--space-20) minmax(0, 1fr);
  align-items: start;
  padding-top: var(--space-4);
}

.entries-stacked .entry-rail {
  grid-row: 1 / -1;
}

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

.entries-stacked .entry-title {
  white-space: normal;
  overflow-wrap: anywhere;
}

.entries-stacked .entry-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
  grid-column: 3 / -1;
  padding-left: var(--space-12);
  padding-bottom: var(--space-4);
}

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

/* Der Zweck neben dem Namen: gedämpft, und er darf umbrechen. */
.entry-note {
  margin-left: var(--space-8);
  font-size: var(--text-13);
  color: var(--fg-muted);
}

/* Ein Feld, das zugeklappt beginnt: der Kopf ist das <summary>. */
.panel-fold > summary {
  cursor: pointer;
  list-style: none;
}

.panel-fold > summary::-webkit-details-marker {
  display: none;
}

.panel-fold:not([open]) > summary {
  border-bottom: 0;
}

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

/* Was ein Token erreicht: Chips in einer Reihe statt einer Zeile je Kontext. */
.reach-picker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin: var(--space-12) 0 0;
  padding: 0;
  border: 0;
}

.reach-picker legend {
  margin-bottom: var(--space-4);
  padding: 0;
  font-weight: 600;
}

label.reach-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  margin: 0;
  padding: var(--space-4) var(--space-8);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  font-weight: inherit;
  font-size: var(--text-13);
  cursor: pointer;
}

.reach-chip input[type="checkbox"] {
  width: auto;
  margin: 0;
  accent-color: var(--brand-accent);
}

.reach-chip:has(input:checked) {
  border-color: var(--brand-accent);
  background: var(--brand-accent-weak);
}

.reach-all {
  border-style: dashed;
}

/* Ein Token, der bald abläuft: der Zustand in der Zustandsfarbe, damit er
   verlängert wird, bevor ein Kalender-Abo still stehen bleibt. */
.token-expiring {
  color: var(--state-attention);
}

/* Der Kalender-Feed eines Tokens (ADR-0042): ein eigener Abschnitt unter den
   Formularen, durch eine Haarlinie getrennt, weil er eine eigene Freigabe ist. */
.token-feed {
  margin-top: var(--space-16);
  padding-top: var(--space-12);
  border-top: 1px solid var(--border-subtle);
}

.token-feed form:first-child {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-12);
}

.token-feed-save {
  margin-top: 0;
}

.token-feed input[readonly] {
  font-family: var(--font-code);
  font-size: var(--text-13);
}

/* Zwei Links, die wie Knöpfe aussehen, weil sie etwas tun: abonnieren. */
.token-feed-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
}

.token-feed-actions a {
  display: inline-block;
  padding: var(--space-4) var(--space-12);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-6);
  color: var(--fg-default);
  text-decoration: none;
}

.token-feed-actions a:hover {
  border-color: var(--brand-accent);
}

.copilot-key-state {
  margin: 0;
}

.copilot-replace > summary {
  cursor: pointer;
  color: var(--fg-muted);
}

/* =============================================================================
 * 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 auf Home (ADR-0030, geändert für `assistent-chat-home.md`
   D10). Home hat kein htmx-Tauschziel, also zeichnet kein Tausch sie neu — die
   Begründung steht bei der Stelle, die sie rendert (views-home.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 Ampel einer Zielmarke (M22 Schnitt 3a, ADR-0040 §5a). Ein Punkt, kein
 * zweiter Textblock: auf /metrics ist er die einzige Rückmeldung zum gerade
 * eingetragenen Wert, auf /goals und der Metrikseite steht die Zahl daneben.
 *
 * Die Farbe ist der Zustandskanal und sonst nichts — und sie ist nie die
 * einzige Aussage: neben jedem Punkt steht seine Bedeutung als Text für
 * Screenreader (`LightMark`), weil eine Ampel, die nur Farbe ist, für einen
 * Teil der Leute gar nichts sagt.
 * ========================================================================== */

.light {
  display: inline-block;
  inline-size: var(--space-8);
  block-size: var(--space-8);
  border-radius: 50%;
  margin-inline-end: var(--space-4);
  vertical-align: baseline;
}

.light-green {
  background: var(--state-positive);
}

.light-yellow {
  background: var(--state-attention);
}

.light-red {
  background: var(--state-overdue);
}

/* =============================================================================
 * Die Reihe vergangener Fenster (M22 Schnitt 3b, ADR-0040 §5b). Ein abgelaufenes
 * Fenster kennt kein Gelb: erfüllt oder nicht. Ohne Eintrag bleibt die Lücke
 * stehen — sie ist ein Platz, keine Farbe, sonst bedeuten vierzehn Punkte
 * irgendwann nicht mehr vierzehn Tage.
 *
 * Kompakt auf /goals (nur Punkte, Namen für Screenreader), ausführlich auf der
 * Metrikseite. Gemessen bei 375px: die Meta-Zeile hat dort rund 335px, ein Punkt
 * mit Abstand ist 12px — vierzehn Tage (168px) und acht Wochen (96px) passen
 * ohne Umbruch.
 * ========================================================================== */

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

.series-compact {
  flex-wrap: nowrap;
}

.series-compact .series-window {
  inline-size: var(--space-8);
  block-size: var(--space-8);
  border-radius: 50%;
}

.series-met {
  background: var(--state-positive);
}

.series-missed {
  background: var(--state-overdue);
}

/* Die Lücke ist eine Kante, keine Fläche: sie behauptet kein Urteil. */
.series-gap {
  background: transparent;
  border: 1px solid var(--border-subtle);
}

.series:not(.series-compact) {
  flex-direction: column;
  gap: var(--space-4);
  margin-block-end: var(--space-12);
}

.series:not(.series-compact) .series-window {
  display: flex;
  gap: var(--space-8);
  padding-inline-start: var(--space-8);
  border-inline-start: 2px solid var(--border-subtle);
  background: none;
}

.series:not(.series-compact) .series-met {
  border-inline-start-color: var(--state-positive);
}

.series:not(.series-compact) .series-missed {
  border-inline-start-color: var(--state-overdue);
}

.series-name {
  color: var(--fg-muted);
  min-inline-size: 9ch;
}

.series-verdict {
  margin: 0 0 var(--space-12);
}

/* =============================================================================
 * 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;
}

/* Die Historie (ADR-0046): derselbe Abschnitt wie die Links, zugeklappt, und
 * ihre Ueberschrift ist die Zeile, die ihn oeffnet. */
.item-history summary {
  font-size: var(--text-13);
  color: var(--fg-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.item-history ul {
  margin-top: var(--space-8);
}

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

/* =============================================================================
 * Die Item-Seite als Formular (Facelift nach M25).
 *
 * Die Seite ist eine Lesespalte mit einem Formular: Felder untereinander, die
 * vier kurzen (Status, Prioritaet, Kontext, Schlaf) nebeneinander, solange Platz
 * ist. Darunter die Links, die Zeitstempel und am Fuss ein Kasten fuer das, was
 * den Besuch beendet.
 * ========================================================================== */

/* Etwas breiter als die Lesespalte: drei Felder nebeneinander, und ein Feld
   fuer Tag und Uhrzeit braucht seine zwoelf rem, um beides zu zeigen. */
main:has(.item-form) {
  max-width: 40rem;
}

.item-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin: 0 0 var(--space-16);
}

.item-chip {
  padding: 0 var(--space-8);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  font-size: var(--text-13);
  color: var(--fg-muted);
}

/* Jedes Feld fuellt seine Spalte, auch eine Auswahl mit kurzen Werten. */
.item-form .field-row select {
  width: 100%;
}

.item-form .field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0 var(--space-12);
}

/* Ein Textfeld traegt oft einen Zeitpunkt mit Versatz, und der passt nicht in
   eine Spalte. Erst ab einer Breite, in der es zwei Spalten gibt: darunter
   wuerde die Spanne eine zweite erzwingen und die Seite zur Seite schieben. */
@media (min-width: 30rem) {
  .item-form .field-row .field-wide {
    grid-column: span 2;
  }
}

/* Zwei Felder unter einem Label: der Tag und daneben die Uhrzeit. Das erste
   nimmt den Platz, das zweite, was es braucht. */
.field-pair {
  display: flex;
  gap: var(--space-8);
}

.field-pair > :first-child {
  flex: 1 1 auto;
}

.field-pair > input[type="time"] {
  flex: 0 0 auto;
  width: auto;
}

/* Der gerenderte Text ist das, was man liest; die Quelle klappt darunter auf. */
.item-form .body {
  padding: var(--space-4) var(--space-12);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-6);
  background: var(--bg-surface);
  overflow-wrap: anywhere;
}

/* Lesen oder bearbeiten, an derselben Stelle: das Kaestchen neben dem Label
   entscheidet, welche der beiden Fassungen steht. Ohne Skript — :has() liest
   den Zustand, und die versteckte Textarea wird trotzdem mitgeschickt. */
.field-head {
  display: flex;
  align-items: baseline;
  gap: var(--space-12);
}

.item-form .body-toggle {
  margin: 0;
  font-size: var(--text-13);
  font-weight: normal;
  color: var(--brand-accent);
  text-decoration: underline;
  cursor: pointer;
}

/* Unsichtbar, aber im Fokus: die Tastatur erreicht es, der Ring sitzt am Wort. */
.body-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  opacity: 0;
}

.body-toggle:has(input:focus-visible) {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.item-form .field-hint {
  margin: var(--space-4) 0 0;
  font-size: var(--text-13);
  color: var(--fg-muted);
}

.body-toggle:has(input:checked) .when-reading,
.body-toggle:not(:has(input:checked)) .when-editing,
.body-field:has(.body-toggle input:checked) .body,
.body-field:has(.body-toggle input:not(:checked)) textarea {
  display: none;
}

.item-form textarea.code {
  font-family: var(--font-code);
  font-size: var(--text-13);
}

.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin: 0;
}

.item-form button.primary {
  font-weight: 600;
}

.stamps {
  margin-top: var(--space-24);
}

/* Archivieren ist harmlos und steht deshalb ohne Warnfarbe da; nur Loeschen
   traegt sie. Beide stehen am Fuss, weil sie den Besuch beenden. */
.item-leave {
  margin-top: var(--space-24);
  padding: var(--space-12) var(--space-16);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-6);
}

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

.item-leave-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
  padding: var(--space-8) 0;
}

.item-leave-row + .item-leave-row {
  border-top: 1px solid var(--border-subtle);
}

.item-leave-row p {
  margin: 0;
  font-size: var(--text-13);
  color: var(--fg-muted);
}

.item-leave-row button {
  margin-top: 0;
  white-space: nowrap;
}

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

.item-move select {
  width: auto;
}

.item-leave-row button.danger {
  border: 1px solid var(--state-overdue);
  border-radius: var(--radius-6);
  background: none;
  color: var(--state-overdue);
}

/* Setzen und Entfernen im Web (M21 Schnitt B): Remove steht in der Zeile, die Suche
 * darunter wie die Linkliste als eigener Abschnitt. */
.item-link-remove {
  display: inline;
}

.item-link-remove button {
  margin-top: 0;
}

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

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

.item-link-candidates {
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
}

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

/* =============================================================================
 * 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;
}

/* =============================================================================
 * Die Zeile einer Marke (M22, owner 2026-10-05) — umbrechen statt kürzen.
 *
 * Eine Marke sagt mehr als die sieben Zellen einer gewöhnlichen Zeile tragen: ihre
 * Metrik, ihren Maßstab, ihren Stand, was fällig ist, ihre Reihe. In einer Zeile
 * gekürzt wurde der Name zu „Ph…“ und die Ampel fiel rechts aus dem Bild. Hier steht
 * in der ersten Zeile Ampel, Name und Rolle; Name und Fakten brechen um, nichts
 * wird abgeschnitten.
 * ========================================================================== */

.target-row {
  display: grid;
  grid-template-columns: var(--space-32) minmax(0, 1fr) auto;
  column-gap: var(--space-8);
  row-gap: var(--space-4);
  align-items: center;
  padding: var(--space-8) var(--space-12) var(--space-8) calc(3px + var(--space-12));
  border-bottom: 1px solid var(--border-subtle);
}

.entries > .target-row:last-child {
  border-bottom: 0;
}

.target-light {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.target-name {
  color: var(--fg-default);
  text-decoration: none;
  overflow-wrap: anywhere;
}

a.target-name:hover {
  text-decoration: underline;
}

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

.target-facts,
.target-series {
  grid-column: 2 / -1;
}

.target-facts {
  font-family: var(--font-code);
  font-size: var(--text-13);
  color: var(--fg-muted);
  overflow-wrap: anywhere;
}

/* Auf der Ziel-Seite ist die Zeile der Kopf eines <details>: dieselben Regeln wie
   für die aufklappbare Eintragszeile, nur für dieses Raster. */
.entries-expandable summary.target-row {
  border-bottom: 0;
  cursor: pointer;
  list-style: none;
}

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

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

/* =============================================================================
 * Das Copilot-Panel (ADR-0044 §1): eine Schublade am rechten Rand, über der
 * Seite, geöffnet von der Sprechblase in der Kopfleiste, geschlossen mit ✕ oder
 * Escape. Auf dem Telefon nimmt sie die ganze Breite. Farben und Höhe nur aus
 * den Tokens (A11, A14): `var(--shadow)` ist die eine Elevation.
 * ========================================================================== */

/* Die Form des Benutzer-Knopfs daneben (shell.css, .user-trigger), und
   `margin: 0` ausdrücklich: der Inline-Block setzt jedem button einen Abstand
   nach oben, der ihn sonst aus der Kopfleiste schiebt. */
.copilot-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: calc((var(--space-32) + var(--space-4)) * var(--density));
  height: calc((var(--space-32) + var(--space-4)) * var(--density));
  margin: 0;
  padding: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: var(--bg-page);
  color: var(--fg-muted);
  cursor: pointer;
}

.copilot-toggle[aria-expanded="true"] {
  border-color: var(--fg-muted);
}

.copilot {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  width: min(28rem, 100vw);
  border-left: 1px solid var(--border-subtle);
  background: var(--bg-surface);
  box-shadow: var(--shadow);
  transform: translateX(100%);
  visibility: hidden;
  transition:
    transform 0.2s ease,
    visibility 0.2s;
}

.copilot[data-open] {
  transform: none;
  visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
  .copilot {
    transition: none;
  }
}

.copilot-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-12) var(--space-16);
  border-bottom: 1px solid var(--border-subtle);
}

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

.copilot-close {
  margin: 0;
  border: none;
  background: none;
  color: inherit;
  font-size: var(--text-13);
  cursor: pointer;
}

#copilot-content {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-12) var(--space-16);
}

.copilot-log {
  margin: 0 0 var(--space-12);
  padding: 0;
  list-style: none;
}

.copilot-log li {
  padding: var(--space-4) 0;
}

.copilot-person {
  font-weight: 600;
  white-space: pre-wrap;
}

.copilot-tool {
  font-family: var(--font-code);
  font-size: var(--text-13);
}

.copilot-thumbs {
  display: inline-flex;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.copilot-thumbs button {
  margin: 0;
  padding: var(--space-4) var(--space-8);
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  background: none;
  font-size: var(--text-13);
  line-height: 1;
  cursor: pointer;
  opacity: 0.6;
}

.copilot-thumbs button[aria-pressed="true"] {
  border-color: var(--border-subtle);
  opacity: 1;
}

.copilot-agent {
  margin-bottom: var(--space-8);
}

.copilot-send textarea {
  width: 100%;
}

.copilot-starters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin: 0 0 var(--space-12);
  padding: 0;
  list-style: none;
}

.copilot-starters form {
  margin: 0;
}

.copilot-starters button {
  margin: 0;
  padding: var(--space-4) var(--space-12);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-full);
  background: none;
  color: inherit;
  font-size: var(--text-13);
  cursor: pointer;
}

/* =============================================================================
 * Die Chat-Seite (Eigentümer, 2026-10-15): links die letzten Gespräche, rechts
 * ein neuer Chat oder ein Gespräch. Auf schmalen Bildschirmen steht die Liste
 * über dem Gespräch. Nur Tokens (A11, A14).
 * ========================================================================== */

.chat-layout {
  display: grid;
  grid-template-columns: minmax(12rem, 18rem) minmax(0, 1fr);
  gap: var(--space-24);
  align-items: start;
}

@media (max-width: 48rem) {
  .chat-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

.chat-list {
  border-right: 1px solid var(--border-subtle);
  padding-right: var(--space-12);
}

.chat-list ul {
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
}

.chat-list a {
  display: block;
  padding: var(--space-4) var(--space-8);
  border-radius: var(--space-8);
  color: inherit;
  text-decoration: none;
}

.chat-list a[aria-current="page"] {
  background: var(--bg-surface);
}

.chat-title {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chat-meta {
  display: block;
  overflow: hidden;
  font-size: var(--text-13);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chat-new-link {
  font-weight: 600;
}

/* Pills under a chat's title (concept assistent-chat-home.md §4.1): its context
   when more than one is selected, its goal — dimmed once the goal is closed. */
.chat-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.chat-pill {
  max-width: 100%;
  padding: 0 var(--space-8);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
  border-radius: var(--space-8);
  color: var(--fg-muted);
  font-size: var(--text-13);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.chat-pill-closed {
  opacity: 0.6;
}

.chat-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  align-items: end;
}

.chat {
  max-width: 48rem;
}

.chat-start {
  margin-top: var(--space-24);
}

.chat-ask {
  display: block;
  margin: 0 0 var(--space-8);
  font-size: var(--text-21);
  font-weight: 600;
}

.chat-start textarea {
  display: block;
  width: 100%;
  margin: 0;
}

/* Der Inline-Block gibt jedem label und button einen Abstand nach oben; in dieser
   Zeile stehen beide nebeneinander und gehören auf eine Linie. */
.chat-start-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  margin-top: var(--space-12);
}

.chat-start-row label,
.chat-start-row button {
  margin: 0;
}

.chat-start-row select {
  width: auto;
}

/* =============================================================================
 * Memory — "What Brain knows about you" (ADR-0049 §9)
 *
 * Eine Erinnerung ist keine Listenzeile. `.entry` ist das siebenspaltige Raster
 * der Listen, dessen erste Spur die 3px-Schiene ist; das eine `<details>` einer
 * Erinnerung landete darin und brach nach jedem Wort um (Eigentümer, 2026-10-27).
 * Hier ist ein Eintrag ein Block über die volle Breite, die Formulare darunter.
 * ========================================================================== */

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

.memory-entry {
  padding: var(--space-8) var(--space-12);
  border-bottom: 1px solid var(--border-subtle);
}

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

.memory-entry > details > summary,
.memory-add > summary {
  cursor: pointer;
  overflow-wrap: anywhere;
}

.memory-detail {
  display: grid;
  gap: var(--space-12);
  padding-top: var(--space-8);
}

.memory-add {
  padding: var(--space-8) var(--space-12);
}

.memory-form {
  display: grid;
  gap: var(--space-4);
  max-width: 40rem;
}

.memory-form button {
  justify-self: start;
}

/* =============================================================================
 * Home (concept `assistent-chat-home.md` §6). Nur Tokens (A11, A14).
 * ========================================================================== */

.home-starters {
  margin-top: var(--space-16);
}

.home-chat {
  margin-top: 0;
}

/* Der Tag wie in einer Kalenderliste: die Zeit links, eine Zeile je Eintrag,
   keine Lücken für die Stunden dazwischen (Eigentümer, 2026-10-28). */
.home-day {
  margin: 0;
  padding: 0;
  list-style: none;
}

.home-slot {
  display: grid;
  grid-template-columns: 4rem minmax(0, 1fr) auto auto;
  gap: var(--space-12);
  align-items: center;
  min-height: var(--row-h);
  padding: 0 var(--space-12);
  border-bottom: 1px solid var(--border-subtle);
}

.home-slot-past {
  opacity: var(--axis-snoozed-opacity);
}

.home-time {
  color: var(--fg-muted);
}

/* Auf Home bricht ein Titel auf höchstens zwei Zeilen um, statt nach dem ersten
   Drittel mit … zu enden (Eigentümer, 2026-10-28): Home zeigt wenige Zeilen, und
   die sollen lesbar sein. Die Zeilenhöhe der Liste ist ein Minimum, eine zweite
   Zeile kostet sonst nichts. */
.home-slot-title,
.home-grid .entry-title {
  display: -webkit-box;
  overflow: hidden;
  overflow-wrap: anywhere;
  white-space: normal;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

.home-slot,
.home-grid .entry {
  padding-block: var(--space-4);
}

.home-act {
  margin: 0;
}

.home-act button {
  margin: 0;
  padding: var(--space-4) var(--space-8);
}

/* Die Statuszeile: Segmente in einer Zeile; ein aufgeklapptes nimmt die ganze
   Breite, damit seine Liste unter der Zeile steht. */
.home-status {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-8) var(--space-16);
  margin: var(--space-12) 0 var(--space-16);
}

.home-seg summary {
  cursor: pointer;
}

.home-seg[open] {
  flex-basis: 100%;
}

.home-seg-warn,
.home-seg-warn summary {
  color: var(--state-overdue);
}

.home-filed-hint {
  margin: var(--space-4) 0 0;
}

/* Home in zwei Spalten ab der Desktop-Breite: links der Tag und die Statuszeile,
   rechts die Ziele (Konzept §6.2). Darunter eine Spalte, in Dokumentreihenfolge. */
/* Auch einspaltig ausdrücklich `minmax(0, 1fr)`: die implizite Spur ist `auto`
   und wächst auf die Mindestbreite der Zeilen — bei 390px ragten die Felder
   21px über die Spalte hinaus (gemessen, 2026-10-28). */
.home-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

.home-greeting {
  margin-bottom: var(--space-24);
}

@media (min-width: 48rem) {
  .home-grid {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: start;
  }
}

.home-metrics,
.home-goals {
  margin: 0;
  padding: 0;
  list-style: none;
}

.home-metric,
.home-goal {
  padding: var(--space-8) var(--space-12);
  border-bottom: 1px solid var(--border-subtle);
}

/* Ein Messwert in einer Zeile: Feld, Einheit, Record. Das Feld nimmt, was übrig
   ist, und darf schrumpfen — mit `width: auto` behielt es seine zwanzig Zeichen
   und ragte in der schmalen Spalte über den Rand (Eigentümer, 2026-10-28). */
.home-metric .metric-record {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-top: var(--space-4);
}

.home-metric .metric-record input,
.home-metric .metric-record select {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  margin: 0;
}

.home-metric .metric-record button,
.home-metric .metric-record p {
  flex: none;
  margin: 0;
}

.home-metric .metric-unit {
  flex: none;
}

.home-goal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

.home-goal-lights {
  display: inline-flex;
  gap: var(--space-4);
}
