/* Editorial Botany — Garten-Wiki Facade
   Refined minimal reading interface. Mobile-first.
   Schriften kommen lokal aus dem jeweiligen Theme (static/themes/*.css),
   keine Anfragen an Google Fonts. */

:root {
  --paper:        #F6F1E7;
  --paper-raised: #FAF7F0;
  --ink:          #1F1A17;
  --ink-soft:     #4A4238;
  --ink-muted:    #8A8175;
  --ink-faint:    #B5AC9E;
  --rule:         #E3DAC8;
  --rule-soft:    #EDE5D5;
  --sage:         #5B6B4A;
  --sage-deep:    #3F4F34;
  --sage-light:   #8FA07A;
  --sage-wash:    #EAEFE0;

  /* Gegenton der Bedeutungssuche (LLM-217, Retrieval-Vorführung): einzige
     wirklich neue Farbe im ganzen Bestand – überall sonst steht bereits eine
     Theme-Variable für das Gemeinte bereit (Wortsuche nutzt --sage). Global
     hier statt je Theme definiert, weil kein Theme sie überschreiben muss;
     ein Theme KANN das später tun. */
  --sinn:      #B45309;
  --sinn-wash: #FEF3C7;

  --serif: 'Newsreader', 'Iowan Old Style', Georgia, serif;
  --display: 'Fraunces', 'Hoefler Text', Garamond, serif;

  --measure: 34rem;
  --gutter: 1.5rem;

  --side-w: 258px;
  --side-w-collapsed: 62px;
  /* Tatsächliche .side-Hintergrundfarbe als eigene Variable: pkm/philosophie
     kehren sie auf --paper um (siehe dortige Theme-Kommentare). SVG-Icons, die
     ihren Hintergrund "freistellen" (z.B. die Löcher im Einstellungen-Zahnrad),
     müssen darauf verweisen statt fest auf --paper-raised, sonst zeigen sie in
     Themes mit umgekehrter Zuordnung einen sichtbaren Farbsprung. */
  --side-bg: var(--paper-raised);
}

/* Dark-Variante NUR der beiden neuen Variablen: Der Bestand hat sonst keine
   prefers-color-scheme-Umschaltung für seine Farbpalette (graph.html regelt
   sein Canvas-Rendering separat und eigenständig, s. dortiger Kommentar) –
   diese Regel greift also nur dann sichtbar, wenn ein künftiges Theme selbst
   auf Dark Mode umschaltet. Bis dahin folgenlos, aber schon vorbereitet statt
   bei der ersten Dark-Mode-Anfrage nachgezogen werden zu müssen. */
@media (prefers-color-scheme: dark) {
  :root {
    --sinn:      #E2A03F;
    --sinn-wash: #33260F;
  }
}

* { box-sizing: border-box; }

/* Globaler [hidden]-Reset. Die Browser-Regel `[hidden] { display: none }` steht
   im UA-Stylesheet und verliert deshalb gegen JEDE Autoren-Regel, die `display`
   setzt — unabhängig von Spezifität. Genau das ließ gefilterte Kacheln sichtbar
   (`.karte { display: flex }`): Das Attribut war gesetzt, die Trefferzahl
   stimmte, die Liste zeigte trotzdem alles. Vor dieser Regel gab es dafür drei
   Einzelfall-Reparaturen im Stylesheet (`.tabelle-zoom[hidden]`,
   `.suche-vorschlaege[hidden]`, `.ws-panel-chat > div[hidden]`) — der
   Kachelfilter war der vierte Fall derselben Falle, und `hidden` wird an 61
   Stellen in den Templates umgeschaltet.

   `!important` ist hier nicht der Vorschlaghammer, sondern die einzige
   Formulierung, die auch gegen später hinzukommende Klassenregeln hält:
   `hidden` heißt versteckt, ausnahmslos. (`hidden="until-found"` wird im
   Projekt nirgends genutzt und wäre der einzige Fall, der eine Ausnahme
   bräuchte.) Die drei Einzelfall-Regeln bleiben stehen — sie sind jetzt
   überflüssig, aber harmlos. */
[hidden] { display: none !important; }

/* Root-Schriftgröße in % statt px: 112,5% = 18px bei Browser-Standard, skaliert
   aber mit der vom Nutzer gesetzten Schriftgröße (WCAG 1.4.4 Resize Text). Nur auf
   html — bei html,body zusammen würde sich der %-Wert auf body verdoppeln. */
html { font-size: 112.5%; }

/* Platz für den Scrollbalken dauerhaft reservieren: Schrumpft der Inhalt unter
   die Fensterhöhe (Katalog auf drei Treffer filtern, Ansicht wechseln),
   verschwindet sonst der Balken, die zentrierte Spalte wird um seine halbe
   Breite verschoben und die ganze Seite ruckt seitlich. Ohne Wirkung dort, wo
   das System überlagernde Scrollbalken zeichnet (macOS-Standard) – dann ist
   die Rinne 0 breit. */
html { scrollbar-gutter: stable; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  line-height: 1.7;
  font-feature-settings: "kern", "liga", "onum";
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
}

body {
  min-height: 100vh;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.12  0 0 0 0 0.10  0 0 0 0 0.07  0 0 0 0.035 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
}

/* ——— Sidebar ——————————————————————————————
   position:fixed über die volle Höhe links; .app-main bekommt margin-left in
   Sidebar-Breite. body bleibt so der einzige Scroll-Container (kein
   verschachteltes internes Scrollen), kompatibel mit Lightbox/Graph-Viewport-
   Tricks, die weiterhin body-relativ arbeiten. */

.side {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--side-w);
  display: flex;
  flex-direction: column;
  background: var(--side-bg);
  border-right: 1px solid var(--rule);
  z-index: 40;
  transition: width 200ms ease;
  overflow: hidden;
}

.side-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 1.1rem 0.6rem 0.9rem 1rem;
}

.side-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  flex: 1;
  min-width: 0;
  font-family: var(--display);
  font-variation-settings: "opsz" 36, "wght" 480, "SOFT" 30;
  font-size: 1.05rem;
  letter-spacing: -0.012em;
  color: var(--ink);
  text-decoration: none;
}

.side-brand .sprig {
  width: 24px;
  height: 24px;
  color: var(--sage);
  flex-shrink: 0;
}

.side-brand em {
  font-style: italic;
  color: var(--sage-deep);
  font-variation-settings: "opsz" 36, "wght" 420, "SOFT" 80;
}

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

.side-toggle {
  flex-shrink: 0;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.3rem;
  line-height: 0;
  border-radius: 4px;
  color: var(--ink-muted);
  transition: color 160ms ease, background 160ms ease;
}

.side-toggle:hover { color: var(--ink); background: var(--paper); }

.newchat {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin: 0.1rem 0.9rem 0.9rem;
  padding: 0.6rem 0.8rem;
  background: var(--sage-deep);
  color: var(--paper);
  border: none;
  border-radius: 4px;
  font-family: var(--serif);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: none;
  cursor: pointer;
  transition: background 160ms ease;
}

.newchat:hover { background: var(--ink); }
.newchat svg { flex-shrink: 0; }

.side-scroll {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
  padding: 0 0.6rem 0.6rem;
}

.navgroup { margin-bottom: 0.3rem; }

.navgroup-label {
  margin: 0.9rem 0.4rem 0.3rem;
  font-family: var(--serif);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
}

.navgroup-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.55rem;
  border-radius: 4px;
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.9rem;
  transition: background 130ms ease, color 130ms ease;
}

.navgroup-item svg { flex-shrink: 0; color: var(--ink-muted); }

/* Sidebar-Hintergrund ist --paper-raised; --paper hebt sich im Hover davon ab. */
.navgroup-item:hover { background: var(--paper); color: var(--ink); }

.navgroup-item[aria-current="page"] {
  background: var(--sage-wash);
  color: var(--sage-deep);
}

.navgroup-item[aria-current="page"] svg { color: var(--sage-deep); }

.navgroup-item-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.navgroup-item-button {
  background: none;
  border: none;
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
}

.badge {
  flex-shrink: 0;
  margin-left: auto;
  background: var(--rule-soft);
  border: 1px solid var(--rule);
  color: var(--ink-muted);
  border-radius: 999px;
  font-size: 0.68rem;
  padding: 0 0.45em;
  line-height: 1.5;
}

.navgroup-item[aria-current="page"] .badge { background: var(--paper-raised); }

.chatlist { margin-top: 0.2rem; }

/* Gruppen-Label (Heute/Diese Woche/Älter) — gleicher Stil wie .navgroup-label,
   die Klasse wird direkt wiederverwendet (siehe _layout.html). */

.chatlist-item {
  display: flex;
  align-items: center;
  border-radius: 4px;
  transition: background 130ms ease;
}

.chatlist-item:hover,
.chatlist-item:focus-within { background: var(--paper); }

.chatlist-item.is-active { background: var(--sage-wash); }
.chatlist-item.is-active .chatlist-item-link { color: var(--sage-deep); }

.chatlist-item-link {
  display: block;
  flex: 1;
  min-width: 0;
  padding: 0.4rem 0.55rem;
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.82rem;
}

.chatlist-item-text {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chatlist-del { flex-shrink: 0; margin-right: 0.25rem; }

/* Desktop: der "×" erscheint erst bei Hover/Fokus der Zeile, sonst versteckt
   (Sidebar bleibt ruhig); auf Touch (kein Hover) dauerhaft sichtbar, da dort
   kein Hover-Vorzustand existiert. Immer per Tastatur fokussierbar. */
.chatlist-del-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  border: none;
  border-radius: 4px;
  background: none;
  color: var(--ink-muted);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 130ms ease, background 130ms ease, color 130ms ease;
}

.chatlist-del-btn:hover { background: var(--rule-soft); color: var(--ink); }

.chatlist-item:hover .chatlist-del-btn,
.chatlist-del-btn:focus-visible { opacity: 1; }

@media (hover: none) {
  .chatlist-del-btn { opacity: 0.6; }
}

.chatlist-empty {
  margin: 0.2rem 0.55rem;
  color: var(--ink-faint);
  font-size: 0.8rem;
}

.side-foot {
  flex-shrink: 0;
  border-top: 1px solid var(--rule);
  padding: 0.6rem 0.6rem 0.7rem;
}

.side-foot .navgroup-item { font-size: 0.88rem; }

/* ——— Content-Träger ————————————————————— */

.app-main {
  margin-left: var(--side-w);
  min-height: 100dvh;
  transition: margin-left 200ms ease;
}

/* Nur der mobile Drawer benutzt den Scrim; Desktop bleibt display:none. */
.scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 35;
  background: rgba(31, 26, 23, 0.38);
}

/* Erst im Mobile-Breakpoint sichtbar (siehe @media (max-width: 600px)). */
.topbar { display: none; }

/* ——— Sidebar einklappen (Desktop-Konzept) —————
   Nur außerhalb des Mobile-Breakpoints wirksam: dort gilt ausschließlich der
   Off-Canvas-Drawer, ein evtl. aus einer früheren Desktop-Session
   persistierter side-collapsed-Zustand darf die mobile Darstellung nicht
   überschreiben (siehe .side-toggle{display:none} im 600px-Query). */
@media (min-width: 601px) {
  html.side-collapsed .side { width: var(--side-w-collapsed); }
  html.side-collapsed .app-main { margin-left: var(--side-w-collapsed); }

  html.side-collapsed .side-head { flex-direction: column; gap: 0.4rem; padding: 0.7rem 0 0.3rem; }
  html.side-collapsed .side-brand { justify-content: center; padding: 0; }
  html.side-collapsed .newchat { margin: 0.3rem 0.5rem 0.8rem; padding: 0.55rem 0; }
  html.side-collapsed .navgroup-item { justify-content: center; padding: 0.55rem 0; }

  /* Gruppenüberschriften und Gesprächsliste im Kompaktmodus vollständig
     entfernen (auch für AT) — die <nav aria-label="…">-Landmarken tragen die
     Gruppenbedeutung bereits, die Gesprächsliste passt konzeptionell nicht in
     eine Icon-Leiste. */
  html.side-collapsed .navgroup-label,
  html.side-collapsed .chatlist { display: none; }

  /* Text/Badge NICHT display:none, sondern nur visuell ausblenden (sr-only-
     Technik): sonst hätten Katalog/Suche/Eingang/…/Abmelden im eingeklappten
     Zustand keinen Accessible Name mehr — die SVG-Icons sind aria-hidden, ein
     entferntes Text-Kind zählt nicht mehr zur Namensberechnung (WCAG 4.1.2).
     Als Nebeneffekt bleiben Badge-Zahlen (z.B. "Eingang 3") weiter Teil des
     vorgelesenen Linknamens. */
  html.side-collapsed .side-brand-text,
  html.side-collapsed .newchat-text,
  html.side-collapsed .navgroup-item-text,
  html.side-collapsed .badge {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

/* ——— Article column ———————————————————— */

.column {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 3rem var(--gutter) 5rem;
  animation: rise 700ms cubic-bezier(.2,.7,.2,1) both;
}

/* Reines Aufblenden ohne transform: ein Transform (auch die von fill-mode:both
   hinterlassene Identitäts-Matrix) würde .column zum Bezugsrahmen für
   position:fixed machen und die fixe TOC-Randleiste mitscrollen lassen. */
@keyframes rise {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.kicker {
  font-family: var(--serif);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--sage-deep);
  margin: 0 0 0.9rem;
}

h1.title {
  font-family: var(--display);
  font-variation-settings: "opsz" 144, "wght" 380, "SOFT" 20;
  font-size: clamp(2.2rem, 6vw, 3.4rem);
  line-height: 1.04;
  letter-spacing: -0.022em;
  margin: 0 0 0.75rem;
  color: var(--ink);
}

h1.title em {
  font-style: italic;
  font-variation-settings: "opsz" 144, "wght" 360, "SOFT" 100, "WONK" 1;
  color: var(--sage-deep);
}

.meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0 0;
  font-family: var(--serif);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-muted);
  margin: 0 0 2.4rem;
}

.meta .dot { color: var(--ink-faint); margin: 0 0.55rem; }

/* ——— Gliederung (TOC, Etappe 5) ————————————
   Zweispaltig erst ab 1180px (genug Raum neben --measure für eine ruhige
   14rem-Spalte); darunter verhält sich .column.has-toc wie normales .column
   (einspaltig, TOC ausgeblendet) — ohne dass eine weitere Regel nötig wäre. */

@media (min-width: 1180px) {
  /* Die Gliederung sitzt als fixe Leiste ganz rechts am Fensterrand, so breit
     wie die linke Sidebar. Die Lesespalte füllt nicht mehr ein Grid, sondern
     zentriert sich im Bereich zwischen linker Sidebar und rechter TOC-Leiste –
     da beide Leisten gleich breit sind, sitzt sie mittig im Fenster. */
  .column.has-toc {
    max-width: none;
    padding-right: calc(var(--side-w) + var(--gutter));
  }
  .column.has-toc .doc-main {
    max-width: calc(var(--measure) * 1.2);
    margin: 0 auto;
  }
}

.toc { display: none; }

@media (min-width: 1180px) {
  .toc {
    display: block;
    position: fixed;
    top: 0;
    right: 0;
    width: var(--side-w);
    height: 100vh;
    overflow-y: auto;
    padding: 3rem 1.4rem;
    border-left: 1px solid var(--rule);
    background: var(--side-bg);
    z-index: 10;
  }
}

.toc-label {
  font-family: var(--serif);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  /* --ink-soft statt --ink-muted: die TOC-Leiste hat jetzt --side-bg als
     Hintergrund (leicht dunkler als die Seite); --ink-muted verfehlt darauf im
     Garten-Theme AA (3,58:1), --ink-soft ist in allen Themes sicher. */
  color: var(--ink-soft);
  margin: 0 0 0.6rem;
}

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

.toc-item { margin: 0.1rem 0; }

/* --ink-muted liegt im Garten-/PKM-Theme nahe der AA-Grenze (4,5:1) — der
   Normalzustand des Links nutzt darum --ink-soft, das in allen drei Themes
   sicher AA-konform ist. */
.toc-link {
  display: block;
  padding: 0.2rem 0 0.2rem 0.6rem;
  border-left: 2px solid transparent;
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.86rem;
  line-height: 1.4;
  transition: color 130ms ease, border-color 130ms ease, background 130ms ease;
}

.toc-link:hover { color: var(--sage-deep); }

.toc-l3 .toc-link { padding-left: 1.3rem; font-size: 0.8rem; }

.toc-link.is-current {
  color: var(--sage-deep);
  font-weight: 600;
  border-left-color: var(--sage-deep);
  background: var(--sage-wash);
}

/* ——— Titel/Sektion bearbeiten ——————————— */

.meta-edit-form {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 28rem;
  margin: 0 0 0.6rem;
}

.meta-edit-form label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  margin-top: 0.5rem;
}

.meta-edit-form select,
.meta-edit-form input[type="text"] {
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 0.4rem 0.65rem;
  font-family: var(--serif);
  font-size: 0.95rem;
  background: var(--paper-raised);
  color: var(--ink);
}

.meta-edit-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.meta-edit-hint {
  font-size: 0.8rem;
  color: var(--ink-muted);
  margin: 0 0 2.4rem;
}

.ornament {
  display: block;
  margin: 2.2rem auto;
  color: var(--sage-light);
  width: 60px;
  opacity: 0.85;
}

article p { margin: 0 0 1.15rem; }

article p.lede::first-letter {
  font-family: var(--display);
  font-variation-settings: "opsz" 144, "wght" 420, "SOFT" 0;
  float: left;
  font-size: 4.2rem;
  line-height: 0.88;
  padding: 0.4rem 0.55rem 0 0;
  color: var(--sage-deep);
}

article h2 {
  font-family: var(--display);
  font-variation-settings: "opsz" 60, "wght" 460, "SOFT" 30;
  font-size: 1.55rem;
  line-height: 1.2;
  letter-spacing: -0.012em;
  margin: 2.6rem 0 0.9rem;
  color: var(--ink);
}

article h3 {
  font-family: var(--display);
  font-variation-settings: "opsz" 30, "wght" 520, "SOFT" 0;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 2rem 0 0.7rem;
  color: var(--sage-deep);
}

article ul {
  list-style: none;
  padding: 0;
  margin: 0 0 1.3rem;
}

article ul li {
  position: relative;
  padding-left: 1.4rem;
  margin: 0.35rem 0;
}

article ul li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--sage-light);
  font-weight: 300;
}

article a.wikilink {
  color: var(--sage-deep);
  text-decoration: none;
  border-bottom: 1px dotted var(--sage-light);
  padding-bottom: 1px;
  transition: background 160ms ease, border-color 160ms ease;
}

article a.wikilink:hover {
  background: var(--sage-wash);
  border-bottom-color: var(--sage-deep);
}

article a.wikilink::before {
  content: "⌘ ";
  color: var(--sage-light);
  font-size: 0.85em;
  margin-right: 0.05em;
}

blockquote {
  margin: 1.6rem 0;
  padding: 0.4rem 0 0.4rem 1.3rem;
  border-left: 2px solid var(--sage-light);
  color: var(--ink-soft);
  font-style: italic;
  font-family: var(--display);
  font-variation-settings: "opsz" 30, "wght" 360, "SOFT" 60;
}

code {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 0.9em;
  background: var(--paper-raised);
  padding: 0.1em 0.35em;
  border-radius: 2px;
  color: var(--ink-soft);
}

pre {
  background: var(--paper-raised);
  padding: 0.8rem 1rem;
  border-radius: 4px;
  overflow-x: auto;
  max-width: 100%;
  white-space: pre;
}

pre code {
  background: none;
  padding: 0;
  border-radius: 0;
  font-size: 0.85em;
}

em.bildunterschrift {
  display: block;
  font-style: italic;
  font-size: 0.82em;
  color: var(--ink-faint);
  text-align: center;
}

/* ——— Tabellen ——————————————————————————— */

article table,
.tabelle-overlay table {
  border-collapse: collapse;
  font-size: 0.94rem;
}

/* Standardfall: Tabelle füllt die Spalte. Innerhalb des Scroll-Wrappers
   (breite Tabellen) und im Overlay wird das unten überschrieben. */
article table {
  width: 100%;
  margin: 1.6rem 0;
}

article th,
.tabelle-overlay th {
  text-align: left;
  font-family: var(--serif);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-muted);
  padding: 0.5rem 0.75rem;
  border-bottom: 2px solid var(--rule);
}

article td,
.tabelle-overlay td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid var(--rule-soft);
  color: var(--ink-soft);
  vertical-align: top;
}

article tr:last-child td,
.tabelle-overlay tr:last-child td { border-bottom: none; }

/* Breite Tabellen: horizontal scrollbarer Container statt Spaltenüberlauf.
   Wirkt komplett ohne JS (auch mobil); die Zoom-Schaltfläche ist optional. */
article .tabelle-figur {
  margin: 1.6rem 0;
}

article .tabelle-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* min-width:100% füllt weiterhin die Spalte; width:auto lässt die Tabelle bei
   Bedarf über die Spalte hinauswachsen → Scrollbalken statt Überlauf. */
article .tabelle-wrap table {
  width: auto;
  min-width: 100%;
  margin: 0;
}

.tabelle-zoom {
  margin-top: 0.5rem;
  font-family: var(--serif);
  font-size: 0.8rem;
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper-raised);
  color: var(--ink);
  cursor: pointer;
}

.tabelle-zoom:hover { border-color: var(--ink-soft); }
.tabelle-zoom[hidden] { display: none; }

/* Vollansicht-Overlay (natives <dialog>: Escape/Fokusfalle/Backdrop nativ). */
.tabelle-overlay {
  position: relative;
  width: min(96vw, 1400px);
  max-width: 96vw;
  max-height: 92vh;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28);
}

.tabelle-overlay::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

/* Rundes ✕ oben rechts (bleibt fix, während der Tabellen-Body scrollt). */
.tabelle-overlay-close {
  position: absolute;
  top: 0.7rem;
  right: 0.7rem;
  z-index: 1;
  width: 2.2rem;
  height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: var(--paper-raised);
  color: var(--ink);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.tabelle-overlay-close:hover { border-color: var(--ink-soft); }

.tabelle-overlay-body {
  overflow: auto;
  max-height: 92vh;
  padding: 3rem 1.2rem 1.4rem;
}

.tabelle-overlay-body table {
  width: auto;
  min-width: 100%;
  margin: 0;
}

/* ——— See also & Footer meta ————————————— */

.see-also {
  margin: 3rem 0 0;
  padding: 1.6rem 0 0;
  border-top: 1px solid var(--rule);
}

.see-also h4 {
  font-family: var(--serif);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--ink-muted);
  margin: 0 0 0.8rem;
  font-weight: 500;
}

.see-also ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.see-also li {
  padding: 0.35rem 0;
  border-bottom: 1px dotted var(--rule);
}

.see-also li:last-child { border-bottom: none; }

.see-also a {
  color: var(--ink);
  text-decoration: none;
  font-family: var(--display);
  font-variation-settings: "opsz" 24, "wght" 440, "SOFT" 30;
  font-size: 1.02rem;
}

.see-also a:hover { color: var(--sage-deep); }

/* ——— Mind-Map-Einstieg (LLM-147) ———————————————————————————
   Steht direkt unter „Siehe auch" und bewusst OHNE eigene Trennlinie: Die
   Lernhilfen-Zone darunter bringt schon eine mit, zwei kurz aufeinander
   folgende Linien zerhacken das Seitenende. `.btn-small` war bisher reine
   Button-Klasse — als Link braucht sie Blockdarstellung und darf nicht
   unterstrichen sein. */
.mindmap-zone {
  margin: 1.4rem 0 0;
}

a.btn-small {
  display: inline-block;
  text-decoration: none;
  color: var(--ink);
}

/* ——— Lernhilfen (LLM-31: Erzeugen-Button + Study-Guide-Partial) ————— */

.lernhilfe-zone {
  margin: 2rem 0 0;
  padding: 1.4rem 0 0;
  border-top: 1px solid var(--rule);
}

.lernhilfe-status {
  margin-left: 0.8rem;
  font-size: 0.82rem;
  color: var(--ink-muted);
}

.lernhilfe-ausgabe {
  margin-top: 1.2rem;
}

.lernhilfe-section {
  margin: 1.6rem 0;
}

/* --ink-soft statt --ink-muted: als gesperrtes Versallabel dieser Größe
   verfehlte --ink-muted AA (Garten 3,41:1, pkm 4,83, philosophie 5,05 –
   gemessen 2026-07-26). Betrifft beide Rendering-Orte des Partials, den
   Lernhilfen-Block in seite.html wie das Projekt-Studio. */
.lernhilfe-section h4 {
  font-family: var(--serif);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--ink-soft);
  margin: 0 0 0.8rem;
  font-weight: 500;
}

.lernhilfe-section ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

.lernhilfe-section li {
  padding: 0.4rem 0;
  border-bottom: 1px dotted var(--rule);
}

.lernhilfe-section li:last-child { border-bottom: none; }

/* ACHTUNG: Der Chip-Block am Dateiende (.lernhilfe-beleg, gleiche
   Spezifität, steht später) überschreibt display, margin-top und font-size
   dieses Blocks – und zwar an BEIDEN Rendering-Orten, nicht nur im Panel. Die
   Größe lebt deshalb dort (0,78rem auf .lernhilfe-beleg a); hier stünde sie
   nur als zweite, wirkungslose Wahrheit. */
.lernhilfe-beleg {
  display: block;
  margin-top: 0.2rem;
  color: var(--ink-muted);
}

.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
  margin-top: 2rem;
}

.tag-chip {
  font-size: 0.78rem;
  padding: 0.2em 0.65em;
  border-radius: 99px;
  background: var(--sage-wash);
  color: var(--sage-deep);
  border: 1px solid var(--sage-light);
  text-decoration: none;
  letter-spacing: 0.02em;
}

.tag-chip:hover {
  background: var(--sage);
  color: #fff;
  border-color: var(--sage);
}

.colophon {
  margin-top: 3.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--rule);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-faint);
  text-align: center;
}

.empty-state {
  color: var(--ink-muted);
  font-style: italic;
}

/* ——— Index ———————————————————————————— */

/* Dezenter, zugeklappter Hinweis auf zuletzt ingestierte Seiten (aus /eingang
   hierher verschoben — im Katalog passender als im Eingang-Tab). */
/* Mehr Luft nach unten als früher (1,5rem): Der Block ist ein Beiwerk zum
   Kopf, keine Steuerung — er soll sich von der Steuerzone darunter absetzen
   statt mit ihr zu verschmelzen (LLM-176). */
.recent-ingested-katalog {
  margin: 0 0 2.3rem;
  font-size: 0.85rem;
}

.recent-ingested-katalog > summary {
  cursor: pointer;
  list-style: none;
  color: var(--ink-muted);
}

.recent-ingested-katalog > summary::-webkit-details-marker { display: none; }

.recent-ingested-katalog ul {
  list-style: none;
  margin: 0.6rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.2rem;
}

.recent-ingested-katalog a {
  color: var(--ink-soft);
}

.recent-ingested-katalog a:hover {
  color: var(--sage-deep);
}

.index-controls {
  display: flex;
  gap: 0.5rem;
  margin: 2rem 0 1.5rem;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.index-toggle-all {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  color: var(--ink-soft);
  padding: 0.45rem 0.9rem;
  border-radius: 2px;
  font: inherit;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

.index-toggle-all:hover {
  border-color: var(--sage);
  color: var(--sage-deep);
  background: var(--sage-wash);
}

.index-section {
  margin: 0;
  border-bottom: 1px solid var(--rule-soft);
}

.index-section:first-of-type {
  border-top: 1px solid var(--rule-soft);
}

details.index-section > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.4rem 0.4rem 1.4rem 0.2rem;
  transition: background 0.12s;
}

details.index-section > summary::-webkit-details-marker { display: none; }

details.index-section > summary:hover {
  background: var(--sage-wash);
}

.index-chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  color: var(--sage);
  font-size: 1.35rem;
  line-height: 1;
  transition: transform 0.18s ease, color 0.15s;
  transform: rotate(0deg);
  flex-shrink: 0;
}

.index-chevron::before { content: "▸"; }

details.index-section > summary:hover .index-chevron {
  color: var(--sage-deep);
}

details.index-section[open] > summary .index-chevron {
  transform: rotate(90deg);
  color: var(--sage-deep);
}

.index-section h2 {
  font-family: var(--display);
  font-variation-settings: "opsz" 48, "wght" 460, "SOFT" 40;
  font-size: 1.5rem;
  letter-spacing: -0.01em;
  color: var(--sage-deep);
  margin: 0;
  flex: 1;
  min-width: 0;
  text-transform: none;
  font-variant: normal;
  line-height: 1.2;
}

/* Zähler ist kein h2-Kind mehr, sondern Geschwister im Flex-Layout des
   <summary> (align-items:center dort hält ihn mittig zur großen Titelzeile);
   margin-left:auto schiebt ihn rechtsbündig. */
.index-section .count {
  font-family: var(--serif);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 400;
  margin-left: auto;
  flex: none;
  white-space: nowrap;
}

.index-section .rule {
  display: none;
}

.index-list {
  list-style: none;
  padding: 0 0 1rem 2.05rem;
  margin: 0;
}

.index-list li {
  padding: 0.85rem 0;
  border-bottom: 1px dotted var(--rule);
}

.index-list li:last-child { border-bottom: none; }

.index-list a.entry-title {
  display: inline;
  font-family: var(--display);
  font-variation-settings: "opsz" 24, "wght" 460, "SOFT" 20;
  font-size: 1.08rem;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -0.005em;
}

.index-list a.entry-title:hover { color: var(--sage-deep); }

.index-list .entry-desc {
  display: block;
  margin-top: 0.15rem;
  color: var(--ink-soft);
  font-size: 0.94rem;
  line-height: 1.5;
}

/* ——— Ask / Fragen ————————————————————— */

.ask-form {
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 4px;
  /* LLM-207: knapperes Polster als früher (1.2rem/1.2rem/1rem) — der
     Absende-Knopf sitzt seit LLM-207 IM Feld statt in einer Aktionszeile
     darunter, das Feld trägt seine Höhe also allein aus dem Text. */
  padding: 0.85rem 0.9rem;
  margin: 2rem 0 0;
}

.ask-form textarea,
.ask-form input[type="search"] {
  width: 100%;
  border: none;
  background: transparent;
  font-family: var(--display);
  font-variation-settings: "opsz" 24, "wght" 380, "SOFT" 30;
  font-size: 1.15rem;
  line-height: 1.5;
  color: var(--ink);
  outline: none;
  padding: 0;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
}

.ask-form textarea {
  resize: none;
  overflow: hidden;
}

.ask-form textarea::placeholder,
.ask-form input[type="search"]::placeholder {
  color: var(--ink-faint);
  font-style: italic;
}

.ask-status {
  font-family: var(--font-mono, monospace);
  font-size: 0.85rem;
  color: var(--ink-faint);
  padding: 0.5rem 0 0.1rem;
}

/* Eingabezeile mit dem Absende-Knopf IM Feld (LLM-207, ersetzt die frühere
   .ask-actions-Zeile mit Tastaturhinweis links und Textknopf rechts).

   flex-end statt center: Bei mehrzeiliger Eingabe wächst das Textfeld nach
   unten (Auto-Resize in _fragen_chat_js.html) — der Knopf bleibt dann auf
   Höhe der letzten Zeile stehen, statt in der Mitte eines hohen Feldes zu
   schweben. */
.ask-eingabe {
  display: flex;
  align-items: flex-end;
  gap: 0.6rem;
}

/* min-width:0 ist Pflicht, nicht Vorsicht: Ein Flex-Kind hält sonst seine
   automatische Mindestbreite und schöbe den Knopf in der schmalen
   Workspace-Spalte aus dem Feld. */
.ask-eingabe textarea {
  flex: 1;
  min-width: 0;
}

/* Runder Icon-Knopf im Stil des Vorbilds. Bewusst NICHT .btn: der ist eine
   breite Textschaltfläche mit Versalien und Sperrung — als 2rem-Kreis
   unbrauchbar. Feste Größe in rem, damit er mit einer hochgesetzten
   Browser-Schriftgröße mitwächst (WCAG 1.4.4). */
.ask-send {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: var(--sage-deep);
  color: var(--paper);
  cursor: pointer;
  transition: background 150ms ease, opacity 150ms ease;
}

.ask-send:hover:not(:disabled) { background: var(--ink); }

.ask-send:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn {
  font-family: var(--serif);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--paper);
  background: var(--sage-deep);
  border: none;
  padding: 0.6rem 1.1rem;
  border-radius: 2px;
  cursor: pointer;
  transition: background 160ms ease;
}

.btn:hover:not(:disabled) { background: var(--ink); }

.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-ghost {
  background: transparent;
  color: var(--sage-deep);
  border: 1px solid var(--sage-light);
  padding: 0.5rem 1rem;
}

.btn-ghost:hover:not(:disabled) {
  background: var(--sage-wash);
  color: var(--sage-deep);
}

.save-row {
  margin-top: 0.9rem;
  text-align: right;
}

/* Chat-Umbau: dezenter Text-Link statt gefülltem Button — pro Antwort-Blase
   sitzt eine Speichern-Aktion, als großer Button wäre sie im Verlauf zu laut. */
.save-btn {
  font-family: var(--serif);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-muted);
  background: none;
  border: none;
  padding: 0.2rem 0;
  cursor: pointer;
  transition: color 160ms ease;
}

.save-btn:hover:not(:disabled) { color: var(--sage-deep); }

.save-btn:disabled { opacity: 0.5; cursor: default; }

.usage-info {
  margin-top: 0.6rem;
  font-size: 0.78rem;
  color: var(--muted, #888);
  letter-spacing: 0.01em;
}

.fragen-error {
  color: #8B3A2A;
  font-size: 0.9rem;
  margin-top: 1rem;
  padding: 0.6rem 0.9rem;
  border-left: 3px solid #C07060;
  background: #FDF3F0;
}

.fragen-hint {
  margin-top: 2rem;
  color: var(--ink-muted);
  font-size: 0.9rem;
  font-style: italic;
}

/* LLM-1: "Neuer Chat" — schlichter Reset-Link über dem Formular, nur bei
   laufendem Gespräch sichtbar (server-seitig per {% if thread %} gesteuert). */
.fragen-newchat {
  margin: 0.8rem 0 0;
}

/* LLM-24: "Frühere Gespräche" — ausklappbare Liste der zuletzt aktualisierten
   Gespräche (details/summary wie .index-section, aber flacher: keine
   Sektions-Hierarchie nötig). */
.fragen-recent {
  margin: 1.2rem 0 0;
  font-size: 0.9rem;
}

.fragen-recent > summary {
  cursor: pointer;
  color: var(--ink-soft);
  font-family: var(--serif);
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  padding: 0.3rem 0;
}

.fragen-recent > summary::-webkit-details-marker { display: none; }

.fragen-recent-list {
  list-style: none;
  padding: 0;
  margin: 0.5rem 0 0;
}

.fragen-recent-item {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--rule-soft);
}

.fragen-recent-item:last-child { border-bottom: none; }

.fragen-recent-title {
  font-family: var(--display);
  font-variation-settings: "opsz" 24, "wght" 400, "SOFT" 20;
  color: var(--ink);
  text-decoration: none;
  flex: 1;
}

.fragen-recent-title:hover { color: var(--sage-deep); }

.fragen-recent-date {
  font-size: 0.78rem;
  color: var(--ink-muted);
  white-space: nowrap;
}

.fragen-recent-delete {
  display: inline;
}

.fragen-recent-delete .btn-ghost {
  padding: 0.25rem 0.6rem;
  font-size: 0.72rem;
}

/* ——— Chat-Shell (Messenger-Layout für /fragen) —————————
   Kompletter Chat lebt in .chat-shell (siehe fragen.html) — scoped alle
   Regeln unten automatisch auf diese eine Seite, .column bleibt für den Rest
   des Wikis unverändert. Eingabe klebt via position:sticky am unteren Rand,
   der Verlauf (.chat-log) wächst darüber (flex:1). */

.chat-shell {
  display: flex;
  flex-direction: column;
  /* Näherung aus Spaltenpadding oben + kompaktem Kopfbereich, je Breakpoint
     unten leicht korrigiert. Die Sidebar nimmt keine vertikale Höhe mehr weg
     (sie sitzt links, nicht oben) — anders als die frühere Masthead-Höhe
     (~5.2rem), die hier einst mit einkalkuliert war. dvh statt vh:
     berücksichtigt ein-/ausblendende mobile Adressleisten, die vh sonst zu
     hoch ansetzt. */
  --chat-shell-offset: 7rem;
  min-height: calc(100dvh - var(--chat-shell-offset));
}

.chat-head { flex: none; }

.chat-head .kicker { margin-bottom: 0.5rem; }

.chat-head h1.title {
  font-size: clamp(1.7rem, 4.5vw, 2.4rem);
  margin-bottom: 0.4rem;
}

.chat-head .meta { margin-bottom: 0.9rem; }

/* Gesprächskopf (Thread geladen): Titel + Zeit statt des großen Hero-Texts.
   Linksbündig (Default — nur .chat-head-empty zentriert explizit, siehe
   unten), daher kein eigenes text-align nötig. */
.thread-head h1.title {
  font-size: clamp(1.3rem, 3vw, 1.7rem);
  margin-bottom: 0.4rem;
}

.thread-head time {
  display: block;
  font-family: var(--serif);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-muted);
  margin-bottom: 0.9rem;
}

/* Leerer Zustand (kein Thread): ruhige, zentrierte Startansicht statt eines
   linksbündigen Kopfs über einem leeren Verlauf. Kopf + Eingabe rücken
   vertikal in die Mitte (chat-shell-empty), die Aktionszeile wird mittig
   ausgerichtet — sonst zöge sie linksbündig aus dem zentrierten Kopf. */
.chat-head-empty { text-align: center; }
/* .meta und .chat-head-actions sind Flex-Container — text-align:center greift
   auf ihren Inhalt nicht, sie brauchen justify-content zum Zentrieren. */
.chat-head-empty .meta { justify-content: center; }
.chat-head-empty .chat-head-actions { justify-content: center; }

.chat-shell-empty { justify-content: center; }

/* Ohne Verlauf soll der leere .chat-log die Eingabe nicht nach ganz unten
   drücken; die Kompose-Leiste steht mittig im Fluss (nicht sticky) und ohne
   Absetz-Kante, da kein Verlauf dahinter durchscrollt. */
.chat-shell-empty .chat-log { flex: 0 0 auto; padding: 0; }

.chat-shell-empty .chat-compose {
  position: static;
  border-top: none;
  box-shadow: none;
  margin-top: 1.4rem;
}

.chat-head-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-bottom: 0.6rem;
}

.chat-head-actions .fragen-recent { margin: 0; }

/* Vorschlags-Chips im leeren Chat (UI-Umbau Etappe 2): deterministische
   Prefill-Links auf zuletzt aufgenommene Seiten — kein JS, kein LLM-Aufruf.
   Sitzt als letztes Kind von .chat-shell UNTER der Kompose-Leiste (dezent,
   nicht mehr im .chat-head). .chip-label nimmt per flex-basis:100% die ganze
   Zeile ein, die Chips wickeln darunter in eigene Zeile(n); nur im leeren
   Chat gerendert, dort per justify-content zentriert wie .meta/.chat-head-actions. */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 1.1rem 0 0.6rem;
}

.chat-shell-empty .chip-row { justify-content: center; }

.chip-label {
  flex-basis: 100%;
  margin: 0 0 0.15rem;
  font-family: var(--serif);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--ink-muted);
  text-align: center;
}

.chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink-soft);
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  font-size: 0.82rem;
  text-decoration: none;
  transition: border-color 140ms ease, color 140ms ease, background 140ms ease;
}

.chip:hover {
  border-color: var(--sage-light);
  background: var(--sage-wash);
  color: var(--sage-deep);
}

.chat-log {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  padding: 1.4rem 0;
}

.chat-msg { display: flex; width: 100%; }
.chat-msg-user { justify-content: flex-end; }
.chat-msg-assistant { justify-content: flex-start; }

.chat-bubble {
  border-radius: 16px;
  padding: 0.85rem 1.1rem;
}

/* Frage rechtsbündig, gefüllt: --sage-deep + --paper-Text ist der stärkere
   der beiden vorgeschlagenen Kontraste (dunkler Grund/helle Schrift) und
   liest sich eindeutig als "gesendete" Nachricht. */
.chat-msg-user .chat-bubble {
  max-width: 72%;
  margin-left: auto;
  background: var(--sage-deep);
  color: var(--paper);
  border-radius: 16px 16px 4px 16px;
  font-family: var(--serif);
  font-size: 1.02rem;
  line-height: 1.6;
  white-space: pre-wrap;
}

/* Antwort linksbündig, hell/randbetont — breiter als die Frage, da Antworten
   lang sind und Markdown/Code/Formeln enthalten. */
.chat-msg-assistant .chat-bubble {
  max-width: 90%;
  margin-right: auto;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 16px 16px 16px 4px;
}

/* Die bestehenden article-Regeln (Überschriften, Listen, Code, Wikilinks,
   KaTeX) greifen unverändert innerhalb der Blase; nur das erste/letzte Kind
   verliert seinen Außenabstand, sonst polstert er zusätzlich zum Blasen-Padding. */
.chat-bubble article { margin: 0; }
.chat-bubble article > *:first-child { margin-top: 0; }
.chat-bubble article > *:last-child { margin-bottom: 0; }

/* Quellenlinks in der Antwort in runde Klammern setzen — sonst wirken sie im
   Fließtext wie normaler Text. Nur im Chat (höhere Spezifität als die globale
   article a.wikilink::before-Regel), ersetzt dort das ⌘-Präfix; die Klammern
   dezent in Textfarbe, damit sie den Link rahmen statt Teil zu wirken. */
.chat-bubble a.wikilink::before {
  content: "(";
  color: var(--ink-muted);
  font-size: 1em;
  margin-right: 0;
}

.chat-bubble a.wikilink::after {
  content: ")";
  color: var(--ink-muted);
}

.chat-thinking {
  margin: 0;
  font-family: var(--font-mono, monospace);
  font-size: 0.85rem;
  font-style: italic;
  color: var(--ink-muted);
}

.chat-compose {
  position: sticky;
  bottom: 0;
  flex: none;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  box-shadow: 0 -10px 18px -16px rgba(31, 26, 23, 0.28);
  padding: 1rem 0 calc(0.9rem + env(safe-area-inset-bottom));
  margin-top: 0.5rem;
}

.chat-compose .ask-form { margin: 0; }

@media (max-width: 600px) {
  .chat-shell { --chat-shell-offset: 5.5rem; }
  .chat-msg-user .chat-bubble { max-width: 88%; }
  .chat-msg-assistant .chat-bubble { max-width: 96%; }
}

@media (min-width: 900px) {
  .chat-shell { --chat-shell-offset: 8.5rem; }
}

/* ——— Gliederung im Chat (UI-Umbau Etappe 5, umgebaut in LLM-207) ————
   Die Gliederung ist seit LLM-207 eine echte Spalte der Arbeitsfläche
   (.ws-panel-gliederung in fragen.html) statt einer per JS eingefügten,
   fixiert rechts stehenden <aside>. Damit ist sie einklappbar wie das
   Studio-Panel im Projekt-Workspace, und Ein-/Ausblenden nach Fensterbreite
   macht das Gitter-CSS statt einer Media-Query-Abfrage im Skript.

   Geblieben ist die Optik: .toc-list/.toc-link stammen unverändert aus der
   Gliederungs-Spalte der Artikelansicht weiter oben. */

/* Frage-Einträge (Top-Level) etwas kräftiger als die eingerückten
   Antwort-Überschriften darunter — hebt die Gesprächsstruktur hervor. */
.ws-panel-gliederung .toc-question > .toc-link { color: var(--ink); font-weight: 600; }

/* Quellenspalte des Chats (LLM-207, Etappe 2). Schlichte Liste im Stil der
   ausklappbaren Seitenliste des Projekt-Panels (.projekt-seitenliste), aber
   ohne deren <details>-Hülle: hier ist die Liste der einzige Inhalt der
   Spalte und hat nichts, worunter sie sich verstecken müsste. */
.chat-quellen-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.chat-quellen-liste a {
  display: flex;
  gap: 0.45rem;
  align-items: baseline;
  padding: 0.4rem 0.5rem;
  border-radius: 4px;
  font-size: 0.9rem;
  line-height: 1.35;
  color: var(--ink-soft);
  text-decoration: none;
}

.chat-quellen-liste a:hover {
  background: var(--paper-raised);
  color: var(--ink);
}

/* Nummer der Quelle in der Liste (LLM-207 E3, eingefärbt LLM-213).

   Sie trägt DIESELBE Ziffer wie der Beleg im Antworttext und sieht deshalb
   auch aus wie er — vorher stand hier ein Punkt, der zwar „belegt" anzeigte,
   aber keinen Bezug zur Ziffer in der Antwort herstellte: Wer wissen wollte,
   wohin die ① zeigt, musste Listeneinträge abzählen.

   Zwei Zustände, beide echt: gefüllt = in der Antwort belegt, nur Kontur =
   hat Kontext geliefert, wurde aber nicht zitiert. Das Retrieval übergibt
   planmäßig mehr Seiten, als die Antwort braucht; „nicht zitiert" ist also
   der Normalfall und kein Mangel — deshalb bleibt der Eintrag sichtbar und
   anklickbar und wird nur zurückgenommen.

   Feste Mindestbreite, damit die Titel aller Zeilen auf einer Fluchtlinie
   stehen (zweistellige Nummern wachsen darüber hinaus). */
.chat-quelle-nummer {
  flex: none;
  display: inline-block;
  min-width: 1.5em;
  padding: 0.05em 0.35em;
  border: 1px solid var(--sage);
  border-radius: 0.7em;
  background: transparent;
  color: var(--sage-deep);
  font-family: var(--font-mono, monospace);
  font-size: 0.72rem;
  line-height: 1.5;
  text-align: center;
}

.chat-quelle-nummer.ist-zitiert {
  background: var(--sage);
  color: var(--paper);
}

/* Lange Seitentitel ohne Leerzeichen (Slugs, zusammengesetzte Begriffe)
   dürfen die schmale Spalte nicht aufspreizen. */
.chat-quelle-titel {
  min-width: 0;
  overflow-wrap: anywhere;
}

.chat-quellen-liste a.ist-zitiert { color: var(--ink); }

/* Die Legende erklärt die beiden Zustände EINMAL unter der Liste statt in
   jeder Zeile (dort tragen sie das title-Attribut plus ein sr-only-Zusatz).
   Ohne sie wäre der Unterschied gefüllt/Kontur etwas, das man raten müsste. */
.chat-quellen-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.8rem;
  margin: 0.9rem 0 0;
  font-size: 0.74rem;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
}

/* Jedes Paar aus Marke und Beschriftung bleibt zusammen. Ohne diese Klammer
   umbricht der Umbruch mitten im Paar und die Beschriftung steht unter einer
   FREMDEN Marke — in der 300px-Spalte der Regelfall, nicht die Ausnahme. */
.chat-quellen-legende-eintrag {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}

/* ——— Belegziffern in der Antwort (LLM-207, Etappe 4) ————————
   Der Renderer liefert `<a class="wikilink">Seitentitel</a>`; das geteilte
   Skript _fragen_belege_js.html macht daraus die Ziffer. Ohne JavaScript
   greift diese Regel nie — dann stehen die Titel-Links da wie bisher.

   `.wikilink` bringt Unterstreichung und Farbe der Fließtext-Links mit; hier
   wird beides zurückgenommen, weil die Ziffer keine Textstelle ist, sondern
   eine Marke am Satzende. */
a.wikilink.ist-beleg {
  display: inline-block;
  min-width: 1.15em;
  margin-left: 0.15em;
  padding: 0 0.28em;
  border: none;
  border-radius: 0.65em;
  /* In der Akzentfarbe GEFÜLLT, nicht in einem blassen Grauton: Die frühere
     Füllung (--rule-soft) lag so nah an --paper, dass am Absatzende nur eine
     nackte Ziffer zu stehen schien und man den Beleg übersah. Bewusst die
     Theme-Variable und kein fester Farbwert — sie ist im pkm-Design blau, in
     philosophie rauchblau, in garten grün; ein Literal machte aus dem
     Gartenwiki ein blaues. Kontrast Papier auf --sage: 5,1 (garten), 5,2
     (pkm), 6,4 (philosophie), also AA in allen dreien. */
  background: var(--sage);
  color: var(--paper);
  font-family: var(--font-mono, monospace);
  /* Schnitt der Umgebung abschütteln. Die Marke steht zwar IM Fließtext, ist
     aber keine Textstelle — in einem kursiven Absatz (die „Faustregel"-Zeilen
     der Antworten sind welche) erbte die Ziffer die Kursive und stand schräg
     im runden Feld, direkt neben derselben Ziffer in aufrecht. Gilt für den
     Schriftschnitt genauso: In einer fett gesetzten Zeile wäre die Marke
     fett, in der nächsten nicht. */
  font-style: normal;
  font-weight: 400;
  /* Hochgestellt ohne <sup>: `vertical-align: super` mit verkleinerter
     Schrift verschiebt die Zeilenhöhe nicht, ein echtes <sup> im Fließtext
     täte das. */
  font-size: 0.66em;
  line-height: 1.7;
  vertical-align: super;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

a.wikilink.ist-beleg:hover,
a.wikilink.ist-beleg:focus-visible {
  background: var(--sage-deep);
  color: var(--paper);
  text-decoration: none;
}

/* Die Ziffer misst rund 15×15 px — sichtbar genug, als ZIELFLÄCHE aber zu
   klein (WCAG 2.2, 2.5.8 nennt 24×24 CSS-Pixel als Mindestmaß, und auf einem
   Berührungsbildschirm trifft man 15 px kaum). Ein unsichtbares
   Pseudo-Element vergrößert die Fläche auf etwa 26 px, ohne die Marke
   optisch aufzublähen — der Text daneben soll ruhig bleiben. Gemessen beim
   Prüfen: Ein Mausklick verfehlte die Ziffer bei einer Abweichung von
   zwei, drei Pixeln. */
a.wikilink.ist-beleg { position: relative; }

/* Die runden Klammern, die `.chat-bubble a.wikilink::before/::after` um jeden
   Quellenlink legt, gelten dem TITEL — eine Ziffer braucht sie nicht. `::after`
   war ohnehin schon überschrieben (es trägt die Trefferfläche, s. u.), `::before`
   nicht: Jede Belegziffer stand deshalb als „(1" da, mit öffnender und ohne
   schließende Klammer. Im Browser gemessen fällt das auch als Versatz auf —
   die Klammer schob die Ziffer um 0,33 em aus der Mitte. Beide Pseudo-Elemente
   gehören zusammen, also wird auch dieses hier stillgelegt. */
a.wikilink.ist-beleg::before {
  content: "";
  margin: 0;
}

a.wikilink.ist-beleg::after {
  content: "";
  position: absolute;
  inset: -0.32rem;
}

/* Beleg am ENDE eines Absatzes oder Listenpunkts (Klasse vom Skript, siehe
   `markiereEndbelege`). Seit der Umstellung der Beleg-Anweisung der
   Normalfall — und ein anderer Fall als die Marke im Satz:

   * KEINE Hochstellung. Hochgestellt wird eine Marke, die an einem Wort
     hängt. Am Blockende hängt sie an nichts, sie steht für sich; auf der
     Grundlinie liest sie sich als das, was sie ist — eine kleine
     Schaltfläche, über die man zur Quelle kommt. (NotebookLM stellt seine
     Quellennummern am Absatzende genauso auf die Grundlinie.)
   * GRÖSSER, weil sie jetzt fast immer angeklickt statt überflogen wird.
   * DEUTLICH GETRENNT. Mehrere Quellen je Block sind der Regelfall, und der
     Abstand ist hier nicht Geschmack, sondern Bedienbarkeit: Die
     Trefferfläche oben reicht 0,32 rem über die Ziffer hinaus, zwei Marken
     im bloßen Wortabstand hätten also überlappende Trefferflächen und ein
     Klick dazwischen öffnete die falsche Quelle. Deshalb der eigene Abstand
     UND die schmalere seitliche Aufweitung: Die Schaltfläche ist breit genug,
     die Aufweitung braucht nur noch die Höhe zu besorgen. */
a.wikilink.ist-beleg.ist-beleg-ende {
  min-width: 2em;
  margin-left: 0.4em;
  padding: 0.15em 0.55em;
  font-size: 0.8em;
  line-height: 1.5;
  vertical-align: baseline;
}

/* Die seitliche Aufweitung ist hier viel kleiner als bei der Marke im Satz —
   und das ist kein Sparen, sondern die Bedingung dafür, dass zwei Marken
   nebeneinander stehen können: Die Aufweitung ist unsichtbar, zwei zu
   großzügige überlappen sich also lautlos, und ein Klick dazwischen öffnet
   die falsche Quelle. Die Breite besorgt stattdessen die Schaltfläche selbst
   (`min-width: 2em`).

   Im Browser gemessen (Grundschrift 15 px): sichtbar 23 × 21 px,
   Trefferfläche 27 × 26 px — über dem Mindestmaß von WCAG 2.2, 2.5.8
   (24 × 24). Per `elementFromPoint` gegengeprüft: die Mitte jeder Marke
   trifft ihre eigene Quelle, ein Punkt zwischen zwei benachbarten trifft den
   Absatz und keine von beiden. Wer an `margin-left`, `min-width`,
   `font-size` oder diesen insets dreht, misst das bitte nach — die
   Aufweitung ist unsichtbar, eine Überlappung fällt sonst niemandem auf. */
a.wikilink.ist-beleg.ist-beleg-ende::after {
  inset: -0.15rem -0.1rem;
}

/* Fenster am Beleg: Titel, Auszug aus dem tatsächlich ausgelieferten
   Abschnitt und der Weg zur Quelle. Liegt an <body> (nicht neben dem Beleg),
   damit es nicht am `overflow` der Chat-Spalte abgeschnitten wird —
   dieselbe Falle wie beim Kanten-Tooltip im Graphen.

   Fläche und Schatten sind das, was es vom Untergrund abhebt, und der
   Untergrund ist fast immer die ANTWORTBLASE: Die Belege stehen in ihr, das
   Fenster klappt darunter auf. `--paper-raised` war deshalb die eine Farbe,
   die hier nicht geht — die Blase trägt genau sie (im pkm-Theme #f3f4f6),
   das Fenster verschwand darin bis auf seinen hellen Rand. `--paper` hebt
   sich davon ab; wo das Fenster über die Blase hinausragt und auf der
   Seitenfläche liegt (dort ebenfalls `--paper`), trägt der Schatten die
   Trennung. Er ist dafür kräftiger als vorher: Der frühere lag mit -12px
   Ausbreitung so eng am Kasten, dass er nur unter ihm sichtbar wurde. */
.beleg-popover {
  position: fixed;
  z-index: 60;
  max-width: min(23rem, calc(100vw - 2rem));
  padding: 0.8rem 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper);
  box-shadow: 0 10px 30px -8px rgba(31, 26, 23, 0.32),
              0 2px 6px -2px rgba(31, 26, 23, 0.2);
}

.beleg-popover-titel {
  margin: 0 0 0.4rem;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--ink);
}

.beleg-popover-auszug {
  margin: 0 0 0.7rem;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--ink-soft);
  /* Der Auszug ist eine Kostprobe, kein Ersatz für die Seite: Nach ein paar
     Zeilen bricht er ab, „Quelle anzeigen" führt zum Rest. */
  max-height: 7.5rem;
  overflow: hidden;
  white-space: pre-line;
}

.beleg-popover-knopf { font-size: 0.78rem; }

/* ——— Inbox / Eingang ——————————————————— */

.tab-nav {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.8rem;
}

.tab-nav .tab {
  padding: 0.45rem 1rem;
  font-size: 0.82rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s, border-color 0.15s;
}

.tab-nav .tab:hover { color: var(--ink); }

.tab-nav .tab.active {
  color: var(--ink);
  border-bottom-color: var(--ink);
  font-weight: 600;
}

.tab-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3em;
  padding: 0 0.3em;
  height: 1.3em;
  border-radius: 999px;
  background: var(--rule);
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 600;
  margin-left: 0.3em;
  vertical-align: middle;
}

.inbox-summary {
  display: flex;
  gap: 1.4rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--ink-muted);
  margin: 0 0 2.2rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid var(--rule);
}

.inbox-summary .num {
  font-family: var(--display);
  font-variation-settings: "opsz" 36, "wght" 460, "SOFT" 30;
  font-size: 1.6rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  display: block;
  text-transform: none;
  margin-top: 0.15rem;
  font-feature-settings: "onum", "lnum" 0;
}

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

.inbox-item {
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--rule);
}

.inbox-item:last-child { border-bottom: none; }

.item-head {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  margin-bottom: 0.45rem;
  flex-wrap: wrap;
}

.type-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--serif);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  padding: 0.18rem 0.55rem;
  border-radius: 2px;
  flex-shrink: 0;
}

.type-badge.link {
  background: var(--sage-wash);
  color: var(--sage-deep);
  border: 1px solid var(--sage-light);
}

.type-badge.md {
  background: var(--paper-raised);
  color: var(--ink-soft);
  border: 1px solid var(--rule);
}

.type-badge.doc {
  background: var(--ink);
  color: var(--paper);
  border: 1px solid var(--ink);
}

.type-badge svg { width: 10px; height: 10px; }

/* Typ-Tags Inline-Popover */
.type-tags {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  vertical-align: middle;
}

.type-badge-btn {
  display: inline-flex;
  align-items: center;
  font-family: var(--serif);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  padding: 0.18rem 0.55rem;
  border-radius: 2px;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink-soft);
  cursor: pointer;
  line-height: inherit;
}

.type-badge-btn:hover {
  border-color: var(--ink-soft);
  color: var(--ink);
}

.type-add-btn {
  font-family: var(--serif);
  font-size: 0.75rem;
  color: var(--ink-faint);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0 0.2rem;
  line-height: inherit;
}

.type-add-btn:hover { color: var(--ink-soft); }

.type-popover {
  display: none;
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  z-index: 200;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.6rem 0.75rem 0.75rem;
  min-width: 160px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.08);
}

.type-popover.open { display: block; }

.type-popover-form { display: flex; flex-direction: column; gap: 0; }

.popover-option {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.3rem 0;
  font-size: 0.85rem;
  color: var(--ink-soft);
  cursor: pointer;
  white-space: nowrap;
}

.popover-option:hover { color: var(--ink); }
.popover-option input { cursor: pointer; margin: 0; }

.popover-footer {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--rule);
}

.btn-small {
  font-family: var(--serif);
  font-size: 0.8rem;
  padding: 0.3rem 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--paper-raised);
  color: var(--ink);
  cursor: pointer;
}

.btn-small:hover { border-color: var(--ink-soft); }

.item-title {
  font-family: var(--display);
  font-variation-settings: "opsz" 30, "wght" 460, "SOFT" 20;
  font-size: 1.15rem;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--ink);
  text-decoration: none;
  flex: 1 1 auto;
  min-width: 0;
}

.item-title:hover { color: var(--sage-deep); }

.item-origin {
  font-size: 0.8rem;
  color: var(--ink-muted);
  margin: 0 0 0.6rem;
  font-style: italic;
}

.tdm-warn {
  font-size: 0.8rem;
  color: #8a5a00;
  background: rgba(180, 120, 0, 0.08);
  border-left: 3px solid #b47800;
  padding: 0.35rem 0.6rem;
  margin: 0 0 0.6rem;
  border-radius: 0 3px 3px 0;
}

.tdm-warn summary {
  cursor: pointer;
  list-style: none;
}

.tdm-warn summary::-webkit-details-marker {
  display: none;
}

.tdm-warn summary::after {
  content: " ⓘ";
  opacity: 0.7;
}

.tdm-warn[open] summary::after {
  content: " ▴";
}

.tdm-warn .tdm-explain {
  margin: 0.45rem 0 0;
  color: var(--ink-muted);
  line-height: 1.5;
}

.freigabe-action {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-muted);
  margin-left: 0.6rem;
  flex-shrink: 0;
}

.item-summary {
  margin: 0 0 0.9rem;
  color: var(--ink-soft);
  font-size: 0.97rem;
  line-height: 1.55;
}

.commit-details {
  margin: 0 0 0.8rem;
  font-size: 0.8rem;
  color: var(--ink-muted);
}

.commit-details > summary {
  cursor: pointer;
  user-select: none;
  color: var(--ink-faint);
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
}

.commit-details > summary::before {
  content: '▸';
  font-size: 0.7em;
  transition: transform 120ms;
}

.commit-details[open] > summary::before {
  transform: rotate(90deg);
}

.commit-files {
  margin: 0.5rem 0 0;
  line-height: 1.7;
  word-break: break-all;
}

.item-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}

.item-foot .meta-line { font-variant-caps: small-caps; letter-spacing: 0.12em; }

.expiry { color: var(--ink-muted); }
.expiry.soon { color: #9a5a2a; }

.item-actions {
  display: inline-flex;
  gap: 0.45rem;
}

/* ——— Buttons / Actions ————————————————— */

.action {
  font-family: var(--serif);
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  padding: 0.4rem 0.75rem;
  border-radius: 2px;
  background: transparent;
  cursor: pointer;
  border: 1px solid var(--rule);
  color: var(--ink-soft);
  transition: all 160ms ease;
}

.action:hover {
  background: var(--paper-raised);
  color: var(--ink);
}

.action.primary {
  border-color: var(--sage-deep);
  background: var(--sage-deep);
  color: var(--paper);
}

.action.primary:hover {
  background: var(--ink);
  border-color: var(--ink);
}

.action.danger:hover {
  border-color: #b25a4a;
  color: #b25a4a;
  background: transparent;
}

.action.danger-confirm {
  background: #b25a4a;
  color: var(--paper);
  border-color: #b25a4a;
}

.action.danger-confirm:hover { background: #7a3024; border-color: #7a3024; }

/* ——— Triage (Eingang-Item) ————————————— */

.triage-bar {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.triage-btn {
  font-family: var(--serif);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  padding: 0.5em 1.2em;
  border: 1px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 2px;
  transition: background 160ms ease, color 160ms ease, border-color 160ms ease;
}

.triage-btn:hover {
  background: var(--sage-wash);
  color: var(--sage-deep);
  border-color: var(--sage-light);
}

.triage-btn.primary {
  background: var(--sage-deep);
  color: var(--paper);
  border-color: var(--sage-deep);
}

.triage-btn.primary:hover {
  background: var(--ink);
  border-color: var(--ink);
}

/* ——— Review ————————————————————————— */

.interval-badge {
  display: inline-flex;
  align-items: center;
  font-family: var(--serif);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  padding: 0.18rem 0.55rem;
  border-radius: 2px;
  background: var(--paper-raised);
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  flex-shrink: 0;
}

.interval-badge.fresh { color: var(--sage-deep); border-color: var(--sage-light); background: var(--sage-wash); }
.interval-badge.aging { color: #6f5418; border-color: #d6c08a; background: #f5edd6; }
.interval-badge.stale { color: #8f3a2c; border-color: #d8a89c; background: #f5e5e0; }

.review-meta {
  font-size: 0.78rem;
  color: var(--ink-muted);
  margin: 0 0 0.7rem;
  font-variant-caps: small-caps;
  letter-spacing: 0.12em;
}

.review-meta .sep { color: var(--ink-faint); margin: 0 0.5rem; }

.review-snippet {
  margin: 0 0 0.9rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1.55;
  font-style: italic;
}

.confirm-row {
  margin-top: 0.9rem;
  padding: 0.85rem 1rem;
  background: #f5e5e0;
  border: 1px solid #d8a89c;
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.confirm-row .warning {
  font-size: 0.88rem;
  color: #7a3024;
  font-style: italic;
}

.confirm-row .actions {
  display: inline-flex;
  gap: 0.45rem;
}

/* ——— Delete Zone ——————————————————————— */

.delete-zone {
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

/* ——— KI-Bildbeschreibung ——————————————— */

blockquote.ki-bildbeschreibung {
  margin: 1.8rem 0;
  padding: 0.85rem 1.05rem;
  background: var(--sage-wash);
  border: 1px solid var(--sage-light);
  border-left: 3px solid var(--sage);
  border-radius: 0 3px 3px 0;
  font-style: normal;
  font-family: var(--serif);
  font-variation-settings: normal;
  color: var(--ink-soft);
  font-size: 0.96rem;
  line-height: 1.6;
}

aside.ki-bildbeschreibung {
  margin: 1.8rem 0;
  padding: 0.85rem 1.05rem;
  background: var(--sage-wash);
  border: 1px solid var(--sage-light);
  border-left: 3px solid var(--sage);
  border-radius: 0 3px 3px 0;
  color: var(--ink-soft);
  font-size: 0.96rem;
  line-height: 1.6;
}

blockquote.ki-bildbeschreibung::before,
aside.ki-bildbeschreibung::before {
  content: "Automatisch erzeugte Bildbeschreibung";
  display: block;
  font-family: var(--serif);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--sage-deep);
  margin-bottom: 0.6rem;
  font-style: normal;
  font-variation-settings: normal;
}

aside.ki-bildbeschreibung blockquote {
  margin: 0.5rem 0;
  padding: 0;
  border-left: none;
  background: none;
  font-style: normal;
  font-family: inherit;
  font-variation-settings: normal;
  color: inherit;
  font-size: inherit;
}

aside.ki-bildbeschreibung p:last-child {
  margin: 0.6rem 0 0;
  padding-top: 0.55rem;
  border-top: 1px dotted var(--sage-light);
  font-size: 0.82rem;
  color: var(--ink-muted);
}

/* ——— Ingest-Log ——————————————————————— */

/* ——— PDF-Upload (Eingang) ————————————————— */
.pdf-upload {
  /* margin-top: sitzt jetzt unter der Item-Liste (UI-Entzerrung Eingang/Aufnehmen),
     braucht daher Abstand nach oben statt nur nach unten. */
  margin: 2.5rem 0;
  padding: 1.3rem 1.5rem 1.5rem;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 3px;
}

.pdf-upload__eyebrow {
  margin: 0 0 0.9rem;
  font-family: var(--serif);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--sage-deep);
}

/* URL-Aufnahme (Eingang): teilt sich die Kartenoptik mit .pdf-upload, hat aber
   keine Dropzone – nur ein Feld und einen Knopf. Der schmale Abstand nach unten
   bindet sie optisch an die PDF-Karte darunter (beides „aufnehmen“). */
.url-capture {
  margin-bottom: 1.2rem;
}

.url-capture__row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.url-capture__field {
  flex: 1 1 auto;
  min-width: 0;
}

.url-capture__field input[type="text"] {
  width: 100%;
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper-raised);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.9rem;
}

.url-capture__field input[type="text"]::placeholder { color: var(--ink-faint); }

.url-capture__field input[type="text"]:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 1px;
}

.url-capture__hint {
  margin: 0.7rem 0 0;
  font-size: 0.8rem;
  color: var(--ink-soft);
}

@media (max-width: 600px) {
  .url-capture__row { flex-direction: column; align-items: stretch; }
  .url-capture__row .btn { width: 100%; }
}

.pdf-dropzone {
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding: 1.3rem 1.4rem;
  border: 1.5px dashed var(--sage-light);
  border-radius: 3px;
  cursor: pointer;
  transition: border-color 160ms ease, background 160ms ease;
}

.pdf-dropzone:hover,
.pdf-dropzone:focus-within {
  border-color: var(--sage-deep);
  background: var(--sage-wash);
}

.pdf-dropzone.is-dragover {
  border-style: solid;
  border-color: var(--sage-deep);
  background: var(--sage-wash);
}

/* Datei-Input unsichtbar, aber tastaturfokussierbar (Fokusring via focus-within) */
.pdf-dropzone input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.pdf-dropzone__icon {
  flex: none;
  width: 32px;
  height: 32px;
  color: var(--sage-deep);
}

.pdf-dropzone__lead {
  display: block;
  font-family: var(--display);
  font-size: 1.02rem;
  color: var(--ink);
}

.pdf-dropzone__lead u {
  text-decoration-color: var(--sage-light);
  text-underline-offset: 3px;
}

.pdf-dropzone__hint {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.8rem;
  /* --ink-faint statt --ink-muted: in pkm/philosophie/garten auf AA (>= 4,5:1)
     auf der erhöhten Fläche (--paper-raised) getunt; --ink-muted unterschritt
     dort den Kontrast (PKM 4,39:1, Garten 3,58:1). */
  color: var(--ink-faint);
}

.pdf-upload__files {
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.pdf-upload__files li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--rule-soft);
}

.pdf-upload__files li:last-child { border-bottom: none; }

.pdf-upload__files .name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pdf-upload__files .size {
  flex: none;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.pdf-upload__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 1.2rem;
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
}

.pdf-upload__opt {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
  cursor: pointer;
}

@media (max-width: 40rem) {
  .pdf-dropzone { flex-direction: column; text-align: center; }
  .pdf-upload__foot { flex-direction: column; align-items: stretch; }
  .pdf-upload__foot .btn { width: 100%; }
}

.ingest-log {
  margin: 0.75rem 0 0;
  padding: 0.75rem 1rem;
  background: var(--ink);
  color: #d4cfca;
  border-radius: 6px;
  font-family: ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
  font-size: 0.7rem;
  line-height: 1.55;
  max-height: 280px;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

/* ——— Einstellungen ————————————————————— */

.settings-saved {
  background: var(--sage-wash);
  color: var(--sage-deep);
  border: 1px solid var(--sage-light);
  border-radius: 6px;
  padding: 0.5rem 1rem;
  font-size: 0.88rem;
  margin-bottom: 1.5rem;
}

.settings-form { display: flex; flex-direction: column; gap: 0; }

.settings-section {
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--rule);
}

.settings-section h2 {
  font-family: var(--serif);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--ink-muted);
  margin: 0 0 1.2rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-bottom: 1rem;
}

.field:last-child { margin-bottom: 0; }

.field label {
  font-size: 0.88rem;
  font-weight: 500;
  color: var(--ink-soft);
}

.field input[type="text"],
.field input[type="number"],
.field select {
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 0.4rem 0.65rem;
  font-family: var(--serif);
  font-size: 0.9rem;
  background: var(--paper-raised);
  color: var(--ink);
  max-width: 28rem;
}

.field input[type="number"] { max-width: 6rem; }

.field input:focus,
.field select:focus {
  outline: 2px solid var(--sage);
  outline-offset: 1px;
  border-color: transparent;
}

.field-hint {
  font-size: 0.78rem;
  color: var(--ink-muted);
  margin: 0;
}

.field-hint-inline {
  font-size: 0.78rem;
  color: var(--ink-muted);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

.review-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: 0.85rem 2rem;
}

.review-grid .field { margin-bottom: 0; }

.review-grid input[type="number"] { max-width: 5rem; }

.ri-hint {
  font-size: 0.75rem;
  color: var(--ink-faint);
}

.settings-actions {
  padding: 1.5rem 0 0;
}

.cost-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.cost-card {
  padding: 0.75rem 1rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--bg-soft, transparent);
}

.cost-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
}

.cost-value {
  font-family: var(--serif);
  font-size: 1.4rem;
  margin: 0.25rem 0;
}

.cost-meta {
  font-size: 0.75rem;
  color: var(--ink-faint);
}

.cost-breakdown {
  width: 100%;
  border-collapse: collapse;
  margin: 0.5rem 0 1rem;
  font-size: 0.85rem;
}

.cost-breakdown th,
.cost-breakdown td {
  text-align: left;
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--rule);
}

.cost-breakdown th {
  font-weight: normal;
  color: var(--ink-faint);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.cost-range-form {
  display: flex;
  align-items: end;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 0.75rem;
}

.cost-range-form .field { margin-bottom: 0; }

.cost-range-result { margin-top: 0.75rem; }

.tools-section { border-bottom: none; }

/* Kompakte, gleichförmige Werkzeug-Zeile (Wartung): Name + Kurzbeschreibung
   links, Aktionsknopf rechts, vertikal mittig; dezente Trennlinie zwischen
   den Zeilen statt einzelner <hr>/Abstands-Inlinestyles. */
.toolrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--rule);
}

.toolrow:last-child { border-bottom: none; }

.toolrow-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1;
  min-width: 0;
}

.toolrow-text b { font-size: 0.9rem; font-weight: 600; color: var(--ink); }

.toolrow-text small {
  font-size: 0.78rem;
  color: var(--ink-muted);
  line-height: 1.4;
}

.toolrow .btn { flex-shrink: 0; }

/* ——— Responsive ———————————————————————— */

@media (max-width: 600px) {
  html { font-size: 106.25%; }   /* 17px-Äquivalent; ganzes UI skaliert proportional */
  .item-foot { align-items: flex-start; flex-direction: column; gap: 0.7rem; }
  .column { padding: 2rem var(--gutter) 3.5rem; }
  h1.title { font-size: 2rem; }
  article p.lede::first-letter { font-size: 3.4rem; }
  .toolrow { flex-direction: column; align-items: flex-start; gap: 0.5rem; }

  /* Sidebar wird zum Off-Canvas-Drawer: außerhalb des Bildschirms per
     transform, öffnet über html.side-open (siehe _layout.html-Script).
     visibility (mit transition-delay) zusätzlich zu transform: ein reiner
     transform-Slide verschiebt nur die Optik, die Links/Buttons bleiben
     unsichtbar per Tab erreichbar. visibility:hidden nimmt sie aus der
     Tab-Reihenfolge, der delay lässt die Slide-Animation beim Öffnen/Schließen
     trotzdem sichtbar ablaufen (sofort sichtbar beim Öffnen, erst nach der
     Animation unsichtbar beim Schließen). */
  .side {
    width: 280px;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 200ms ease, visibility 0s linear 200ms;
    box-shadow: 12px 0 32px -18px rgba(31, 26, 23, 0.35);
  }

  html.side-open .side {
    transform: translateX(0);
    visibility: visible;
    transition: transform 200ms ease, visibility 0s linear 0s;
  }
  html.side-open .scrim { display: block; }

  /* Einklappen ist ein Desktop-Konzept, mobil gilt nur der Drawer. */
  .side-toggle { display: none; }

  /* Sidebar liegt als Overlay über dem Inhalt, reserviert keinen Platz mehr. */
  .app-main { margin-left: 0; }

  .topbar {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    position: sticky;
    top: 0;
    z-index: 30;
    background: var(--paper);
    border-bottom: 1px solid var(--rule);
    padding: 0.65rem 0.9rem;
  }

  .topbar-burger,
  .topbar-newchat {
    display: inline-flex;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--ink-soft);
    padding: 0.2rem;
    line-height: 0;
    text-decoration: none;
  }

  .topbar-brand {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--display);
    font-variation-settings: "opsz" 36, "wght" 480, "SOFT" 30;
    font-size: 0.95rem;
    color: var(--ink);
    text-decoration: none;
  }

  .topbar-brand span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .topbar-brand .sprig { width: 20px; height: 20px; color: var(--sage); flex-shrink: 0; }
  .topbar-brand em { font-style: italic; color: var(--sage-deep); }
}

@media (min-width: 900px) {
  .column { padding: 4.5rem var(--gutter) 6rem; }
}

/* ——— Log-Viewer ————————————————————— */

.log-page-header {
  max-width: var(--measure);
  margin-left: auto;
  margin-right: auto;
}

.log-toolbar {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.log-search {
  flex: 1 1 14rem;
  min-width: 10rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper-raised);
  color: var(--ink);
  font-family: var(--serif);
  font-size: 0.85rem;
}

.log-level-select {
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper-raised);
  color: var(--ink);
  font-size: 0.85rem;
}

.log-count {
  font-size: 0.78rem;
  color: var(--ink-muted);
  white-space: nowrap;
}

.log-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--rule);
  border-radius: 6px;
  margin-top: 2rem;
}

.log-table {
  width: 100%;
  border-collapse: collapse;
  font-family: ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
  font-size: 0.72rem;
  line-height: 1.45;
}

.log-table thead th {
  background: var(--paper-raised);
  color: var(--ink-muted);
  font-family: var(--serif);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.4rem 0.65rem;
  text-align: left;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}

.log-table tbody tr {
  border-bottom: none;
}

.log-table tbody tr:nth-child(odd)  { background: var(--paper); }
.log-table tbody tr:nth-child(even) { background: var(--paper-raised); }

.log-table td {
  padding: 0.55rem 0.75rem;
  vertical-align: top;
  border-top: 1px solid var(--rule-soft);
}

.log-table tbody .log-row.log-error   { background: #fff0f0; }
.log-table tbody .log-row.log-warning { background: #fef9e7; }
.log-table tbody .log-row.log-debug   { color: var(--ink-muted); }

.level-badge {
  display: inline-block;
  padding: 0.1em 0.45em;
  border-radius: 3px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.level-error   { background: #fde8e8; color: #c0392b; }
.level-warning { background: #fef3cd; color: #7d5a00; }
.level-info    { background: var(--sage-wash); color: var(--sage-deep); }
.level-debug   { background: var(--rule-soft); color: var(--ink-muted); }

.col-ts     { white-space: nowrap; color: var(--ink-muted); width: 11rem; }
.col-level  { white-space: nowrap; width: 5.5rem; }
.col-logger { white-space: nowrap; color: var(--ink-muted); width: 9rem; }
.col-msg    { word-break: break-word; }

.exc-detail {
  margin-top: 0.3rem;
}

.exc-detail summary {
  cursor: pointer;
  color: var(--ink-muted);
  font-size: 0.7rem;
}

.exc-detail pre {
  margin: 0.3rem 0 0;
  padding: 0.5rem;
  background: var(--ink);
  color: #d4cfca;
  border-radius: 4px;
  font-size: 0.68rem;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

.log-msg-text {
  word-break: break-word;
  font-weight: 600;
}

.log-extras {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 0.15rem 1.5rem;
  margin-top: 0.5rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--rule-soft);
  font-family: ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
  font-size: 0.68rem;
}

.log-extra-pair {
  display: flex;
  gap: 0.4rem;
  align-items: baseline;
  overflow: hidden;
}

.log-extras dt {
  color: var(--ink-muted);
  white-space: nowrap;
  flex-shrink: 0;
}

.log-extras dd {
  margin: 0;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background 120ms ease;
  border-radius: 3px;
  padding: 0 0.2em;
}

.log-extras dd[data-copy]:hover {
  background: var(--sage-wash, rgba(0, 0, 0, 0.05));
}

.log-extras dd.copied {
  color: var(--sage, #4a7c59);
  font-weight: 500;
}

.log-footer {
  margin-top: 0.75rem;
  font-size: 0.8rem;
  color: var(--ink-muted);
}

/* Archivierte Seiten */

.banner-archiviert {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  background: var(--sage-wash);
  border-left: 3px solid var(--sage);
  padding: 0.75rem 1rem;
  margin-bottom: 2.5rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

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

.archiv-item {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--rule-soft);
}

.archiv-item:last-child { border-bottom: none; }

.archiv-item-title {
  font-family: var(--display);
  font-variation-settings: "opsz" 30, "wght" 420, "SOFT" 20;
  color: var(--ink);
  text-decoration: none;
  flex: 1;
}

.archiv-item-title:hover { color: var(--sage-deep); }

.archiv-item-meta {
  font-size: 0.8rem;
  color: var(--ink-muted);
  white-space: nowrap;
}

article a.wikilink.wikilink-archived {
  color: #C06420;
  border-bottom-color: #C06420;
}

article a.wikilink.wikilink-archived:hover {
  background: #fdf0e6;
  border-bottom-color: #C06420;
}

.wikilink-archived .archived-marker {
  font-size: 0.78em;
  opacity: 0.7;
}

.archived-chip {
  opacity: 0.7;
  font-style: italic;
}

.suche-archiv-opt {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-size: 0.9rem;
  color: var(--ink-soft);
  cursor: pointer;
}

/* ——— Suche: eigene Suchbox mit Lupe, getrennte Aktionszeile ——————
   Anders als .ask-form (Chat-Eingabebox) trägt hier .searchbox die
   Box-Optik (Rahmen/Hintergrund) direkt um das Eingabefeld; .search-actions
   liegt bewusst schlicht darunter statt in der Box, da sie nicht mehr Teil
   derselben ist. (Der Vergleich lautete bis LLM-207 auf die gepunktete
   Oberkante von .ask-actions — die Zeile gibt es im Chat nicht mehr, der
   Absende-Knopf sitzt dort jetzt im Feld.) */
.suche-form { margin: 2rem 0 0; }

.searchbox {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0.7rem 1rem;
}

.searchbox svg {
  width: 17px;
  height: 17px;
  color: var(--ink-muted);
  flex: none;
}

.searchbox input {
  flex: 1;
  border: none;
  background: transparent;
  outline: none;
  font-family: var(--display);
  font-size: 1.05rem;
  color: var(--ink);
  padding: 0;
  -webkit-appearance: none;
  appearance: none;
}

.searchbox input::placeholder {
  color: var(--ink-faint);
  font-style: italic;
}

.search-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 0.9rem;
}

/* ——— Such-Autocomplete (E6) ————————————— */

.suche-ac { position: relative; }

.suche-vorschlaege {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--paper-raised, var(--paper));
  border: 1px solid var(--rule);
  border-radius: 4px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
  list-style: none;
  margin: 0;
  padding: 0.3rem;
  max-height: 16rem;
  overflow-y: auto;
}

.suche-vorschlaege[hidden] { display: none; }

.suche-vorschlag {
  display: flex;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.4rem 0.6rem;
  cursor: pointer;
  border-radius: 6px;
}

.suche-vorschlag:hover,
.suche-vorschlag.is-active {
  background: var(--sage-wash);
  color: var(--sage-deep);
}

.suche-vorschlag-art {
  font-size: 0.78rem;
  color: var(--ink-soft);
  white-space: nowrap;
}

.suche-vorschlag:hover .suche-vorschlag-art,
.suche-vorschlag.is-active .suche-vorschlag-art {
  color: var(--sage-deep);
}

/* ——— Artikel-Bilder + Lightbox ————————— */

article img {
  max-width: 100%;
  height: auto;
  display: block;
  cursor: zoom-in;
  border-radius: 2px;
  margin: 1.2rem 0;
}

.lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(31, 26, 23, 0.92);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease;
  cursor: zoom-out;
}

.lightbox-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.lightbox-overlay img {
  max-width: 92vw;
  max-height: 92vh;
  object-fit: contain;
  border-radius: 2px;
  box-shadow: 0 8px 48px rgba(0, 0, 0, 0.5);
  cursor: zoom-out;
}

/* ——— Barrierefreiheit ———————————————————————
   Theme-übergreifend (alle Wikis): Skip-Link, sichtbarer Tastatur-Fokus,
   Reduced-Motion. Nutzt die --sage-Variablen des jeweils geladenen Themes. */

.skip-link {
  position: absolute;
  left: 0.5rem;
  top: -3.5rem;
  z-index: 1000;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--sage);
  border-radius: 4px;
  padding: 0.5em 0.9em;
  font-family: var(--display);
  font-size: 0.9rem;
  text-decoration: none;
  transition: top 120ms ease;
}

.skip-link:focus {
  top: 0.5rem;
  outline: 2px solid var(--sage);
  outline-offset: 2px;
}

/* Programmatischer Sprungfokus auf <main> braucht keinen Ring. */
main:focus {
  outline: none;
}

/* Globaler Tastatur-Fokus — gilt für alle interaktiven Elemente, die sonst
   keinen eigenen sichtbaren Fokus haben (Links, Buttons, Nav, Tabs). */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--sage);
  outline-offset: 2px;
  border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- TeX-Formeln (KaTeX) --- */
/* Vor dem Client-Rendering zeigen die Spans den rohen TeX-Quelltext (Fallback
   ohne JS); Display-Formeln stehen als Block, überbreite scrollen horizontal. */
.math-display {
  display: block;
  overflow-x: auto;
  overflow-y: hidden;
  padding: 0.2rem 0;
}

/* ===== Listenansichten: Projekte (LLM-157) und Katalog (LLM-175) =====
   Beide Seiten zeigen dieselbe Sache in zwei Darstellungen (Kachel/Tabelle)
   und teilen sich deshalb die Bausteine: .liste-fullwidth (Breite),
   .liste-toolbar + .ansicht-umschalter (Kopfzeile), .karten-grid/.karte
   (Kacheln), .liste-tabelle/.liste-zeile (Tabelle). Die Namen sind seit
   LLM-175 neutral — vorher trugen sie ein „projekt-"-Präfix, was beim zweiten
   Nutzer entweder zu einer Kopie derselben Regeln oder zu einem irreführenden
   Namen geführt hätte. Projekt- bzw. katalogspezifisch bleiben nur die
   Ergänzungen (Zeilenmenü dort, Sektions-Chip hier). */

/* Steuerzone: Umschalter samt Filter und (im Katalog) die Kategorie-Chips
   gehören zusammen — sie steuern alle dieselbe Liste. Vorher standen Kopfzeile,
   „Zuletzt ingestiert", Toolbar, Chips und Liste in fast gleichem Abstand
   (2,4 / 1,5 / 1,6 / 1,6rem); bei gleichmäßigen Abständen kann das Auge nicht
   erkennen, was zusammengehört, und alles wirkt gedrängt. Jetzt: innen eng
   (gap), außen Luft, und eine Haarlinie schließt die Zone gegen die Liste ab.
   Auf der Projektübersicht enthält die Zone nur die Toolbar — dieselbe Regel
   trägt beide Fälle. */
.liste-steuerung {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin: 0 0 1.9rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid var(--rule-soft);
}

/* Die Kinder bringen eigene Außenabstände mit (sie stehen auch außerhalb der
   Zone); hier zählt allein der gap. */
.liste-steuerung > * { margin-bottom: 0; }

.liste-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0 0 1.6rem;
}

/* Umschalter und (in der Projektübersicht) „Neues Projekt" bilden die linke
   Gruppe, damit rechts in BEIDEN Übersichten dasselbe steht: der Textfilter
   (LLM-176). Der Abstand ist größer als der Gruppen-Innenabstand von
   .ansicht-umschalter, damit der Knopf nicht wie dessen dritter Reiter wirkt. */
.liste-toolbar-links {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  flex-wrap: wrap;
}

/* ——— Textfilter der Übersichten (LLM-176) ——— */

/* Allgemeine Hilfsklasse: sichtbar für Screenreader, unsichtbar am Schirm.
   Dasselbe Rezept steckt bisher zweimal inline im Stylesheet (eingeklappte
   Sidebar, Datei-Input der PDF-Dropzone); neue Stellen nutzen diese Klasse. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.liste-filter {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.liste-filter input[type="search"] {
  width: min(18rem, 60vw);
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper-raised);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.85rem;
}

.liste-filter input[type="search"]::placeholder { color: var(--ink-faint); }

.liste-filter input[type="search"]:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 1px;
}

/* Nur ohne JavaScript sichtbar: das Skript blendet ihn beim Start aus, weil
   dann das Tippen filtert. */
.liste-filter-los {
  padding: 0.35rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper-raised);
  color: var(--ink-soft);
  font-family: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

/* Sitzt IN der Filterzeile links vom Feld (LLM-176): Als eigene Zeile darunter
   erschien sie erst beim Filtern und schob die ganze Liste nach unten. Die
   Filtergruppe ist rechtsbündig, also wächst sie nach links und das Eingabefeld
   bleibt an seinem Platz. nowrap, damit „12 von 72" nicht umbricht und die
   Zeilenhöhe verändert. */
.liste-filter-treffer {
  font-size: 0.8rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.liste-filter-leer {
  margin: 0 0 1.4rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

@media (max-width: 600px) {
  /* Auf schmalen Schirmen steht der Filter unter der linken Gruppe und nimmt
     die volle Breite – ein 18rem-Feld neben zwei Bedienelementen bräche um. */
  .liste-filter { width: 100%; }
  .liste-filter input[type="search"] { width: 100%; }
}

.ansicht-umschalter {
  display: inline-flex;
  border: 1px solid var(--rule);
  border-radius: 6px;
  overflow: hidden;
}

.ansicht-umschalter a {
  padding: 0.4rem 0.9rem;
  font-size: 0.82rem;
  text-decoration: none;
  /* --ink-faint statt --ink-muted, weil der Hintergrund die erhöhte Fläche
     ist: dort unterschreitet --ink-muted den AA-Kontrast (4,39:1 statt 4,5:1),
     --ink-faint ist in den Themes genau dafür getunt. Gleiche Begründung wie
     bei .pdf-dropzone__hint weiter oben; axe-Lauf 2026-07-25. */
  color: var(--ink-faint);
  background: var(--paper-raised);
}

.ansicht-umschalter a + a { border-left: 1px solid var(--rule); }

.ansicht-umschalter a[aria-current="true"] {
  background: var(--sage-wash);
  color: var(--sage-deep);
  font-weight: 600;
}

.ansicht-umschalter a:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: -2px;
}

/* ——— Breite beider Ansichten ——— */

/* Sechs Tabellenspalten (LLM-167) wie auch mehrere Kacheln je Reihe sprengen
   --measure (34rem) deutlich – dasselbe Mittel wie .column.ws-fullwidth/
   .column.graph-fullwidth (Unterseite gibt dem <main> über main_extra eine
   zusätzliche Klasse), hier aber nur max-width statt Vollbreiten-Ausbruch:
   die Seite bleibt zentriert, nur breiter. Bewusst für BEIDE Ansichten, sonst
   springt beim Umschalten auch der Kopf, der in beiden derselbe ist. */
.column.liste-fullwidth {
  max-width: calc(var(--measure) * 2.2);
}

/* Kicker, Titel und der einleitende Absatz sollen trotzdem Lesebreite
   behalten, sonst läuft der Fließtext über 1000px – nur Toolbar, Tabelle und
   Kachelgitter sollen die neue Breite ausnutzen. Scoped auf
   .liste-fullwidth, damit keine andere Seite mit
   .kicker/h1.title/.meta betroffen ist. */
.column.liste-fullwidth .kicker,
.column.liste-fullwidth h1.title,
.column.liste-fullwidth .meta {
  max-width: var(--measure);
}

/* ——— Kachelansicht ——— */

/* Mindestbreite und Innenabstand je +15% gegenüber dem ersten Entwurf
   (16rem/1.1rem 1.2rem): In der schmalen Lesespalte passten nur zwei Kacheln
   nebeneinander, in der jetzt vollen Breite sind es vier – die Kacheln dürfen
   dabei nicht kleinteilig wirken (bei voller Breite 344px statt 303px).
   min(…, 100%) statt der nackten 18.4rem: Eine Mindestbreite größer als der
   Container zwingt die Spur trotzdem auf ihren Mindestwert und schiebt die
   Kachel seitlich aus dem Bildschirm – auf 320px-Geräten liegen 18.4rem
   (276px im pkm-Theme, 313px im garten-Theme) über der Inhaltsbreite von
   275px bzw. 269px. Der min()-Riegel deckelt die Spur auf den Container. */
.karten-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(18.4rem, 100%), 1fr));
  gap: 1.1rem;
}

.karte {
  position: relative;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper-raised);
  padding: 1.25rem 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.karte-link {
  text-decoration: none;
  color: var(--ink);
  border-radius: 3px;
}

.karte-link:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}

/* Reserviert Platz rechts, damit der Titeltext nicht unter das absolut
   positionierte Menü läuft – das Menü liegt oben rechts über der Titelzeile
   (.karte-menue, LLM-167). */
.karte-titel {
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  margin: 0;
  padding-right: 2rem;
}

/* Vier Zeilen Deckel (LLM-175): Die Katalog-Beschreibungen kommen aus
   index.md und reichen von einem Halbsatz bis zu mehreren Sätzen. Ungedeckelt
   bestimmt die längste Beschreibung die Höhe der GANZEN Gitterreihe, und
   daneben stehen drei fast leere Kacheln. Der volle Text steht weiterhin in
   der Tabellenansicht (title-Attribut) und auf der Seite selbst.
   Projektbeschreibungen sind kurz — dort ändert der Deckel nichts. */
.karte-beschreibung {
  color: var(--ink-soft);
  font-size: 0.9rem;
  margin: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}

/* `margin-top: auto` statt eines festen Abstands (LLM-175): Die Kacheln einer
   Gitterreihe sind gleich hoch, ihre Inhalte aber unterschiedlich lang — ohne
   das Auto-Maß hinge der Fuß (Kategorie bzw. Zähler/Datum) bei kurzen Kacheln
   in der Mitte, bei langen unten. So sitzt er in jeder Kachel auf gleicher
   Höhe. Gilt für beide Listenseiten. */
.karte-fuss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: 0.4rem;
}

/* --ink-faint: die Karte liegt auf --paper-raised, siehe .ansicht-umschalter a. */
.karte-datum {
  font-size: 0.76rem;
  color: var(--ink-faint);
}

/* Verankert das Menü der Kachel oben rechts (Vorbild: .liste-zeile-menue in
   der Tabelle – dort übernimmt die <td> die Positionierung, hier übernimmt
   dieser Wrapper dieselbe Rolle, LLM-167). */
.karte-menue {
  position: absolute;
  top: 1rem;
  right: 1rem;
}

/* ——— Tabellenansicht ——— */

/* Bildlauf-Rahmen der Tabellenansicht. Bewusst NICHT durchgehend
   `overflow-x: auto` (so stand es als Inline-Style im Template): Sobald eine
   Achse einen anderen Wert als `visible` trägt, zieht die CSS-Overflow-
   Spezifikation die andere Achse auf `auto` nach – der Container klippt dann
   auch nach unten und schneidet das aufgeklappte Zeilen-Menü ab
   (.liste-zeile-aktionen, position:absolute), sichtbar als plötzlicher
   senkrechter Scrollbalken neben einem halben Menü. Auf Breiten, wo die
   Tabelle ohnehin passt, gibt es also gar nichts zu scrollen und `visible`
   ist richtig; erst darunter braucht es den waagerechten Bildlauf, und dort
   ist das Menü der seltenere Fall. */
.liste-tabelle-wrap { overflow: visible; }

@media (max-width: 600px) {
  .liste-tabelle-wrap { overflow-x: auto; }
}

.liste-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.liste-tabelle th {
  text-align: left;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--rule);
}

.liste-tabelle td {
  padding: 0.6rem 0.7rem;
  border-bottom: 1px solid var(--rule-soft);
}

.liste-zeile { cursor: pointer; }
.liste-zeile:hover { background: var(--sage-wash); }

/* Der Titel-Link trägt die Tastatur-/No-JS-Navigation der Zeile; er soll sich
   optisch aber wie Zellentext lesen, nicht wie ein Fließtext-Link. */
.liste-zeile-link {
  color: var(--ink);
  text-decoration: none;
  font-weight: 600;
}

.liste-zeile-link:hover { color: var(--sage-deep); }

.liste-zeile-link:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
  border-radius: 3px;
}

/* Einzeilig mit Ellipse plus title-Attribut für den vollen Text – dasselbe
   Muster wie .projekt-kopf-beschreibung in projekte_workspace.html, nur ohne
   deren Flex-spezifisches flex:1/min-width:0 (hier ein <td>, kein Flex-Kind).
   max-width erzwingt die Kappung: ohne festen Wert würde die Spalte im
   Auto-Table-Layout einfach so breit wie der Text (LLM-167). */
.liste-zeile-beschreibung {
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.liste-zeile-menue { position: relative; text-align: right; }

/* Beide Ansichten sollen exakt dasselbe Icon-Erscheinungsbild haben, ohne
   CSS zu duplizieren – die vier Regeln dieses Blocks gelten deshalb für
   beide Menü-Wrapper (LLM-167). */
.liste-zeile-menue summary,
.karte-menue summary {
  cursor: pointer;
  list-style: none;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  color: var(--ink-faint);
}

.liste-zeile-menue summary::-webkit-details-marker,
.karte-menue summary::-webkit-details-marker { display: none; }

.liste-zeile-menue summary:hover,
.karte-menue summary:hover { background: var(--rule-soft); }

.liste-zeile-menue summary:focus-visible,
.karte-menue summary:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}

.liste-zeile-aktionen {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 5;
  display: flex;
  flex-direction: column;
  min-width: 9rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper-raised);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
  overflow: hidden;
}

.liste-zeile-aktionen button,
.liste-zeile-aktionen form button {
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.8rem;
  border: none;
  background: none;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}

.liste-zeile-aktionen button:hover { background: var(--sage-wash); }

/* ——— Katalog: Kategorie als Filter und Chip (LLM-175) ——— */

/* Die Filterzeile ersetzt das frühere Sektions-Akkordeon: Sie zeigt dieselbe
   Übersicht (alle Kategorien mit Zähler), ist aber immer sichtbar statt nur
   im zugeklappten Zustand — und sie filtert, was das Akkordeon nie konnte.
   Bewusst Links statt JS-Umschalter: ohne JavaScript bedienbar, verlinkbar,
   und der Server filtert ohnehin. */
.sektions-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 1.6rem;
}

.sektions-filter a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: 0.8rem;
  text-decoration: none;
  /* --ink-faint statt --ink-muted: der Chip liegt auf --paper-raised, dort
     unterschreitet --ink-muted den AA-Kontrast (gleiche Begründung wie bei
     .ansicht-umschalter a). */
  color: var(--ink-faint);
  background: var(--paper-raised);
}

.sektions-filter a:hover { color: var(--sage-deep); border-color: var(--sage-light); }

.sektions-filter a[aria-current="true"] {
  background: var(--sage-wash);
  border-color: var(--sage-light);
  color: var(--sage-deep);
  font-weight: 600;
}

.sektions-filter a:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}

.sektions-filter-zahl { font-variant-numeric: tabular-nums; opacity: 0.8; }

/* Der Chip an Kachel und Tabellenzeile trägt dieselbe Kategorie wie die
   Filterzeile und führt auf denselben Filter — die Kategorie ist damit
   überall dasselbe Ding, egal wo man sie anfasst. */
.sektions-chip {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--sage-wash);
  color: var(--sage-deep);
  font-size: 0.74rem;
  text-decoration: none;
  /* Ohne nowrap bricht „Sicherheit & Datenschutz" in der Tabellenspalte um und
     die Pille wird zum zweizeiligen Klotz; die Spalte hat die Breite dafür. */
  white-space: nowrap;
}

.sektions-chip:hover { background: var(--sage-light); color: var(--paper); }

.sektions-chip:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}

/* Sortierbare Spaltenköpfe: Der Pfeil erscheint erst, wenn JavaScript die
   Sortierung übernommen hat (aria-sort wird dann von "none" weggesetzt) —
   ohne JS zeigt der Kopf keinen Hinweis auf eine Funktion, die es nicht gibt. */
/* Die Projekttabelle deckelt die Beschreibung auf 22rem, weil dort fünf
   weitere Spalten daneben stehen. Der Katalog hat drei Spalten und damit Platz
   — ohne eigenen Deckel bliebe die Beschreibung grundlos beschnitten. */
.katalog-tabelle .liste-zeile-beschreibung { max-width: 36rem; }

.katalog-tabelle th[data-sort] { cursor: pointer; user-select: none; }

.katalog-tabelle th[data-sort]:hover { color: var(--sage-deep); }

.katalog-tabelle th[aria-sort="ascending"]::after { content: " ↑"; }
.katalog-tabelle th[aria-sort="descending"]::after { content: " ↓"; }

.katalog-tabelle th[data-sort]:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: -2px;
}

/* ——— Dialoge (Anlegen/Umbenennen/Picker) ——— */

/* Gedämpfter Text IM Dialog trägt --ink-soft statt --ink-faint: der Dialog
   liegt auf --paper, wo selbst der AA-getunte Meta-Ton knapp reißt (garten
   4,31:1). Betrifft Feldbeschriftungen, Reiter, Vorschauzahlen, Slug-Zusatz. */

.projekt-dialog {
  width: min(30rem, 92vw);
  padding: 1.4rem 1.5rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28);
}

.projekt-dialog::backdrop { background: rgba(0, 0, 0, 0.5); }

.projekt-dialog h2 {
  margin: 0 0 0.9rem;
  font-family: var(--display);
  font-size: 1.2rem;
}

.projekt-dialog form {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.projekt-dialog label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-top: 0.5rem;
}

.projekt-dialog input[type="text"],
.projekt-dialog textarea,
.projekt-dialog select {
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 0.45rem 0.65rem;
  font-family: var(--serif);
  font-size: 0.95rem;
  background: var(--paper-raised);
  color: var(--ink);
}

.projekt-dialog-aktionen {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
  margin-top: 1rem;
}

/* ——— Picker (vier Reiter) ——— */

.projekt-picker-dialog { width: min(34rem, 92vw); }

.projekt-picker-tabs {
  display: flex;
  gap: 0.3rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--rule);
}

.projekt-picker-tabs [role="tab"] {
  border: none;
  background: none;
  font: inherit;
  font-size: 0.85rem;
  padding: 0.5rem 0.8rem;
  color: var(--ink-soft);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.projekt-picker-tabs [role="tab"][aria-selected="true"] {
  color: var(--sage-deep);
  border-bottom-color: var(--sage-deep);
  font-weight: 600;
}

.projekt-picker-tabs [role="tab"]:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}

.projekt-picker-auswahl,
.projekt-picker-vorschau {
  font-size: 0.82rem;
  color: var(--ink-soft);
  margin: 0.3rem 0;
}

.projekt-picker-seitenliste {
  list-style: none;
  margin: 0.4rem 0;
  padding: 0;
  max-height: 14rem;
  overflow-y: auto;
  border: 1px solid var(--rule-soft);
  border-radius: 6px;
}

.projekt-picker-seite {
  padding: 0.35rem 0.7rem;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 0.88rem;
}

.projekt-picker-seite:last-child { border-bottom: none; }

.projekt-picker-seite label { display: flex; align-items: flex-start; gap: 0.5rem; text-transform: none; letter-spacing: normal; color: var(--ink); font-size: inherit; margin: 0; }

.projekt-picker-seite input[type="checkbox"] { flex: none; margin-top: 0.2rem; }

.projekt-picker-seite-text { flex: 1; }

.projekt-picker-slug { color: var(--ink-soft); font-size: 0.78rem; }

/* ——— Workspace (dreispaltig: Quellen · Chat · Studio) ——— */

/* --ink-soft: --ink-faint erreicht auf --paper im Garten-Theme nur 4,31:1.
   Das gilt dort für JEDE --ink-faint-Fläche auf Papier, nicht nur hier – der
   Zielwert steht so im Theme-Kommentar, wird aber knapp verfehlt; siehe
   .projekt-regel-anzahl. Diese Klasse wird nur vom Workspace benutzt. */
.projekt-zurueck {
  display: inline-block;
  margin-bottom: 1rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
  text-decoration: none;
}

.projekt-zurueck:hover { color: var(--sage-deep); }

/* Kompakte einzeilige Kopfleiste des Workspace: Zurück-Link, Titel,
   Beschreibung und Umbenennen nebeneinander statt gestapelt. Die frühere
   gestapelte Variante (.projekt-workspace-kopf) ist damit entfallen. */
.projekt-kopfzeile {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  flex-wrap: wrap;
}

/* Hebt das margin-bottom der allgemeinen .projekt-zurueck-Regel auf – in der
   einzeiligen Leiste würde es die Grundlinien auseinanderziehen. */
.projekt-kopfzeile .projekt-zurueck {
  margin-bottom: 0;
  white-space: nowrap;
}

.projekt-titel {
  font-family: var(--display);
  font-variation-settings: "opsz" 40, "wght" 420, "SOFT" 20;
  font-size: 1.35rem;
  line-height: 1.2;
  letter-spacing: -0.015em;
  margin: 0;
  color: var(--ink);
  /* KEIN white-space:nowrap (stand hier bis zur Messung unten): Der Titel ist
     der einzige Teil der Kopfzeile, dessen Länge der Nutzer frei bestimmt –
     `_NAME_MAX_LEN` in projects.py erlaubt 120 Zeichen. Mit nowrap wuchs er
     einfach weiter und schob die ganze Seite über die Fensterkante, und zwar
     auf JEDER Breite: gemessen 1386px Seitenbreite bei 901px Fenster
     (Titelbreite allein 1104px), auf Telefonbreite schon ab knapp 50 Zeichen
     (441px bei 375px Fenster). Deshalb kein Breakpoint – die Kopfzeile ist
     ohnehin `flex-wrap: wrap`, der Titel brach als einziges Kind nicht mit um.

     Umbrechen statt kappen: Anders als bei .projekt-kopf-beschreibung (Ellipse
     + title-Attribut) ist der Name die Identität der Seite; „Wissensbasis fuer
     die redaktio…“ nimmt sie weg, zwei Zeilen kosten nur Höhe. Solange Platz
     ist, ändert sich nichts – bei 48 Zeichen auf 901px und 1280px sind
     Titelbreite, Zeilenhöhe und Nachbarpositionen unverändert (gemessen).

     `anywhere` statt `break-word`: Nur `anywhere` senkt auch die
     Inhaltsmindestbreite, das Flex-Kind darf also wirklich schrumpfen – bei
     `break-word` bliebe ein einzelner überlanger Name (ein Wort ohne
     Leerzeichen) weiterhin ein starrer Block. Gleiche Wahl und gleicher Grund
     wie bei .lernhilfe-beleg a. */
  overflow-wrap: anywhere;
}

.projekt-titel em {
  font-style: italic;
  font-variation-settings: "opsz" 40, "wght" 400, "SOFT" 100, "WONK" 1;
  color: var(--sage-deep);
}

/* Nimmt den Rest der Zeile und schneidet ab, statt umzubrechen – der volle
   Text steht im title-Attribut (s. Template). min-width:0 ist nötig, sonst
   ignoriert ein Flex-Kind das text-overflow und dehnt die Zeile. */
.projekt-kopf-beschreibung {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-family: var(--serif);
  font-size: 0.8rem;
  color: var(--ink-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Ohne Beschreibung fehlt das dehnende Flex-Kind – dann schiebt der Knopf
   sich selbst an den rechten Rand. */
.projekt-kopfzeile .btn-ghost { margin-left: auto; }

/* Der Workspace ist die einzige Ansicht, die den Inhaltsbereich VOLLSTÄNDIG
   ausfüllt – randlos bis an Fensterkante und -boden, direkt anschließend an
   die Sidebar. Begründung: Es ist eine dichte Arbeitsfläche aus drei
   Spalten; ein zentrierter Kasten mit Weißraum ringsum verschenkt auf
   Laptop-Schirmen genau die Fläche, die die Spalten brauchen, und erzeugt
   nebenbei einen zweiten Bildlauf (Seite UND Spalte).

   .column bringt für Lesetexte eine Breitenbegrenzung und Ränder mit; beides
   wird hier abgeräumt und in die Kopfzone verlegt, die als einzige noch
   Seitenrand trägt. Die Flex-Spalte ersetzt zugleich jede geratene
   Höhenformel: die Kopfzone nimmt, was sie braucht, das Gitter exakt den
   Rest – unabhängig davon, ob eine Projektbeschreibung oder eine
   Flash-Meldung darübersteht. */
.column.ws-fullwidth {
  max-width: none;
  padding: 0;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

.projekt-kopfzone {
  flex: none;
  padding: 0.75rem var(--gutter);
}

@media (max-width: 900px) {
  /* Einspaltig gestapelt braucht die Seite mehr als die Fensterhöhe – hier
     scrollt wieder das Dokument, nicht die einzelne Spalte. */
  .column.ws-fullwidth {
    height: auto;
    display: block;
  }
}

/* Die drei Spalten sind EINE zusammenhängende Fläche mit Trennlinien, keine
   drei gerundeten Einzelkarten (Vorbild: das Flow-Mockup zum
   Projekte-Konzept). Kein Rahmen und kein Radius außen herum: das Gitter
   grenzt links an die Sidebar, rechts an die Fensterkante und unten an den
   Fensterboden – gerundete Ecken bräuchten dort einen Rand, der genau den
   Platz kostet, um den es geht. Bleibt die Linie nach oben, die es vom
   Seitenkopf trennt.

   Feste Außenspalten, flexible Mitte: der Chat ist die Arbeitsfläche und
   bekommt jeden zusätzlichen Pixel, Quellen- und Studio-Spalte behalten ihre
   Lesebreite. */
.ws-grid {
  display: grid;
  /* Die drei Spaltenbreiten stehen als Variablen statt als feste Werte im
     grid-template-columns: Einklappen heißt dann nur noch, --ws-links bzw.
     --ws-rechts auf --ws-leiste zu setzen (s. „Außenspalten einklappen“
     weiter unten), und ein späteres Ziehen der Breiten griffe auf dieselbe
     Variable. Ohne diesen Zwischenschritt entstünden zwei konkurrierende
     Mechanismen für dieselbe Größe. */
  /* Quellen-Spalte wächst stufenlos mit dem Fenster statt fest zu stehen
     (LLM-207). Das Platzbudget erzwingt es: Die Sidebar belegt 258px, das
     Studio 300px — bei 1440px Fensterbreite bleiben der Mitte damit 632px,
     also GENAU ihre Lesebreite. Ein fester Zuwachs auf 300px ginge deshalb
     unmittelbar von der Mitte ab und drückte den Chat auf einem 1280px-Schirm
     unter seine Lesebreite. Gemessen an dieser Formel: 250px bis 1190px
     Fensterbreite (unverändert wie vorher), 302px bei 1440px (die
     gewünschten +20%), 360px ab 1715px.

     Die Untergrenze ist Teil der Entscheidung, nicht Vorsicht: ohne sie liefe
     die Spalte auf schmalen Fenstern unter ihre Lesbarkeit. */
  --ws-links: clamp(250px, 21vw, 360px);
  --ws-rechts: 300px;
  /* Breite der eingeklappten Leiste. In rem, damit sie mit einer vom Nutzer
     hochgesetzten Schriftgröße mitwächst (WCAG 1.4.4) – der Klapp-Knopf darin
     ist ein Icon-Knopf und würde bei fester px-Breite irgendwann anstoßen. */
  --ws-leiste: 2.6rem;
  grid-template-columns: var(--ws-links) 1fr var(--ws-rechts);
  /* Gleiche Bewegung wie beim Einklappen der Sidebar (.side). Der globale
     prefers-reduced-motion-Block am Dateiende schaltet sie mit ab. */
  transition: grid-template-columns 200ms ease;
  border-top: 1px solid var(--rule);
  /* Weiße Arbeitsfläche wie im Mockup: die Karten darin (Regeln, Artefakte,
     Studio-Kacheln, Lernhilfe) tragen dieselbe Fläche und heben sich allein
     durch ihre Rahmen ab. ACHTUNG bei Textfarben in diesen Panels –
     --paper ist in allen drei Themes DUNKLER als --paper-raised, die
     Kontraste sind hier also knapper als auf einer abgesetzten Fläche. */
  background: var(--paper);
  /* Nimmt exakt die Resthöhe unter der Kopfzone – alle drei Spalten damit
     gleich hoch, jede scrollt für sich (s. .ws-panel-koerper). Ohne
     min-height:0 würde ein Flex-Kind nicht unter seine Inhaltshöhe
     schrumpfen und das Gitter über den Fensterboden hinausschieben. */
  flex: 1;
  min-height: 0;
}

/* Ohne Studio-Panel (`lernhilfen_enabled: false`) rendert das Template nur
   zwei Panels – dann darf das Gitter auch nur zwei Spuren haben, sonst steht
   rechts eine leere Spalte, die der Mitte fehlt.

   Bewusst über grid-template-columns statt über `--ws-rechts: 0`: die
   Klapp-Regeln weiter unten setzen genau diese Variable, und ein aus einer
   früheren Sitzung gemerktes `ws-rechts-zu` gewänne dort über die
   Spezifität – die leere Spur wäre wieder da, nur schmaler. Eine fehlende
   Spur kann keine Variable zurückholen. --ws-links bleibt unangetastet (die
   Quellen-Spalte klappt weiter und ließe sich später ziehen), --ws-rechts hat
   in diesem Zustand schlicht keine Spalte mehr.

   Steht vor dem gestapelten Breakpoint: dort gewinnt die einspaltige Regel
   bei gleicher Spezifität über die Quellreihenfolge. */
.ws-grid-ohne-rechts {
  grid-template-columns: var(--ws-links) 1fr;
}

@media (max-width: 900px) {
  .ws-grid {
    grid-template-columns: 1fr;
    /* Einspaltig gestapelt ergibt eine gemeinsame Höhe keinen Sinn – die
       Panels wachsen mit ihrem Inhalt, die Seite scrollt als Ganzes. */
    flex: none;
  }

  /* Gestapelt kommt auf /fragen der Chat ZUERST (LLM-207, Etappe 2): Die
     Seite ist die Startseite des Wikis, und in Dokumentreihenfolge stünde
     sonst die Quellenspalte davor — wer die Seite öffnet, landete zuerst bei
     einer Liste (im leeren Zustand: bei deren Erklärungstext) und müsste
     daran vorbeiscrollen, um überhaupt fragen zu können.

     Nur für den Chat, nicht für den Projekt-Workspace: Dort ist die
     Quellenliste die Arbeitsgrundlage, die man beim Betreten zuerst prüft,
     und die Reihenfolge ist Bestand. */
  .ws-panel-chat-fragen { order: -1; }
}

.ws-panel {
  display: flex;
  flex-direction: column;
  /* Ohne min-height:0 wächst ein Flex-Element über seinen Inhalt hinaus,
     statt den Kind-Container scrollen zu lassen (Flexbox-Default
     min-height:auto) – der Panel-Körper bekäme dann nie eine Scroll-Grenze. */
  min-height: 0;
  /* Dasselbe Argument für die Waagerechte, hier aber als GITTER-Element: die
     automatische Mindestgröße (min-width:auto) hält ein Grid-Element auf
     seiner Inhaltsmindestbreite – es überläuft dann seine Spur, statt zu
     schrumpfen. Bei großer Wurzelschrift (Browser-Schriftgröße „sehr groß“,
     ab etwa 22px) schob das den ganzen Workspace über die Fensterkante:
     gemessen 419px Panelbreite bei 375px Viewport, also ein waagerechter
     Bildlauf der GESAMTEN Seite auf Telefonbreite. Mit min-width:0 schrumpft
     das Panel mit und der Überlauf landet dort, wo ihn der Entwurf erwartet –
     im Scroll-Container der Spalte (.ws-panel-koerper).

     `minmax(0, 1fr)` auf der Spur allein genügt NICHT (gemessen): dann
     schrumpft zwar die Spur, das Element mit min-width:auto überläuft sie
     trotzdem. Die Regel gilt deshalb für BEIDE Breakpoints – auf dem Desktop
     stehen zwar feste Spurbreiten (250px/300px), die automatische
     Mindestgröße greift dort aber genauso. */
  min-width: 0;
  border-right: 1px solid var(--rule);
}

.ws-panel:last-child { border-right: 0; }

@media (max-width: 900px) {
  /* Senkrechte Trennlinien stünden im gestapelten Fluss quer. */
  .ws-panel {
    border-right: 0;
    border-bottom: 1px solid var(--rule);
  }
  .ws-panel:last-child { border-bottom: 0; }

  /* Gestapelt ist Klappen gegenstandslos (die Spalten stehen untereinander,
     es gibt keine Breite zu gewinnen) – der Knopf entfällt ganz. Die
     Klapp-Regeln selbst stehen in einer min-width-Abfrage und greifen hier
     ohnehin nicht, ein aus einer Desktop-Sitzung persistierter Zustand kann
     die gestapelte Darstellung also nicht verstellen. Gleiches Vorgehen wie
     beim Sidebar-Einklappen (s. .side-toggle im 600px-Query). */
  .ws-panel-klapp { display: none; }
}

/* ——— Außenspalten einklappen —————
   Quellen- und Studio-Spalte lassen sich auf eine schmale Leiste einklappen,
   die Mitte (Chat/Werkzeug) nimmt den frei werdenden Platz. Die Spalte
   verschwindet dabei NICHT ganz: Knopf und ein senkrechtes Rubrum bleiben
   stehen, sonst fehlte der Weg zurück.

   Nur außerhalb des gestapelten Breakpoints wirksam – exakt die Bauweise des
   Sidebar-Einklappens (@media (min-width: 601px) weiter oben): ein in einer
   Desktop-Sitzung gemerkter Klappzustand darf die gestapelte Darstellung auf
   dem Telefon nicht überschreiben. */
@media (min-width: 901px) {
  /* Öffnet man eine Quelle im Panel, verbreitert sich die Spalte für die
     Leseansicht (LLM-169, W3) — dieselbe Variable wie die Klapp-Regel
     darunter (Vertrag für ein späteres Ziehen der Breiten, LLM-170), kein
     zweiter Mechanismus für dieselbe Größe. Steht VOR der `ws-quellen-zu`-
     Regel: beide Selektoren haben dieselbe Spezifität (0,2,1), bei
     gleichzeitig gesetzten Klassen gewinnt über die Quellreihenfolge das
     Einklappen — die richtige Rangfolge, denn Einklappen ist die explizite,
     zuletzt getroffene Nutzerhandlung (das Klapp-Skript in
     projekte_workspace.html entfernt `ws-quellen-offen` beim Einklappen
     ohnehin aktiv, diese Reihenfolge ist also nur die zweite Absicherung).
     Kein fester Wert: 480px ließen der Chat-Mitte direkt am Breakpoint
     (901px) kaum Platz. Bis LLM-207 stand hier `min(480px, 38vw)` — also
     eine reine Obergrenze ohne Untergrenze, wodurch die Leseansicht auf
     schmalen Fenstern beliebig eng werden konnte.

     Die Werte sind nach dem ersten Praxiseinsatz gesenkt worden (34vw statt
     40vw, Deckel 560 statt 620): Auf einem 14-Zoll-MacBook (1512px) ergaben
     40vw eine 605px breite Leseansicht, und mit Sidebar (258px) und rechter
     Spalte (300px) blieben dem Chat GEMESSEN 349px — die Antwortblase war
     dann 285px breit, Überschriften brachen in Einzelwörter. Nichts lief
     technisch über, es war schlicht unbenutzbar. Zusammen mit dem
     automatischen Einklappen der rechten Spalte (s. _spalten_klapp.html)
     bleiben demselben Fenster jetzt rund 700px. */
  html.ws-quellen-offen .ws-grid { --ws-links: clamp(380px, 34vw, 560px); }

  html.ws-quellen-zu .ws-grid { --ws-links: var(--ws-leiste); }
  html.ws-rechts-zu .ws-grid { --ws-rechts: var(--ws-leiste); }

  /* Die Klapp-Regeln hängen an den POSITIONS-Markern `.ws-panel-links` und
     `.ws-panel-rechts`, nicht an den inhaltlichen Klassen (bis LLM-207:
     `.ws-panel-quellen` und `.ws-panel-studio`): Rechts steht im Workspace
     das Studio, auf /fragen die Gliederung — zwei verschiedene Inhalte an
     derselben Stelle. `:first-child`/`:last-child` wären der naheliegende
     Ersatz, greifen aber daneben, sobald die rechte Spur fehlt
     (`ws-grid-ohne-rechts`): Letztes Panel ist dann der Chat, und ein aus
     einer früheren Sitzung gemerktes `ws-rechts-zu` blendete dessen Körper
     aus. Ein expliziter Marker kann das nicht. */
  html.ws-quellen-zu .ws-panel-links .ws-panel-koerper,
  html.ws-rechts-zu .ws-panel-rechts .ws-panel-koerper { display: none; }

  /* Titel und Zähl-Badge weichen, der Knopf rückt in die Mitte der Leiste.
     Der Innenabstand des Kopfes (1rem seitlich) passt in 2,6rem nicht mehr –
     die Mindesthöhe bleibt unangetastet, damit die Trennlinie unter dem Kopf
     weiter mit den beiden anderen Spalten fluchtet. */
  html.ws-quellen-zu .ws-panel-links .ws-panel-kopf,
  html.ws-rechts-zu .ws-panel-rechts .ws-panel-kopf {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }

  html.ws-quellen-zu .ws-panel-links .ws-panel-kopf > h2,
  html.ws-quellen-zu .ws-panel-links .ws-panel-kopf > .ws-panel-zahl,
  html.ws-rechts-zu .ws-panel-rechts .ws-panel-kopf > h2,
  html.ws-rechts-zu .ws-panel-rechts .ws-panel-kopf > .ws-panel-zahl {
    display: none;
  }

  html.ws-quellen-zu .ws-panel-links .ws-panel-leiste,
  html.ws-rechts-zu .ws-panel-rechts .ws-panel-leiste {
    display: flex;
  }
}

/* Icon-Knopf im Spaltenkopf, im Stil von .side-toggle (dasselbe Panel-Icon,
   dieselbe Bedeutung). flex: none, damit ihn der Kopf nicht staucht. */
.ws-panel-klapp {
  flex: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.3rem;
  line-height: 0;
  border-radius: 4px;
  color: var(--ink-muted);
  transition: color 160ms ease, background 160ms ease;
}

/* --paper-raised statt --paper wie bei .side-toggle: die Panels stehen hier
   selbst auf --paper, ein Hover in derselben Farbe wäre unsichtbar. */
.ws-panel-klapp:hover {
  color: var(--ink);
  background: var(--paper-raised);
}

/* Inhalt der eingeklappten Leiste: Zähl-Badge über gestürztem Rubrum. Nur im
   eingeklappten Zustand eingeblendet (display:flex, s. oben) – die
   Voreinstellung `none` hier deckt zugleich den gestapelten Breakpoint unter
   900 px ab, wo die Klapp-Regeln gar nicht greifen.

   Das Badge ist der eigentliche Indikator: eingeklappt sagt allein die Zahl,
   ob in der Spalte etwas liegt (s. Begründung am Markup im Template). Es
   steht im DOM ein zweites Mal, weil der Spaltenkopf seine Mindesthöhe
   behalten muss, damit die Trennlinien der drei Spalten fluchten. */
.ws-panel-leiste {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  flex: none;
  padding-top: 0.7rem;
}

/* Senkrechtes Rubrum: sagt, WELCHE Spalte hier steckt. aria-hidden im
   Template – die <section> trägt ihr aria-label unverändert und der Knopf
   seinen eigenen Namen, vorgelesen wäre das die dritte Wiederholung desselben
   Wortes. Die Zahl daneben bleibt zugänglich, sonst wäre der Indikator
   sehend-exklusiv. */
.ws-panel-leiste-titel {
  writing-mode: vertical-rl;
  font-family: var(--display);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* --ink-soft: die Panels stehen auf --paper, dort verfehlen --ink-muted und
     --ink-faint im Garten-Theme AA (s. Kommentar bei .projekt-regel-anzahl). */
  color: var(--ink-soft);
  user-select: none;
}

/* Die Panels stehen auf --paper (weiße Arbeitsfläche). Dort verfehlen BEIDE
   naheliegenden Metatöne AA im Garten-Theme: --ink-muted von Haus aus und
   --ink-faint mit 4,31:1 knapp. Deshalb --ink-soft, wie bei
   .projekt-regel-anzahl. Nur hier überschrieben, die globale
   .empty-state-Regel bleibt unangetastet. */
.ws-panel .empty-state { color: var(--ink-soft); }

.ws-panel h2 {
  font-family: var(--display);
  font-size: 1.05rem;
  margin: 0;
}

/* Kopf bleibt beim Scrollen des Panel-Körpers stehen (flex: none) und trägt
   die Trennlinie nach unten.

   `min-height` samt `nowrap`: die drei Spaltenköpfe MÜSSEN exakt gleich hoch
   sein, sonst laufen ihre Trennlinien auf drei verschiedenen Höhen quer
   durchs Gitter. Deshalb steht hier eine feste Mindesthöhe statt eines
   umbrechenden Kopfes – Knöpfe, die daneben nicht mehr passen, gehören in
   den Panel-Körper (s. „Quelle hinzufügen“ im Template). */
.ws-panel-kopf {
  display: flex;
  flex: none;
  align-items: center;
  flex-wrap: nowrap;
  min-height: 3.4rem;
  gap: 0.6rem;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid var(--rule);
}

/* Kopf-Knöpfe kompakt, damit sie die Kopfhöhe nicht aufblähen. */
.ws-panel-kopf .btn,
.ws-panel-kopf .btn-ghost {
  font-size: 0.75rem;
  padding: 0.3rem 0.7rem;
  white-space: nowrap;
}

.ws-panel-kopf h2 { margin: 0; }

/* Schiebt alles nach dem Zähl-Badge (den Knopf) an den rechten Rand. Steht
   auf dem Badge statt auf dem Knopf, weil nicht jeder Panel-Kopf einen Knopf
   hat (Studio) und nicht jeder ein Badge (Chat/Werkzeug). */
.ws-panel-kopf .ws-panel-zahl { margin-right: auto; }

/* --paper-raised: das Badge liegt auf der jetzt weißen Panel-Fläche und
   bräuchte sonst allein den Rahmen, um sich abzuheben (Mockup: .count auf
   --raised). */
.ws-panel-zahl {
  font-size: 0.7rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 99px;
  padding: 0.05em 0.55em;
}

/* Der eine Scroll-Container je Spalte. */
.ws-panel-koerper {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem;
}

.projekt-regelliste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.projekt-regel {
  border: 1px solid var(--rule-soft);
  border-radius: 6px;
  padding: 0.7rem 0.8rem;
}

.projekt-regel-kopf {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}

.projekt-regel-pill {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.1em 0.55em;
  border-radius: 99px;
  background: var(--rule-soft);
  /* --ink-soft, nicht --ink-faint: --rule-soft ist die dunkelste der hellen
     Flächen, dort reicht auch der AA-getunte Meta-Ton nicht (garten 3,87:1). */
  color: var(--ink-soft);
}

.projekt-regel-pill-statisch {
  background: var(--sage-wash);
  color: var(--sage-deep);
}

.projekt-regel-wert {
  font-size: 0.9rem;
  color: var(--ink);
  margin: 0 0 0.5rem;
  word-break: break-word;
}

/* Umbruch erlaubt: in der 250px-Spalte passen Seitenzahl, „Bearbeiten“ und
   „Entfernen“ nicht in eine Zeile – ohne wrap schöbe der Fuß die Spalte
   waagerecht auf (gemessen 274px Inhalt in 249px Spalte). */
.projekt-regel-fuss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.4rem 0.6rem;
}

.projekt-regel-aktionen {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

/* --ink-soft: seit die Panels auf --paper stehen (weiße Arbeitsfläche wie im
   Mockup) erreicht --ink-faint im Garten-Theme nur noch 4,31:1 und verfehlt
   AA. --ink-muted hilft dort NICHT – garten dreht die Reihenfolge um und
   setzt --ink-muted (#8A8175) heller als --ink-faint (#777163). */
.projekt-regel-anzahl {
  font-size: 0.8rem;
  color: var(--ink-soft);
}

/* Vollbreiten-Knopf über der Regelliste (Mockup `.addsrc`). */
.projekt-quelle-hinzufuegen {
  display: block;
  width: 100%;
  margin-bottom: 0.9rem;
  text-align: center;
}

.projekt-effektiv {
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
  font-size: 0.9rem;
}

/* --ink-soft, gleiche Begründung wie .projekt-regel-anzahl oben. */
.projekt-effektiv-hinweis {
  font-size: 0.78rem;
  color: var(--ink-soft);
  margin-top: 0.2rem;
}

.projekt-seitenliste {
  margin-top: 0.6rem;
  font-size: 0.85rem;
}

.projekt-seitenliste summary {
  cursor: pointer;
  color: var(--ink-soft);
}

.projekt-seitenliste summary:hover { color: var(--sage-deep); }

/* Bewusst OHNE eigenes max-height/overflow-y: der Panel-Körper ist der EINE
   Scroll-Container je Spalte (s. .ws-panel-koerper). Ein geschachtelter
   zweiter Scrollbalken erschien schon bei einer Handvoll Einträgen, während
   darunter die halbe Spalte leer stand. Lang wird die Liste nur, wenn der
   Nutzer sie selbst aufklappt – dann darf sie die Spalte füllen.

   Negativer Seitenrand: Trennlinien und Hover-Fläche greifen etwas über die
   Textkante hinaus, der Linktext selbst fluchtet dank des ausgleichenden
   Innenabstands am <a> weiter mit dem übrigen Panelinhalt. */
.projekt-seitenliste ul {
  list-style: none;
  margin: 0.5rem -0.45rem 0;
  padding: 0;
  border-top: 1px solid var(--rule);
}

/* Trennlinie je Eintrag: Wiki-Titel sind oft mehrzeilig (Haupttitel + Zusatz
   nach „ – “), ohne Linie verschwimmt das Ende des einen Links mit dem Anfang
   des nächsten. --rule statt --rule-soft, weil letzteres im PKM-Theme mit
   --paper-raised identisch ist und auf der weißen Panel-Fläche unsichtbar
   bliebe. */
.projekt-seitenliste li {
  border-bottom: 1px solid var(--rule);
}

.projekt-seitenliste li a {
  display: block;
  padding: 0.45rem;
  line-height: 1.35;
  color: var(--ink);
  /* Die durchgehende Unterstreichung war der zweite Grund für den verwischten
     Eindruck – über drei Zeilen gezogen liest sie sich als Fläche statt als
     Linkgrenze. In einer Liste, deren Einträge ausnahmslos Links sind, trägt
     die Zeile selbst die Affordanz (WCAG 1.4.1 zielt auf Links IM Fließtext);
     bei Hover und Tastaturfokus kehrt die Unterstreichung zurück. */
  text-decoration: none;
}

.projekt-seitenliste li a:hover,
.projekt-seitenliste li a:focus-visible {
  color: var(--sage-deep);
  background: var(--paper-raised);
  text-decoration: underline;
}

/* ——— Quellenansicht im Panel (LLM-169, W3) ——————————————————
   Öffnet eine Seite aus der Seitenliste OHNE den Workspace zu verlassen —
   Kurzfassung = Zusammenfassung + Text, kein Nachbau von seite.html (keine
   TOC, kein „Siehe auch", kein Graph). Rendert in derselben Panel-Spalte wie
   die Regelliste oben (.ws-panel-koerper), deshalb bewusst kompakter
   als die Vollseiten-Leseansicht. */

.projekt-quelle-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.9rem;
}

.projekt-quelle-kopf .btn-ghost {
  font-size: 0.78rem;
  padding: 0.3rem 0.6rem;
}

/* Eigene Klasse statt Wiederverwendung von .projekt-zurueck: beide Links
   spielen dieselbe Rolle (unauffällige Navigation), sitzen aber in
   unterschiedlichen Kontexten (Kopfzeile des ganzen Workspace vs. Kopf der
   Quellenansicht) und sollen sich unabhängig voneinander ändern lassen. */
.projekt-quelle-vollstaendig {
  flex: none;
  font-size: 0.78rem;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
}

.projekt-quelle-vollstaendig:hover { color: var(--sage-deep); }

/* Gleiche Größe wie .ws-panel h2 (Vorbild: spielt hier dieselbe Rolle
   als prominente Überschrift innerhalb der Spalte). */
.projekt-quelle-titel {
  font-family: var(--display);
  font-size: 1.05rem;
  line-height: 1.3;
  margin: 0 0 0.7rem;
  color: var(--ink);
}

/* --paper-raised (heller als die --paper-Panelfläche, s. Kommentar bei
   .ws-grid) plus linker Akzentstreifen setzen die
   Zusammenfassung sichtbar vom Fließtext darunter ab, ohne ein eigenes
   Aufklapp-Element zu brauchen (Index-Beschreibungen sind auf 300 Zeichen
   begrenzt, s. Kommentar im Partial). */
.projekt-quelle-zusammenfassung {
  background: var(--paper-raised);
  border-left: 3px solid var(--sage-light);
  border-radius: 0 4px 4px 0;
  padding: 0.6rem 0.8rem;
  margin: 0 0 1.2rem;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

/* Etwas kleiner als die Vollseiten-Leseansicht: dort erbt `article p` die
   Root-Größe, hier ist die Spalte auch im geöffneten Zustand
   (--ws-links: min(480px, 38vw)) schmaler als die Lesespalte. word-break/
   overflow-wrap gegen lange unumbrochene Tokens (URLs, lange Slugs) in
   dieser schmalen Spalte. */
.projekt-quelle-text {
  font-size: 0.92rem;
  word-break: break-word;
  overflow-wrap: break-word;
}

/* article img bringt bereits max-width:100% mit (s. „Artikel-Bilder"
   weiter oben) – hier zusätzlich explizit, falls sich diese Klasse einmal
   vom article-Element löst. */
.projekt-quelle-text img {
  max-width: 100%;
}

/* ——— Chat im Projekt-Workspace (LLM-158, Etappe E3) ——————————
   Bettet die geteilte Chat-Shell (Abschnitt "Chat-Shell" oben,
   templates/_fragen_chat.html/_fragen_chat_js.html) in die mittlere
   Panel-Spalte des Workspace ein. Rein additiv — die /fragen-Vollseiten-
   Regeln oben bleiben unverändert, hier ausschließlich Overrides mit dem
   Panel-Präfix .ws-panel-chat. */

/* Chat- und Werkzeug-Ansicht teilen sich die Mittelspalte und werden per
   `hidden` umgeblendet (s. projekte_workspace.html). Beide brauchen die
   Flex-Achse der Spalte, damit ihr Kopf steht und ihr Körper scrollt.

   ACHTUNG: `display: flex` würde das `hidden`-Attribut überstimmen — dieses
   Stylesheet hat KEINEN globalen [hidden]-Reset. Die zweite Regel ist
   deshalb kein Beiwerk, sondern die Bedingung dafür, dass das Umblenden
   überhaupt noch funktioniert. */
.ws-panel-chat > div {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1;
}

.ws-panel-chat > div[hidden] { display: none; }

/* Trägt nur Innenabstand und Flex-Achse; der Verlauf scrollt eine Ebene
   tiefer in .chat-log (s. Kommentar im Template). */
.ws-chat-koerper {
  overflow-y: visible;
  display: flex;
  flex-direction: column;
}

/* calc(100dvh - …) ist für einen Chat als eigene Vollseite gedacht; im Panel
   bestimmt die Spaltenhöhe den Rahmen, nicht der Viewport.

   Diese Regel gilt seit LLM-207 (Etappe 2) für BEIDE Chats — /fragen ist
   seither ebenfalls eine Arbeitsfläche mit diesem Panel in der Mitte. Die
   Spur bleibt flexibel — sie bekommt weiterhin jeden Pixel, den die
   Außenspalten übriglassen —, aber der Inhalt darin läuft nicht mehr über
   die volle Breite. Auf einem 1920px-Schirm waren das vorher über 1000px
   Zeilenlänge, also weit jenseits dessen, was sich ruhig liest; die beiden
   Chats sahen nebeneinander wie zwei verschiedene Oberflächen aus. (Die
   Breite von /fragen stand bis dahin in einer eigenen
   `.column.has-chat-toc`-Regel, die mit der freistehenden Gliederungs-Aside
   entfallen ist.)

   `margin-inline: auto` zentriert die begrenzte Box in der Spur; ein
   `width: 100%` braucht es dafür nicht, das Flex-Kind wird ohnehin bis zur
   max-width gestreckt. */
.ws-panel-chat .chat-shell {
  min-height: 0;
  flex: 1;
  max-width: calc(var(--measure) * 1.2);
  margin-inline: auto;
}

/* Verlauf füllt die Restfläche der Spalte und scrollt darin. Früher eine
   feste max-height: seit das Gitter eine gemeinsame Spaltenhöhe hat, würde
   ein fester Wert entweder Luft verschenken oder überlaufen.

   Der Innenabstand rechts gehört zu DIESEM Kasten und nicht zur .chat-shell:
   Der Scrollbalken sitzt an seiner Innenkante, und die Fragenblase steht
   rechtsbündig (`margin-left: auto`) — ohne Abstand klebt sie unmittelbar
   daran. Links bleibt es bei null, dort ist keine Kante, an die etwas stoßen
   könnte, und die Antwortblase soll die Breite behalten. */
.ws-panel-chat .chat-log {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  padding-right: 0.9rem;
}

/* Die Gesprächsliste ist Beiwerk über dem Verlauf: sie darf ihm bei vielen
   Gesprächen nicht die Fläche nehmen, sondern scrollt selbst. */
.ws-panel-chat .projekt-chatliste {
  flex: none;
  max-height: 8rem;
  overflow-y: auto;
}

/* position:sticky bezieht sich auf den Viewport-Rand der Vollseite; im
   Panel-Gitter würde die Leiste beim Scrollen der GESAMTEN Seite über die
   Panel-Grenzen hinaus "kleben" — hier reicht der normale Fluss am Ende
   des Panels (border-top bleibt als optische Trennlinie erhalten). */
/* Transparent statt der eigenen Fläche: die Leiste soll die Fläche des
   Panels durchscheinen lassen, egal welche das ist. Die Trennlinie oben
   bleibt als Abgrenzung. */
.ws-panel-chat .chat-compose {
  position: static;
  box-shadow: none;
  background: transparent;
  padding-bottom: 0;
}

/* Die zentrierte Startansicht (.chat-shell-empty oben) braucht Platz, den die
   Chat-Spalte des Workspace nicht hat — der Kopf ist dort ohnehin leer
   (chat_hero=False) und bleibt einfach im normalen Fluss.

   Gescopt auf den Workspace, seit /fragen dieselben Panel-Bausteine benutzt
   (LLM-207): Dort trägt der leere Zustand den Hero („Frag dein Wiki"), und
   der gehört wie bisher in die Mitte der Fläche. Die Unterscheidung ist die
   Zusatzklasse am Panel, nicht die Fensterbreite — die beiden Fälle
   unterscheiden sich im INHALT, nicht in der Größe. */
.ws-panel-chat-projekt .chat-shell-empty { justify-content: flex-start; }

/* Gegenstück für /fragen (LLM-207, Etappe 2): Dort ist der leere Zustand die
   Startansicht des Wikis — Hero und Eingabefeld gehören zusammen in die Mitte
   der Fläche, wie vor dem Spalten-Umbau.

   Nötig, weil `.ws-panel-chat .chat-log { flex: 1 }` (Verlauf füllt die
   Spalte und scrollt darin) seit dem Umbau AUCH auf /fragen greift und dort
   `.chat-shell-empty .chat-log { flex: 0 0 auto }` bei gleicher Spezifität
   über die Quellreihenfolge schlägt: Der leere Verlauf nahm die ganze Höhe,
   schob die Eingabe an den Fensterboden und ließ den Hero oben allein
   stehen. Mit der zusätzlichen Klasse (0,3,0) gewinnt wieder die
   Startansicht — und nur sie, der gefüllte Thread scrollt unverändert. */
.ws-panel-chat-fragen .chat-shell-empty .chat-log { flex: 0 0 auto; }

/* ——— Gesprächsliste des Projekts (nur DIESES Projekts, siehe
   projekte_workspace.html) — eigene schlichte Klasse im Stil der übrigen
   Projekt-Panels, spiegelt aber das Muster der Sidebar-Chatliste
   (.chatlist-item, _layout.html). */
.projekt-chatliste-liste {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.projekt-chatliste-item {
  border-radius: 4px;
  transition: background 130ms ease;
}

/* --paper-raised: die Panel-Fläche ist jetzt selbst --paper, ein Hover in
   derselben Farbe wäre unsichtbar. */
.projekt-chatliste-item:hover,
.projekt-chatliste-item:focus-within { background: var(--paper-raised); }

.projekt-chatliste-item.is-active { background: var(--sage-wash); }
.projekt-chatliste-item.is-active .projekt-chatliste-link { color: var(--sage-deep); }

/* --ink-soft (nicht --ink-faint): das Panel steht auf --paper, wo --ink-faint
   AA verfehlt (siehe .ws-panel .empty-state oben) — und für einen Link
   statt reinem Metatext ist der kräftigere Ton ohnehin richtig. */
.projekt-chatliste-link {
  display: block;
  overflow: hidden;
  padding: 0.35rem 0.5rem;
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.84rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ——— Studio-Panel (LLM-159, E4) ————————————————————————
   Bis hierher hatten die im Template verwendeten Studio-Klassen GAR KEIN
   CSS – das Panel rendelte in Browser-Defaults (Listenpunkte, grauer
   Standard-Knopf). Aufbau nach dem Flow-Mockup zum Projekte-Konzept.

   Schriftgrößen: die rem-Werte des Mockups sind UNVERÄNDERT übernommen, nicht
   auf eine px-Größe umgerechnet. Die Wurzelgröße ist hier nämlich keine
   Konstante, sondern Theme-Sache – pkm und philosophie setzen 100% (16px,
   exakt die Mockup-Basis), die Garten-Basis 112,5% (18px), und alle drei
   verkleinern auf Mobilgeräten noch einmal. Eine feste Umrechnung träfe
   damit höchstens ein Theme und bräche die Absicht der anderen; relative
   Werte skalieren dagegen mit. Ausnahme ist der KI-Badge, s. dort. */

/* auto-fit statt fester zwei Spalten: real existiert derzeit genau EIN
   Format (study-guide), das dann die volle Breite nimmt, statt neben einer
   leeren Zelle zu stehen. Ab zwei Formaten entsteht das Raster des Mockups. */
.projekt-studio-starter {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  gap: 0.5rem;
}

/* Kachel statt Knopf. Bewusst OHNE Icon und Untertitel: das Mockup zeigt
   dort zehn Formate mit Symbol und Kurzbeschreibung, für die es im Wiki
   weder einen Icon-Satz noch ein Beschreibungsfeld gibt (Format trägt nur
   `label`). Erfundene Untertitel wären eine Behauptung über das Format. */
.projekt-studio-tool {
  display: block;
  width: 100%;
  text-align: left;
  font-family: var(--display);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0.6rem 0.7rem;
  cursor: pointer;
  transition: background 130ms ease, border-color 130ms ease;
}

.projekt-studio-tool:hover {
  border-color: var(--sage-light);
  background: var(--sage-wash);
}

/* --ink-soft statt des naheliegenden --ink-muted: als kleines Versallabel
   auf --paper-raised erreicht --ink-muted im Garten-Theme nur 3,58:1 und
   verfehlt AA (gemessen; pkm 4,39, philosophie 4,58 – ebenfalls knapp).
   Gleiche Begründung wie bei .projekt-regel-pill weiter oben.

   0,68rem ist die Untergrenze der Hausskala: der kleinste Wert, den das Wiki
   auch anderswo verwendet (Sidebar-Gruppenlabel, .toc-label, Badge-Pill).
   Die früheren 0,64rem stammten aus dem Studio-Mockup und lagen darunter –
   auf Mobilgeräten (Wurzel 93,75%) wären das 9,6px versal mit Sperrung. */
.projekt-studio-erzeugt-kopf {
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-soft);
  margin: 1.2rem 0 0.6rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
}

.projekt-artefakt-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

/* Titel/Meta links, „Löschen“ rechts in DERSELBEN Zeile – ohne diese Regel
   stapelt der Browser Knopf und Formular untereinander. */
.projekt-artefakt {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper);
  padding-right: 0.4rem;
}

.projekt-artefakt:hover { border-color: var(--sage-light); }

.projekt-artefakt-oeffnen-btn {
  flex: 1;
  /* Ohne min-width:0 ignoriert ein Flex-Kind das text-overflow seines
     Inhalts und drückt stattdessen die Zeile auseinander. */
  min-width: 0;
  text-align: left;
  font-family: var(--display);
  background: none;
  border: 0;
  padding: 0.45rem 0.55rem;
  cursor: pointer;
}

.projekt-artefakt-titel {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --ink-soft, nicht --ink-faint: der Chip liegt auf --paper, wo --ink-faint
   im Garten-Theme nur 4,31:1 erreicht. --ink-muted hilft hier nicht weiter –
   --paper ist dort DUNKLER als --paper-raised, der Wert fiele noch tiefer.
   Die Abstufung zum Titel bleibt erhalten, der steht auf --ink. */
.projekt-artefakt-meta {
  display: block;
  font-size: 0.7rem;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ——— Artefakt-Aktionsmenü (LLM-167) ————————————————————————
   Quellen/Umbenennen/Löschen passen nicht mehr nebeneinander in die 300px-
   Spalte – dasselbe Klapp-Menü-Muster wie .liste-zeile-menue/-aktionen
   weiter oben (Projekt-Aktionen in der Übersichtstabelle): position:relative
   auf dem <details>, position:absolute auf dem aufklappenden Inhalt. Der
   Inhalt bleibt damit außerhalb des normalen Flusses – die Zeilenhöhe der
   Artefaktkarte ändert sich beim Öffnen nicht, das Menü schwebt darüber statt
   die Liste darunter aufzustoßen. --ink-soft statt --ink-muted/--ink-faint
   für Metatexte, gleiche Begründung wie überall in diesem Panel (die Panels
   stehen auf --paper, s. Kommentar bei .ws-panel .empty-state oben). */
.projekt-artefakt-menue { position: relative; }

.projekt-artefakt-menue summary {
  cursor: pointer;
  list-style: none;
  padding: 0.15rem 0.5rem;
  border-radius: 4px;
  color: var(--ink-soft);
}

.projekt-artefakt-menue summary::-webkit-details-marker { display: none; }

.projekt-artefakt-menue summary:hover { background: var(--rule-soft); }

.projekt-artefakt-menue summary:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}

/* Feste Breite statt min-width (anders als .liste-zeile-aktionen, deren
   Inhalt nur einzeilige Knöpfe sind): die 300px-Spalte hat nach Innenabstand
   nur rund 268px Platz, und .ws-panel-koerper scrollt mit
   overflow-y:auto – das zieht overflow-x auf denselben Nicht-"visible"-Wert
   (CSS-Overflow-Spezifikation), ein zu breites Dropdown bekäme also eine
   eigene Scrollleiste statt sichtbar überzustehen. `right:0` verankert am
   rechten Rand des <details> (das dank .projekt-artefakt bereits nah am
   rechten Kartenrand sitzt), 14rem bleiben innerhalb der 268px.

   Die 14rem sind allerdings nur bei normaler Wurzelschrift schmal genug: Sie
   wachsen mit ihr, der verfügbare Platz (Fensterbreite) nicht. Da `right:0`
   die RECHTE Kante festnagelt, wandert die linke nach außen – ab etwa 28px
   Wurzelschrift auf Telefonbreite über die linke Fensterkante hinaus
   (gemessen: linke Kante bei -57px), und dorthin kann in einer
   Links-nach-rechts-Schrift NIEMAND scrollen: der Menüanfang wäre schlicht
   weg. Deshalb der Deckel. Er rechnet mit der Fensterbreite statt mit `100%`,
   weil `100%` sich auf das <details> bezöge – das ist der gut 20px breite
   ⋮-Auslöser, kein brauchbarer Bezug. Die abgezogenen 2,4rem sind der Weg der
   rechten Menükante zur rechten Fensterkante (1rem Panel-Innenabstand +
   0,4rem Kartenrand) plus dieselbe 1rem links, damit das Menü genauso weit
   eingerückt steht wie die Karte darüber. Ein Breakpoint ist dafür unnötig:
   ab 901px Fensterbreite ist der Deckel nie kleiner als 14rem und damit
   wirkungslos – die Desktop-Darstellung bleibt unberührt. */
.projekt-artefakt-aktionen {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 5;
  width: 14rem;
  max-width: calc(100vw - 2.4rem);
  /* KEIN eigenes Padding und overflow:hidden – jeder Abschnitt bringt sein
     Padding selbst mit, damit die trennenden Haarlinien durchlaufen statt
     eingerückt zu enden (Bauweise wie .liste-zeile-aktionen). */
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: 6px;
  /* Der kräftigere Schatten (0.16 statt 0.12) trägt hier die Ablösung: im
     PKM-Theme steht das Panel auf reinem Weiß, --paper-raised ist dort nur
     ein Hauch Grau – ohne deutlichen Schlagschatten wirkt das Menü flach
     auf der Karte aufliegend statt darüber schwebend. */
  background: var(--paper-raised);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.16);
}

.projekt-artefakt-abschnitt { padding: 0.6rem 0.7rem; }

.projekt-artefakt-abschnitt + .projekt-artefakt-abschnitt,
.projekt-artefakt-loeschen-form { border-top: 1px solid var(--rule); }

/* Uppercase-Idiom des Panels, gleiche Größe wie .projekt-studio-erzeugt-kopf:
   „3 QUELLEN“ und „TITEL“ sind Rubriken des Menüs, kein Fließtext. Vorher
   0,6rem und damit noch eine Stufe unter der Hausuntergrenze (Begründung dort)
   – bei 16px-Wurzel 9,6px, auf Mobilgeräten 9px.
   Als <label> im Umbenennen-Formular trägt dieselbe Klasse zusätzlich die
   Beschriftungsrolle – deshalb display:block statt eines <p>-Defaults. */
.projekt-artefakt-abschnitt-kopf {
  display: block;
  margin: 0 0 0.4rem;
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-soft);
}

.projekt-artefakt-quellen {
  list-style: none;
  margin: 0;
  padding: 0;
  /* Gekappt plus eigener Bildlauf: ein Artefakt kann bis zu 300 Quellen
     tragen (MAX_PAGES), die Liste würde sonst über den Fensterboden
     hinauswachsen. Zusammen mit den einzeiligen Einträgen unten passen rund
     sechs Titel hinein – und die Kappung trifft nie mitten in ein Wort, was
     bei umbrechenden Titeln wie „RTK – Token-Kosten-Analyse und
     Tool-Vergleich …“ nach einem Darstellungsfehler aussah. */
  max-height: 8rem;
  overflow-y: auto;
  font-size: 0.78rem;
}

/* Einzeilig statt umbrechend: Wiki-Titel sind lang, drei umbrechende
   Einträge füllen das halbe Menü. Der volle Text steht im title-Attribut
   (s. Template) und im DOM – gekappt ist nur die Darstellung, gleiche
   Bauweise wie .projekt-artefakt-titel darüber. */
.projekt-artefakt-quellen a {
  display: block;
  padding: 0.2rem 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Menü-Einträge, keine Fließtext-Links: die Standard-Linkfarbe samt
     Unterstreichung macht die Liste unruhig und lässt sie wie einen
     Absatz mit Verweisen wirken statt wie eine Aufzählung von Quellen.
     Die Kennzeichnung als Link übernimmt der Hover-Zustand. */
  color: var(--ink);
  text-decoration: none;
}

.projekt-artefakt-quellen a:hover {
  color: var(--sage-deep);
  text-decoration: underline;
}

.projekt-artefakt-quellen-leer {
  margin: 0;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

.projekt-artefakt-umbenennen-form {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

/* --paper (nicht --paper-raised): der Dropdown-Hintergrund selbst ist
   --paper-raised (s. .projekt-artefakt-aktionen oben) – dasselbe Umkehr-
   Muster wie .projekt-dialog input[type="text"] (Dialog auf --paper, Feld
   auf --paper-raised), hier nur seitenverkehrt, damit sich das Eingabefeld
   von seinem Container abhebt. */
.projekt-artefakt-umbenennen-form input[type="text"] {
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 0.35rem 0.5rem;
  font-family: var(--serif);
  font-size: 0.85rem;
  background: var(--paper);
  color: var(--ink);
}

/* Rechtsbündig statt links: der Knopf bestätigt die Eingabe darüber und
   sitzt am Ende ihres Leseflusses (ohne align-self zöge der
   flex-column-Default align-items:stretch ihn über die volle Menübreite). */
.projekt-artefakt-umbenennen-form button {
  align-self: flex-end;
  padding: 0.25rem 0.7rem;
  font-size: 0.78rem;
}

/* „Löschen“ ist eine Menüzeile, kein Formularknopf: volle Breite, rahmenlos,
   Hover-Fläche – identisch zu .liste-zeile-aktionen button in der
   Projektübersicht, damit beide Klapp-Menüs der App dasselbe Idiom teilen. */
.projekt-artefakt-loeschen-form button {
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.7rem;
  border: none;
  background: none;
  font: inherit;
  font-size: 0.8rem;
  color: var(--ink);
  cursor: pointer;
}

.projekt-artefakt-loeschen-form button:hover { background: var(--sage-wash); }

/* ——— Lernhilfen-Artefakt als Karte ————————————————————
   Gilt für BEIDE Orte, an denen das Partial gerendert wird (Projekt-Studio
   und der Lernhilfen-Block in seite.html): die Kopfzeile ist dort wie hier
   die Auszeichnung „das hat eine Maschine erzeugt“. Die kompakteren
   Schriftgrößen weiter unten sind dagegen NUR auf den Workspace gescoped –
   auf der breiten Seitenansicht bleibt der Fließtext in Lesegröße. */
.lernhilfe-ergebnis {
  border: 1px solid var(--rule);
  border-radius: 7px;
  overflow: hidden;
  background: var(--paper);
}

.lernhilfe-kopf {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.6rem 0.85rem;
  background: var(--paper-raised);
  border-bottom: 1px solid var(--rule);
}

.lernhilfe-kopf-titel {
  font-family: var(--display);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--ink);
}

/* Das Mockup setzt hier 0.6rem, was bei 16px-Wurzel 9,6px ergibt – und auf
   Mobilgeräten (93,75%) nur noch 9px. Für versale Schrift mit Sperrung ist das
   die Grenze zur Unlesbarkeit, deshalb wie die übrigen Versallabels des
   Panels auf der Hausuntergrenze 0,68rem (siehe
   .projekt-studio-erzeugt-kopf). */
.lernhilfe-ki-badge {
  margin-left: auto;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--sage-deep);
  background: var(--sage-wash);
  border: 1px solid var(--sage-light);
  border-radius: 99px;
  padding: 0.15em 0.6em;
}

.lernhilfe-koerper { padding: 0.85rem; }

/* Die erste Abschnittsüberschrift im Körper braucht keinen Abstand nach
   oben mehr – den liefert jetzt das Karten-Padding. */
.lernhilfe-koerper .lernhilfe-section:first-child { margin-top: 0; }

/* ——— Lernkarten (LLM-144) ————————————————————————————————
   EIN Markup, zwei Darstellungen: Stapel (Standard – eine Karte, umdrehbar)
   und Liste (`.lernkarten-liste` – alle Karten mit beiden Seiten). Zwischen
   beiden steht nur diese eine Klasse auf dem Wurzelelement; der delegierte
   Handler in templates/_layout.html schaltet sie um, den Ausgangszustand
   rendert der Server. Deshalb liegt die gesamte Zustandslogik hier im CSS und
   nicht im JavaScript – das Partial kommt per innerHTML in die Seite und darf
   keinen Initialisierungsschritt brauchen. */
.lernkarten-leiste {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}

.lernkarten-zaehler {
  font-family: var(--display);
  font-size: 0.8rem;
  color: var(--ink-soft);
  /* Ziffern gleicher Breite: sonst wandert die Leiste beim Blättern von
     „9 / 12“ auf „10 / 12“ seitlich. */
  font-variant-numeric: tabular-nums;
}

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

.lernkarte {
  border: 1px solid var(--rule);
  border-radius: 7px;
  background: var(--paper-raised);
  padding: 1rem;
}

.lernkarte-vorder {
  font-weight: 600;
  color: var(--ink);
}

.lernkarte-rueck {
  color: var(--ink-soft);
  line-height: 1.55;
}

.lernkarten-steuerung {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

/* An den Enden des Stapels sind „Zurück“/„Weiter“ deaktiviert – das muss man
   sehen, sonst wirkt der Knopf kaputt statt am Anschlag. `.btn-small` hat
   anders als `.btn` keinen eigenen Deaktiviert-Zustand; die Werte hier sind
   von dort übernommen (opacity 0.4). Bewusst auf die Kartensteuerung gescoped
   statt `.btn-small:disabled` global zu ergänzen: Das beträfe jeden anderen
   Knopf dieser Klasse im ganzen Wiki und gehört damit nicht in dieses Ticket.
   Der Hover-Rahmen wird mit zurückgenommen, sonst meldet ein toter Knopf
   weiterhin Bedienbarkeit. */
.lernkarten-steuerung .btn-small:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.lernkarten-steuerung .btn-small:disabled:hover { border-color: var(--rule); }

/* Stapel: nur die aktive Karte, von ihr nur eine Seite. Die Mindesthöhe hält
   die Karte beim Umdrehen ruhig – ohne sie springt die Steuerung darunter je
   nach Antwortlänge hoch und runter. Grid statt Flex, damit die sichtbare
   Seite die volle Kartenbreite behält und trotzdem senkrecht mittig sitzt. */
.lernkarten:not(.lernkarten-liste) .lernkarte {
  min-height: 7.5rem;
  display: grid;
  align-items: center;
}

.lernkarten:not(.lernkarten-liste) .lernkarte:not(.lernkarte-aktiv) { display: none; }
.lernkarten:not(.lernkarten-liste) .lernkarte-rueck { display: none; }
.lernkarten:not(.lernkarten-liste) .lernkarte-umgedreht .lernkarte-vorder { display: none; }
.lernkarten:not(.lernkarten-liste) .lernkarte-umgedreht .lernkarte-rueck { display: block; }

/* Liste: alle Karten, beide Seiten, keine Blätter-Steuerung. */
.lernkarten-liste .lernkarte { margin-bottom: 0.6rem; }
.lernkarten-liste .lernkarte-rueck { margin-top: 0.4rem; }
.lernkarten-liste .lernkarten-steuerung { display: none; }

/* ——— FAQ (LLM-32) ————————————————————————————————————————
   Natives <details>/<summary>-Akkordeon je Frage statt eines Skripts – das
   Partial kommt wie bei den Lernkarten per innerHTML in die Seite und darf
   keinen Initialisierungsschritt brauchen. Der Fokusring kommt kostenlos aus
   der globalen `summary:focus-visible`-Regel weiter oben in dieser Datei;
   hier nur Marker und Layout. */
.faq-eintrag {
  border-bottom: 1px dotted var(--rule);
}

.faq-eintrag:last-child { border-bottom: none; }

.faq-eintrag > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0;
  font-weight: 600;
  color: var(--ink);
}

.faq-eintrag > summary::-webkit-details-marker { display: none; }

/* Chevron als eigenes Zeichen statt des Browser-Default-Dreiecks – Muster
   .commit-details weiter oben in dieser Datei: ▸ gedreht statt eines
   zweiten Icon-Satzes. */
.faq-eintrag > summary::before {
  content: '▸';
  flex-shrink: 0;
  color: var(--sage);
  transition: transform 120ms ease;
}

.faq-eintrag[open] > summary::before {
  transform: rotate(90deg);
}

.faq-antwort {
  padding: 0 0 0.8rem 1.2rem;
  color: var(--ink-soft);
  line-height: 1.55;
}

/* Konzept-Optik nach Mockup: linker Akzentbalken statt punktierter
   Trennlinie unter jedem Eintrag.

   BEWUSST OHNE font-size: Das Mockup zeichnete die Lernhilfe im 300px breiten
   Studio-Panel und setzte sie deshalb auf 0,85rem herunter. Werkzeuge öffnen
   aber in der MITTELSPALTE (Eignerentscheidung 2026-07-24, siehe
   docs/projekte-konzept.md) – `.ws-panel-chat` ist genau diese Spalte,
   dasselbe Element, in dem der Chat mit 1rem läuft. Die verkleinerte Schrift
   war damit ein mitgewanderter Mockup-Wert ohne Breitenargument: dieselbe
   Lernhilfe stand auf seite.html in 1rem, im Panel in 0,85rem und direkt
   neben einem 1rem-Chat. Wer hier wieder eine Größe setzt, muss erklären,
   warum derselbe Inhalt in derselben Spalte kleiner sein soll als der Chat.
   Die kompakte line-height bleibt: Einträge sind eine Liste, kein Fließtext. */
.ws-panel-chat .lernhilfe-section li {
  padding: 0 0 0 0.7rem;
  margin-bottom: 0.8rem;
  border-bottom: none;
  /* --sage-light statt des im Mockup verwendeten Wash-Tons: der Balken liegt
     hier auf der weißen Kartenfläche, wo --sage-wash praktisch unsichtbar
     bleibt (im Mockup liegt er auf einer abgesetzten Fläche). */
  border-left: 2px solid var(--sage-light);
  line-height: 1.5;
  color: var(--ink-soft);
}

.ws-panel-chat .lernhilfe-section li strong { color: var(--ink); }

.ws-panel-chat .lernhilfe-section {
  margin: 0 0 1.1rem;
}

/* Ebenfalls ohne font-size (Begründung bei .ws-panel-chat
   .lernhilfe-section li) – es gilt der Seitenwert 0,74rem. Die engere
   Sperrung bleibt: sie ist eine Breitenanpassung an die Spalte, keine
   Größenentscheidung. */
.ws-panel-chat .lernhilfe-section h4 {
  letter-spacing: 0.16em;
  margin-bottom: 0.6rem;
}

/* Belege als kompakter Chip statt breit laufender unterstrichener Links.
   ABWEICHUNG vom Mockup: dort steht `white-space: nowrap`, weil die Belege
   kurze Slugs sind ([[bm25]]). Hier sind es vollständige Seitentitel von
   teils über 90 Zeichen – nowrap würde die 300px-Spalte waagerecht
   sprengen. Stattdessen inline-block mit Umbruch: der Rahmen umschließt
   auch den mehrzeiligen Chip sauber. */
/* font-size: 0 auf dem Container ist Absicht und kein Versehen: bei mehreren
   Belegen setzt die Route die Links durch reine Text-Kommas getrennt
   („<a>, <a>“). Als Chips gesetzt stünde dieses Komma als nacktes
   Satzzeichen zwischen zwei Kästchen und läse sich wie ein Tippfehler. Der
   Textknoten wird hier auf 0 gesetzt, die Chips holen ihre Größe selbst
   zurück; im DOM bleibt das Komma erhalten (Screenreader-Trennung). */
.lernhilfe-beleg {
  display: block;
  margin-top: 0.4rem;
  font-size: 0;
  line-height: 1.4;
}

/* 0,78rem ist der Wert, den der Beleg auf seite.html schon immer haben
   sollte (.lernhilfe-beleg weiter oben) – nur kam er dort nie an, weil dieser
   Block den Container überschreibt. Der Chip trägt die Größe jetzt für BEIDE
   Rendering-Orte, statt im Panel eine Stufe kleiner zu laufen. */
.lernhilfe-beleg a {
  display: inline-block;
  max-width: 100%;
  margin: 0.15rem 0.25rem 0 0;
  font-size: 0.78rem;
  overflow-wrap: anywhere;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--sage-deep);
  background: var(--sage-wash);
  border: 1px solid var(--sage-light);
  border-radius: 3px;
  padding: 0.05em 0.4em;
  text-decoration: none;
}

.lernhilfe-beleg a:hover { border-color: var(--sage); }

/* ——— Mindmap (LLM-179) ————————————————————————————————————
   Eingerückter, aufklappbarer Baum aus nativen <details>/<summary> je Ast
   mit Unterpunkten (Muster .faq-eintrag: Chevron statt Browser-Standard-
   Dreieck, kein eigenes Skript nötig). Ein Ast OHNE Unterpunkte rendert
   stattdessen nur seine Beschriftung (.mindmap-blatt) — keine leere
   Aufklapp-Hülle. Die Einrückung je Ebene kommt allein aus dem
   Innenabstand von .mindmap-kinder (dem <ul> der jeweiligen Kinderliste);
   das Template verschachtelt dafür einen rekursiven Jinja-Makro-Aufruf
   (templates/_lernhilfe_mindmap.html) — keine feste Ebenenanzahl im CSS. */
.mindmap-wurzel {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 1rem;
}

.mindmap-baum { margin: 0; }

.mindmap-ast { margin: 0.15rem 0; }

/* summary UND Blatt teilen sich Flex/Gap, damit ihr Text unabhängig vom
   Chevron- bzw. Punkt-Symbol auf gleicher Höhe beginnt (beide stehen als
   Geschwister im selben .mindmap-kinder-<li>). */
.mindmap-ast > summary,
.mindmap-blatt {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0;
  margin: 0;
}

.mindmap-ast > summary {
  list-style: none;
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
}

.mindmap-ast > summary::-webkit-details-marker { display: none; }

/* Chevron als eigenes Zeichen statt des Browser-Default-Dreiecks — Muster
   .faq-eintrag > summary::before weiter oben in dieser Datei. */
.mindmap-ast > summary::before {
  content: '▸';
  flex-shrink: 0;
  color: var(--sage);
  transition: transform 120ms ease;
}

.mindmap-ast[open] > summary::before { transform: rotate(90deg); }

.mindmap-blatt {
  color: var(--ink-soft);
}

.mindmap-blatt::before {
  content: '•';
  flex-shrink: 0;
  color: var(--sage-light);
}

.mindmap-kinder {
  list-style: none;
  margin: 0.15rem 0 0.3rem;
  padding: 0 0 0 1.3rem;
  border-left: 1px dotted var(--rule);
}

/* Frage-Auslöser der Liste (LLM-180) — gewöhnlicher Link, kein Skript nötig
   (s. Kommentar in _lernhilfe_mindmap.html, warum es ihn nur bei gesetztem
   `slug` gibt). Textuell statt als Chip (anders als .lernhilfe-beleg a):
   das ist ein Vorschlag, kein Beleg, und soll sich davon unterscheiden.
   Gepunktete statt durchgezogene Unterstreichung, dieselbe Zurückhaltung wie
   der Frage-Knopf der gezeichneten Ansicht im Ruhezustand. */
.mindmap-frage-link {
  display: inline-block;
  margin-left: 0.3rem;
  font-size: 0.72rem;
  color: var(--ink-muted);
  text-decoration: none;
  border-bottom: 1px dotted var(--ink-muted);
}

.mindmap-frage-link:hover,
.mindmap-frage-link:focus-visible {
  color: var(--sage-deep);
  border-bottom-color: var(--sage-deep);
}

/* ——— Mindmap: gezeichnete Ansicht (LLM-181) ————————————————————
   Zweite Darstellung neben dem aufklappbaren Baum oben: ein liegender,
   gezeichneter Baum via D3 (d3-hierarchy + d3-shape, lokal vendoriert über
   scripts/vendor_d3.py, KEINE vollständige D3-Bibliothek), umschaltbar gegen
   die Liste über eine Modifier-Klasse auf dem Wrapper – exaktes Muster der
   Lernkarten (.lernkarten/.lernkarten-liste weiter oben in dieser Datei).
   Farben ausschließlich über var(--…), damit die Zeichnung jedem Wiki-Theme
   folgt (kein eigenes prefers-color-scheme-Handling, s. dortiger
   Kommentarblock); Geometrie (Boxbreite, Layout-Koordinaten, Pfade) kommt aus
   der Textmessung in JavaScript (templates/_lernhilfe_mindmap_js.html) und
   lässt sich nicht vorab in CSS festlegen. */
.mindmap-werkzeugleiste {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}

/* Standard: Liste sichtbar, Zeichnung ausgeblendet. */
.mindmap-ansicht:not(.mindmap-ansicht-karte) .mindmap-zeichnung { display: none; }
/* Karte aktiv: Liste + Wurzelüberschrift ausgeblendet – die Zeichnung stellt
   die Wurzel als eigenen Knoten dar, eine zweite Überschrift wäre doppelt. */
.mindmap-ansicht-karte .mindmap-wurzel,
.mindmap-ansicht-karte .mindmap-baum {
  display: none;
}

/* Festes Kamera-Sichtfeld (LLM-182): anders als vorher hat der Container eine
   FESTE statt einer maximalen Höhe, und `overflow` steht auf `hidden` statt
   `auto` – das <svg> füllt ihn per CSS immer exakt aus (s. Kopfkommentar
   „ZOOM & ZIEHEN" in _lernhilfe_mindmap_js.html), es gibt also nie natives
   Scrollen, das Kamera-Pan übernimmt diese Aufgabe vollständig. Ein hartes
   `hidden` verhindert außerdem, dass gerundete Pixelwerte beim Zoomen eine
   1px-Scrollleiste aufreißen. */
.mindmap-zeichnung {
  position: relative;
  overflow: hidden;
  height: 32rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper);
}

.mindmap-svg {
  display: block;
  width: 100%;
  height: 100%;
  /* Verhindert, dass der Browser einen Zieh-Vorgang zusätzlich als native
     Touch-Geste (Seiten-Scroll/Pinch) deutet – Ziehen übernimmt das JS
     vollständig selbst (LLM-182). */
  touch-action: none;
  user-select: none;
  cursor: grab;
}

.mindmap-svg.mindmap-svg-zieht { cursor: grabbing; }

.mindmap-kante {
  fill: none;
  stroke: var(--rule);
  stroke-width: 1.3;
}

.mindmap-knoten-rect {
  fill: var(--paper-raised);
  stroke: var(--sage-light);
  stroke-width: 1;
}

/* Wurzelknoten optisch hervorgehoben – dieselbe Farbpaarung wie der
   Primärknopf `.btn` (Papier auf Salbei), in allen drei Themes bereits
   kontrastgeprüft im Einsatz. */
.mindmap-knoten-wurzel .mindmap-knoten-rect {
  fill: var(--sage);
  stroke: var(--sage-deep);
}

.mindmap-knoten-text {
  font-family: var(--serif);
  font-size: 0.75rem;
  fill: var(--ink);
  text-anchor: middle;
  dominant-baseline: central;
}

.mindmap-knoten-wurzel .mindmap-knoten-text {
  font-weight: 700;
  fill: var(--paper);
}

/* LLM-183: Klick auf JEDEN nicht-Wurzel-Knoten stellt jetzt eine Frage
   (vorher nur bei Ästen: Auf-/Zuklappen) – „Erkennbarkeit"-Vorgabe des
   Tickets, deshalb cursor:pointer jetzt auch für Blätter, nicht mehr nur für
   Äste. Die dreiwertige Klassenzuweisung in _lernhilfe_mindmap_js.html
   (Wurzel/Ast/Blatt) sorgt dafür, dass die nicht klickbare Wurzel keine
   dieser beiden Klassen trägt und entsprechend NICHT klickbar aussieht. */
.mindmap-knoten-verzweigt,
.mindmap-knoten-blatt {
  cursor: pointer;
}

.mindmap-chevron { fill: var(--sage); }

/* Chevron-Trefferfläche (LLM-183): eigenes, deutlich größeres Mausziel um
   das kleine Dreieck herum. `fill: transparent` statt `none` — anders als
   `none` gilt eine transparente Füllung als „gemalt" und bleibt damit per
   Default (pointer-events: visiblePainted) klickbar, ein etabliertes
   SVG-Muster für unsichtbare Hit-Areas. Eigener Klick-Handler in
   _lernhilfe_mindmap_js.html::baueChevronZiel, stoppt die Weitergabe an den
   Knoten-Klick (Frage). Kein eigener Tab-Haltepunkt (s. Kopfkommentar der
   JS-Datei, Abschnitt „TASTATUR") – reines Mausziel. */
.mindmap-chevron-ziel { cursor: pointer; }

.mindmap-chevron-treffer { fill: transparent; }

/* SVG-Elemente mit tabindex unterstützen :focus-visible wie gewöhnliche
   interaktive Elemente – Fokusring über Kastenrand statt eines nativen
   Outlines, dessen Darstellung auf SVG-Knoten browserübergreifend uneinheitlich
   ausfällt. */
.mindmap-knoten:focus-visible .mindmap-knoten-rect {
  stroke: var(--sage-deep);
  stroke-width: 2;
}

/* Hover-Hervorhebung (LLM-183, „Erkennbarkeit"): dieselbe Optik wie der
   Fokusring, aber dezenter (stroke-width 1.5 statt 2) – zeigt Maus-Nutzenden,
   dass ein Klick auf den Knoten etwas auslöst (Frage stellen). Nur auf den
   klickbaren Klassen, nicht auf der Wurzel. */
.mindmap-knoten-verzweigt:hover .mindmap-knoten-rect,
.mindmap-knoten-blatt:hover .mindmap-knoten-rect {
  stroke: var(--sage-deep);
  stroke-width: 1.5;
}

/* Leichter Tooltip für sehende Tastaturnutzer (Hover/Fokus) – Muster
   #edge-tooltip in graph.html, hier positioniert über die aus dem
   Baumlayout bekannten Koordinaten statt über getBoundingClientRect. Der
   Schatten übernimmt bewusst denselben Wert wie dort (kein neuer
   hartkodierter Farbwert, sondern derselbe Bestandswert für dieselbe Art von
   Element). */
.mindmap-tooltip {
  position: absolute;
  z-index: 1;
  max-width: 18em;
  padding: 0.3em 0.6em;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 5px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
  pointer-events: none;
}

/* ——— Mindmap: Quelle-Knopf (LLM-180, umgewidmet unter LLM-183) ——————————
   War bis LLM-183 der „Frage-Knopf" AUSSERHALB des Kastens (stellte eine
   Frage). Seit LLM-183 sitzt derselbe kleine „?"-Knopf INNERHALB der
   Kastenfläche, rechts vom Titeltext (Platz dafür reserviert
   _lernhilfe_mindmap_js.html bereits in der Kastenbreite, s. dortigen
   Kommentar), und zeigt stattdessen die Quelle(n) des Knotens – das Stellen
   der Frage ist auf einen Klick auf den KNOTEN selbst gewandert. Bewusst
   OHNE eigenen Tab-Haltepunkt (anders als der frühere Frage-Knopf) – Details
   und Begründung im Kopfkommentar der JS-Datei bzw. direkt bei
   baueQuelleKnopf(). Im Ruhezustand unsichtbar (`opacity:0`) – erscheint
   erst bei Hover/Fokus DES KNOTENS (der umgebenden .mindmap-knoten-Gruppe):
   `:focus-within` deckt auch Tab-Navigation direkt in den Knoten hinein ab,
   ohne dass der Knopf je unsichtbar „aktiv" wäre. */
.mindmap-quelle-knopf {
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms ease;
}

.mindmap-knoten:hover .mindmap-quelle-knopf,
.mindmap-knoten:focus-within .mindmap-quelle-knopf {
  opacity: 1;
}

.mindmap-quelle-kreis {
  fill: var(--paper-raised);
  stroke: var(--sage);
  stroke-width: 1;
}

.mindmap-quelle-glyph {
  font-family: var(--serif);
  font-size: 0.62rem;
  font-weight: 700;
  fill: var(--sage-deep);
  text-anchor: middle;
  dominant-baseline: central;
  pointer-events: none;
}

/* Eigener Hover-Zustand DES KNOPFS (nicht nur des Knotens) – dieselbe
   Sage/Papier-Farbumkehr wie beim Wurzelknoten (.mindmap-knoten-wurzel
   weiter oben), hier als Aktivierungs-Feedback statt Dauerhervorhebung. Kein
   eigener :focus-visible-Zustand mehr (der Knopf ist seit LLM-183 nicht mehr
   fokussierbar, s. Kopfkommentar oben). */
.mindmap-quelle-knopf:hover .mindmap-quelle-kreis {
  fill: var(--sage);
  stroke: var(--sage-deep);
  stroke-width: 2;
}

.mindmap-quelle-knopf:hover .mindmap-quelle-glyph {
  fill: var(--paper);
}

/* ——— Mindmap: Quellen-Popover (LLM-183) ————————————————————————
   Zeigt beim Klick auf den Quelle-Knopf die Titel ALLER Belege eines
   Knotens als klickbare Links (nie nur den ersten, s. Kommentar in
   _lernhilfe_mindmap_js.html::toggleQuellenPopover) – ein eigenständiges,
   INTERAKTIVES Overlay (echte <a>-Links, `pointer-events` also nicht auf
   `none` gesetzt), anders als der rein informative .mindmap-tooltip oben.
   Optik angelehnt an .mindmap-tooltip (gleiche Kartenoptik), Links im
   Chip-Stil von .lernhilfe-beleg a weiter oben in dieser Datei – dieselbe
   Sprache wie überall sonst, wo ein Beleg-Wikilink gezeigt wird. */
.mindmap-quelle-popover {
  position: absolute;
  z-index: 2;
  min-width: 9em;
  max-width: 20em;
  padding: 0.5em 0.7em;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ink);
  background: var(--paper-raised);
  border: 1px solid var(--rule);
  border-radius: 5px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}

.mindmap-quelle-popover-kopf {
  margin: 0 0 0.35em;
  font-family: var(--display);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* --ink-faint statt --ink-muted: die Karte liegt auf --paper-raised, dort
     unterschreitet --ink-muted den AA-Kontrast (gleiche Begründung wie bei
     .ansicht-umschalter a bzw. .pdf-dropzone__hint weiter oben). */
  color: var(--ink-faint);
}

.mindmap-quelle-popover ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.mindmap-quelle-popover li + li { margin-top: 0.3em; }

.mindmap-quelle-popover a {
  display: inline-block;
  max-width: 100%;
  overflow-wrap: anywhere;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: var(--sage-deep);
  background: var(--sage-wash);
  border: 1px solid var(--sage-light);
  border-radius: 3px;
  padding: 0.05em 0.4em;
  text-decoration: none;
}

.mindmap-quelle-popover a:hover,
.mindmap-quelle-popover a:focus-visible {
  border-color: var(--sage);
}

/* ——— Mindmap: Vollbild (LLM-182) ————————————————————————————————
   CSS-Überlagerung auf dem VORHANDENEN .mindmap-ansicht-Wrapper (kein
   separates Element, keine Fullscreen-API) – Vorbild ist das mobile Sheet in
   templates/graph.html. `role="dialog"`/`aria-modal` setzt das Skript nur
   während des Vollbildmodus (s. _lernhilfe_mindmap_js.html), deshalb steht
   hier keine feste ARIA-Zuweisung im Markup. z-index 900: knapp unter der
   Lightbox/dem Skip-Link (beide 1000, s. weiter oben in dieser Datei), aber
   über jedem sonstigen Element der Seite. */
.mindmap-ansicht.mindmap-ansicht-vollbild {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem;
  background: var(--paper);
  overflow: auto;
}

.mindmap-ansicht-vollbild .mindmap-werkzeugleiste,
.mindmap-ansicht-vollbild .mindmap-wurzel {
  flex: none;
}

/* Liste im Vollbild: eigener Scrollbereich statt der Container-Höhe von
   .mindmap-zeichnung, die im Vollbild ohnehin nicht gilt (s.u.). */
.mindmap-ansicht-vollbild .mindmap-baum {
  flex: 1 1 auto;
  overflow: auto;
}

/* Überschreibt die feste 32rem-Höhe außerhalb des Vollbilds – hier bestimmt
   der Flex-Container die verfügbare Fläche. */
.mindmap-ansicht-vollbild .mindmap-zeichnung {
  flex: 1 1 auto;
  height: auto;
}

/* ===== Retrieval-Vorführung (LLM-217, Etappe B) =====================
   Admin-Diagnoseseite /einstellungen/retrieval: zeigt die ECHTE /fragen-
   Retrieval-Kaskade Schritt für Schritt (templates/retrieval_demo.html).
   Eigener Namensraum `.retrieval-*` durchgängig, auch wo ein kürzerer Name
   nahegelegen hätte (`.chip`, `.liste`, `.beleg` …) – die kurzen Namen sind
   anderswo im Bestand bereits mit eigener Bedeutung belegt (Chat-Vorschlags-
   Chips, Katalog/Projekte-Listenbausteine, Beleg-Popover), eine Kollision
   wäre dort nicht sofort sichtbar, aber real. Farben/Schriften kommen aus
   den Theme-Variablen (var(--sage), var(--paper) …), keine eigenen Werte
   außer der einen neuen Gegenfarbe --sinn/--sinn-wash (oben bei :root). */

.retrieval-intro { max-width: var(--measure); }

.retrieval-hint {
  font-family: var(--display);
  font-size: 0.85rem;
  color: var(--ink-muted);
  margin: 0 0 1rem;
}

/* Gleicher Farbwert wie .fragen-error (routes/fragen.py-Pendant auf
   /fragen) – ein zweiter, eigens erfundener Fehlerton hätte auf derselben
   Seitenfamilie zwei verschiedene Bedeutungen für „Fehler" suggeriert. */
.retrieval-status-fehler { color: #8B3A2A; }

/* Fluss links, bleibt beim Scrollen stehen; Daten rechts, flexibel breit.
   Bewusst NUR diese eine Ausrichtung (Entscheidung des Eigners, LLM-217) –
   der Entwurf sah zusätzlich eine waagerechte Variante vor, die hier nicht
   gebaut ist. */
.retrieval-buehne {
  display: grid;
  /* Breiter als zunächst gebaut (LLM-217, nach dem ersten Blick auf die
     fertige Seite): Das Bild skaliert mit der Spalte, bei rund 300 px
     standen Beschriftung und Zahlen zu gedrängt. Die Obergrenze bleibt,
     damit die zwei Trefferlisten rechts nebeneinander Platz behalten. */
  grid-template-columns: clamp(20rem, 32%, 28rem) minmax(0, 1fr);
  align-items: start;
  gap: 1.75rem;
}

.retrieval-fluss-spalte { position: sticky; top: 1rem; }

@media (max-width: 60rem) {
  /* Unterhalb der Fluss-/Datenspalten-Breite bleibt die Spalte nicht mehr
     stehen (kein Platz mehr, um sie neben der Daten-Spalte sinnvoll zu
     fixieren) – gestapelt statt nebeneinander, dieselbe SVG-Geometrie. */
  .retrieval-buehne { grid-template-columns: minmax(0, 1fr); }
  .retrieval-fluss-spalte { position: static; }
}

.retrieval-fluss-spalte svg { display: block; width: 100%; height: auto; }

.retrieval-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  margin-top: 0.7rem;
  font-family: var(--display);
  font-size: 0.78rem;
  color: var(--ink-muted);
}

.retrieval-legende span { display: inline-flex; align-items: center; gap: 0.4rem; }

.retrieval-punkt { width: 0.6rem; height: 0.6rem; border-radius: 50%; display: inline-block; }

.retrieval-knoten { cursor: pointer; }
.retrieval-knoten text { pointer-events: none; }

/* Stufe, deren Daten in DIESEM Lauf noch nicht eingetroffen sind (Anfangs-
   zustand oder Ereignisstrom noch nicht so weit) – abgedunkelt statt
   ausgeblendet, damit die Form der ganzen Kaskade von Anfang an sichtbar
   bleibt. */
.retrieval-knoten-wartet { opacity: 0.45; }

.retrieval-knoten:focus-visible { outline: 2px solid var(--sage); outline-offset: 2px; }

/* ——— Datenblock ——— */

.retrieval-panel-kopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.3rem;
}

.retrieval-panel-kopf h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
}

.retrieval-panel-zahl {
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  color: var(--ink-muted);
}

.retrieval-panel-lead {
  font-family: var(--display);
  font-size: 0.87rem;
  color: var(--ink-muted);
  margin: 0 0 1rem;
  max-width: var(--measure);
  line-height: 1.5;
}

.retrieval-leer {
  font-family: var(--display);
  font-size: 0.85rem;
  color: var(--ink-muted);
  padding: 0.6rem 0;
  margin: 0;
}

.retrieval-spuren { display: grid; gap: 1.25rem; }
@media (min-width: 60rem) { .retrieval-spuren { grid-template-columns: 1fr 1fr; } }

.retrieval-spur-titel {
  font-family: var(--display);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin: 0 0 0.4rem;
  color: var(--ink-soft);
}

.retrieval-spur-wort .retrieval-spur-titel { color: var(--sage); }
.retrieval-spur-sinn .retrieval-spur-titel { color: var(--sinn); }

.retrieval-anfrage {
  margin: 0 0 0.6rem;
  padding: 0.45rem 0.6rem;
  border-radius: 5px;
  font-family: var(--display);
  font-size: 0.8rem;
  line-height: 1.4;
  border-left: 2px solid var(--rule);
  background: var(--paper-raised);
  color: var(--ink-soft);
}

.retrieval-anfrage b {
  display: block;
  font-weight: 600;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 0.15rem;
}

.retrieval-anfrage-wort { border-left-color: var(--sage); background: var(--sage-wash); }
.retrieval-anfrage-sinn { border-left-color: var(--sinn); background: var(--sinn-wash); }

.retrieval-liste { border: 1px solid var(--rule); border-radius: 8px; overflow: hidden; }

.retrieval-treffer { display: flex; gap: 0.6rem; padding: 0.5rem 0.6rem; align-items: flex-start; }
.retrieval-treffer + .retrieval-treffer { border-top: 1px solid var(--rule-soft); }
.retrieval-treffer-gewaehlt { background: var(--sage-wash); }
.retrieval-treffer-verworfen { opacity: 0.5; }

.retrieval-rang {
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--ink-faint);
  min-width: 1.5rem;
  padding-top: 0.12rem;
}

.retrieval-treffer-text { min-width: 0; flex: 1; }

.retrieval-titel-zeile {
  font-family: var(--display);
  font-size: 0.85rem;
  line-height: 1.35;
  font-weight: 500;
  margin: 0;
  color: var(--ink);
}

.retrieval-abschnitt-zeile {
  font-size: 0.76rem;
  color: var(--ink-muted);
  margin: 0.12rem 0 0;
  font-family: var(--display);
  line-height: 1.35;
}

.retrieval-herkunft {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.02rem 0.35rem;
  border-radius: 3px;
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  background: var(--rule-soft);
  color: var(--ink-faint);
  white-space: nowrap;
}

.retrieval-herkunft-nachbar { background: var(--sinn-wash); color: var(--sinn); }

.retrieval-marker { display: flex; gap: 0.2rem; padding-top: 0.2rem; }
.retrieval-marker i { width: 0.42rem; height: 1.05rem; border-radius: 2px; display: block; }
.retrieval-m-wort { background: var(--sage); }
.retrieval-m-sinn { background: var(--sinn); }
.retrieval-m-leer { background: var(--rule); }

.retrieval-punktwert {
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
  font-size: 0.74rem;
  color: var(--ink-muted);
  padding-top: 0.18rem;
  white-space: nowrap;
}

.retrieval-regler { display: grid; gap: 0.55rem; margin-bottom: 0.8rem; max-width: 26rem; }

.retrieval-regler label {
  font-family: var(--display);
  font-size: 0.8rem;
  color: var(--ink-soft);
  display: grid;
  gap: 0.2rem;
}

.retrieval-regler input[type="range"] { width: 100%; accent-color: var(--sage); }

.retrieval-wert { color: var(--ink-muted); font-variant-numeric: tabular-nums; }

.retrieval-merke {
  padding: 0.6rem 0.75rem;
  border-radius: 5px;
  background: var(--paper-raised);
  border-left: 2px solid var(--sinn);
  font-family: var(--display);
  font-size: 0.82rem;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0 0 1rem;
}

.retrieval-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.retrieval-chip {
  font-family: var(--display);
  font-size: 0.85rem;
  background: var(--sage-wash);
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  border-radius: 4px;
  padding: 0.2rem 0.55rem;
}

/* ——— Antwort ——— */

.retrieval-antwort-grid { display: grid; gap: 1.75rem; }
@media (min-width: 62rem) {
  .retrieval-antwort-grid { grid-template-columns: minmax(0, 1.6fr) minmax(15rem, 1fr); }
}

.retrieval-antwort-text { max-width: var(--measure); }

/* pre-wrap: ein Block kann ein Listenpunkt mit mehreren Zeilen sein
   (belegmass.bloecke() reicht ihn als EINEN mehrzeiligen String durch) –
   die Zeilenumbrüche stecken im Text, nicht im Markup (Einfügung per
   textContent, s. Skript). */
.retrieval-antwort-text p { margin: 0 0 1rem; white-space: pre-wrap; }

.retrieval-beleg {
  font-family: var(--display);
  font-size: 0.62rem;
  font-weight: 700;
  vertical-align: super;
  color: var(--sage);
  background: var(--sage-wash);
  border-radius: 3px;
  padding: 0.05rem 0.28rem;
  margin-left: 0.12rem;
  cursor: pointer;
  border: 0;
}

.retrieval-beleg:hover,
.retrieval-beleg:focus-visible { background: var(--sage); color: var(--paper); outline: none; }

.retrieval-bilanz { font-family: var(--display); font-size: 0.84rem; }
.retrieval-bilanz h3 { font-size: 0.95rem; margin: 0 0 0.2rem; font-weight: 600; color: var(--ink); }
.retrieval-bilanz-hinweis { color: var(--ink-muted); font-size: 0.8rem; }
.retrieval-bilanz ul { list-style: none; margin: 0.5rem 0 0; padding: 0; display: grid; gap: 0.5rem; }
.retrieval-bilanz li { display: flex; gap: 0.5rem; align-items: baseline; line-height: 1.35; }

.retrieval-bilanz .retrieval-nr {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.7rem;
  color: var(--sage);
  background: var(--sage-wash);
  border-radius: 3px;
  padding: 0.05rem 0.3rem;
  min-width: 1.3rem;
  text-align: center;
}

.retrieval-bilanz .retrieval-nr-ungenutzt { color: var(--ink-faint); background: var(--rule-soft); }
.retrieval-bilanz li.retrieval-ungenutzt { color: var(--ink-muted); }
.retrieval-bilanz .retrieval-zeichen { color: var(--ink-faint); font-variant-numeric: tabular-nums; font-size: 0.77rem; }

.retrieval-fazit {
  margin-top: 1rem;
  padding: 0.7rem 0.8rem;
  background: var(--paper-raised);
  border-left: 2px solid var(--sinn);
  border-radius: 0 5px 5px 0;
  font-family: var(--display);
  font-size: 0.84rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

.retrieval-fussnoten {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
  display: grid;
  gap: 1rem;
}

.retrieval-fussnote {
  font-family: var(--display);
  font-size: 0.82rem;
  color: var(--ink-muted);
  max-width: var(--measure);
  line-height: 1.6;
  margin: 0;
}

.retrieval-fussnote strong { color: var(--ink-soft); font-weight: 600; }

@media (prefers-reduced-motion: no-preference) {
  .retrieval-treffer,
  .retrieval-beleg,
  .retrieval-knoten rect {
    transition: fill 0.15s ease, stroke-width 0.15s ease, background-color 0.15s ease;
  }
}
