/* ============================================================
   WIP Verlag — Design-System „Galerie" (Etappe 0, Task 9)
   Referenz: companion/screen-004c-galerie.html
   Sanft salbeigrüne Leinwand, frei schwebende weiße Karten,
   Glas-Topbar, Pillen-Buttons, Akzent Tannengrün.
   Alle späteren Etappen bauen auf diesen Custom Properties auf.
   ============================================================ */

:root {
  /* Leinwand (Verlaufs-Familie) */
  --canvas: #e9f0e8;
  --canvas-mid: #e4ede3;
  --canvas-deep: #dde8de;
  --canvas-glow: #f2f6ef;

  /* Flächen */
  --card: #fdfefd;
  /* Reserviert für Etappe 1 (Buchseiten-Ansicht: Papierton der gerenderten Seite) */
  --paper: #fbfaf5;

  /* Text — AA-geprüft (WCAG 2.x, >=4.5:1): --muted auf Glas-Topbar 5.9:1 /
     Karte 6.2:1; --faint auf Karte 5.1:1 UND --sage-soft 4.7:1. Hierarchie
     bleibt: ink dunkler als muted, muted sichtbar dunkler als faint. */
  --ink: #26332b;
  --muted: #52645a;
  --faint: #5f7166;

  /* Salbei-Töne (Ränder, Chips, ruhige Flächen) */
  --sage: #cdddd0;
  --sage-soft: #eef4ee;
  --sage-mid: #a9c1ae;

  /* Akzent Tannengrün */
  --accent: #0e6e4f;
  --accent-deep: #0a5039;
  --accent-soft: #ddebe0;
  /* Reserviert für Etappe 2 (Terminal/Editor-Bedienflächen: weicher Fokus-Ring
     auf farbigen Flächen, wo der harte Outline zu laut wäre) */
  --accent-ring: rgba(14, 110, 79, 0.18);

  /* Fehler (gedeckt, zur Palette passend) */
  --danger: #a8433a;
  --danger-soft: #f9edea;
  --danger-border: #ecd5cf;

  /* Warnung — gedecktes Amber, zur Salbei/Tannengrün-Palette passend. Trägt
     (wie --danger) eine Doppelrolle: Chip-Text UND Akzentkante der Wording-
     Warnungen (Etappe 4). Kontrast --amber-Text auf --amber-soft = 6.6:1
     (WCAG 2.x >=4.5:1; dieselbe geprüfte Paarung wie status-chip--layout). */
  --amber: #6b4d14;
  --amber-soft: #f7ecd2;
  --amber-border: #ecdcb0;

  /* Terminal (Etappe 2): dunkle Karte in Grün-Anthrazit. terminal.ts liest
     diese Tokens zur Laufzeit (getComputedStyle) für das xterm-Theme —
     --term-bg MUSS dem xterm-Hintergrund entsprechen, sonst franst das
     Zeilenraster sichtbar gegen die Karte aus. */
  --term-bg: #17221d;
  --term-bg-head: #1c2a24;
  --term-ink: #d8e4dc;
  --term-muted: #8fa397;
  --term-cursor: #7ec8a8;
  --term-selection: rgba(126, 200, 168, 0.3);
  --term-border: rgba(255, 255, 255, 0.08);

  /* Radien */
  --radius-card: 18px;
  --radius-input: 12px;
  --radius-pill: 999px;

  /* Mehrschicht-Schatten (schwebende Karten) */
  --shadow-sm: 0 1px 2px rgba(30, 46, 36, 0.05), 0 4px 14px rgba(30, 46, 36, 0.07);
  --shadow-md: 0 1px 2px rgba(30, 46, 36, 0.05), 0 8px 24px rgba(30, 46, 36, 0.09),
    0 28px 56px -28px rgba(30, 46, 36, 0.18);
  --shadow-lg: 0 2px 4px rgba(30, 46, 36, 0.06), 0 14px 34px rgba(30, 46, 36, 0.11),
    0 40px 80px -32px rgba(30, 46, 36, 0.24);
  --shadow-accent: 0 10px 22px -8px rgba(10, 80, 57, 0.55);

  /* Schrift */
  --font-sans: ui-rounded, "SF Pro Rounded", Seravek, "Gill Sans", "Trebuchet MS",
    Avenir, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-serif: "Iowan Old Style", Charter, "Palatino Linotype", Palatino, Georgia,
    Cambria, serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
    "Liberation Mono", monospace;
}

/* ---------- Basis ---------- */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html {
  height: 100%;
}

body {
  min-height: 100vh;
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  background:
    radial-gradient(120% 90% at 12% -10%, var(--canvas-glow) 0%, rgba(242, 246, 239, 0) 55%),
    radial-gradient(110% 100% at 100% 110%, var(--canvas-deep) 0%, rgba(221, 232, 222, 0) 60%),
    linear-gradient(160deg, var(--canvas) 0%, var(--canvas-mid) 55%, var(--canvas-deep) 100%);
}

/* Werkstatt füllt das Fenster EXAKT und scrollt NICHT (die Raster-Ansicht
   blättert statt zu scrollen). Ohne das lässt body{min-height:100vh} den Body
   über die Fensterhöhe hinauswachsen → Dokument-Scrollleiste. Nur auf breiten
   Fenstern: ab ≤960px stapeln Viewer/Terminal/Marker untereinander und die
   Seite DARF dann scrollen. Innere Panels (Terminal, Marker-Liste) haben eigene
   overflow:auto — die scrollen weiter für sich. */
@media (min-width: 961px) {
  body.page-werkstatt,
  body.page-editor {
    /* page-editor ebenfalls (Frank 2026-07-07): auch der Editor füllt das
       Fenster exakt — Kapitel-Liste, Textarea und Wording-Body scrollen
       intern (deren overflow:auto existiert bereits). */
    height: 100vh;
    min-height: 0;
    overflow: hidden;
  }
}

svg {
  display: block;
}

/* Icon-Slots: client.ts injiziert inline-SVGs aus icons.ts in [data-icon] */
[data-icon] {
  display: inline-flex;
  width: 18px;
  height: 18px;
  flex: none;
}

[data-icon] svg {
  width: 100%;
  height: 100%;
}

/* Sichtbarer Fokus im Akzent (Tastatur-Bedienung); der Umriss folgt dem
   border-radius des Elements (Pillen bleiben Pillen). */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

::selection {
  background: var(--accent-soft);
  color: var(--accent-deep);
}

/* Einschwebe-Animation der Karten */
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.float {
  animation: rise 0.55s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

/* ---------- Karte ---------- */

.card {
  background: var(--card);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-md);
}

/* ---------- Marke ---------- */

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
}

.brand-tile {
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: linear-gradient(150deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 6px 14px -4px rgba(10, 80, 57, 0.45);
  flex: none;
}

.brand-tile [data-icon] {
  width: 19px;
  height: 19px;
}

.brand-name {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 17.5px;
  letter-spacing: 0.01em;
  line-height: 1.15;
  white-space: nowrap;
}

.brand-sub {
  font-size: 11.5px;
  color: var(--muted);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* ---------- Pillen-Buttons ---------- */

.pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  background: var(--card);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--radius-pill);
  padding: 9px 18px;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.pill-btn:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.pill-btn:active {
  transform: none;
  box-shadow: var(--shadow-sm);
}

.pill-btn:disabled {
  opacity: 0.55;
  cursor: default;
  transform: none;
  box-shadow: var(--shadow-sm);
}

.pill-btn [data-icon] {
  color: var(--accent);
  width: 17px;
  height: 17px;
}

/* Umschalt-Pillen (aria-pressed, z. B. Editor-„Umbruch"): gedrückt = sanft
   akzentgetönt, damit der Zustand ohne Blick auf den Text erkennbar ist. */
.pill-btn[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent-deep);
}

.pill-btn--primary {
  background: linear-gradient(150deg, var(--accent) 0%, var(--accent-deep) 100%);
  border-color: var(--accent-deep);
  color: #fff;
  box-shadow: var(--shadow-accent), var(--shadow-sm);
}

.pill-btn--primary [data-icon] {
  color: #fff;
}

.pill-btn--primary:hover {
  box-shadow: 0 14px 28px -8px rgba(10, 80, 57, 0.6), var(--shadow-md);
}

/* ---------- Eingabefelder ---------- */

.input-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
}

.input-field label {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.input-field input {
  font-family: var(--font-sans);
  font-size: 15.5px;
  color: var(--ink);
  background: #fbfdfb;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  padding: 11px 14px;
  width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.input-field input::placeholder {
  color: var(--faint);
}

.input-field input:hover {
  border-color: var(--sage-mid);
}

.input-field input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

/* Auswahlfelder (Musterkapitel-Dialog) — gleiche Optik wie die Eingaben */
.input-field select {
  font-family: var(--font-sans);
  font-size: 15.5px;
  color: var(--ink);
  background: #fbfdfb;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  padding: 11px 14px;
  width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.input-field select:hover {
  border-color: var(--sage-mid);
}

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

.input-field select:disabled {
  color: var(--faint);
  cursor: default;
}

/* ---------- Fehlermeldung ---------- */

.error-box {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid var(--danger-border);
  border-radius: var(--radius-input);
  padding: 10px 13px;
  text-align: left;
}

.error-box [data-icon] {
  width: 16px;
  height: 16px;
  margin-top: 1.5px;
}

/* ============================================================
   Login-Seite
   ============================================================ */

.page-login {
  display: grid;
  place-items: center;
  padding: 32px 20px;
}

.login-wrap {
  width: min(400px, 100%);
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.login-card {
  padding: 44px 40px 36px;
  box-shadow: var(--shadow-lg);
  text-align: center;
}

.login-card .brand-tile {
  width: 46px;
  height: 46px;
  border-radius: 14px;
  margin: 0 auto 18px;
}

.login-card .brand-tile [data-icon] {
  width: 23px;
  height: 23px;
}

.wordmark {
  font-family: var(--font-serif);
  font-size: 29px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.login-sub {
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-top: 6px;
}

.login-rule {
  width: 52px;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
  opacity: 0.65;
  margin: 18px auto 26px;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.login-form .pill-btn--primary {
  margin-top: 6px;
  padding: 12px 20px;
  font-size: 15px;
}

.login-footer {
  text-align: center;
  font-size: 12.5px;
  /* muted statt faint: liegt direkt auf der Leinwand (dunkelster Verlaufston
     #dde8de) — dort schafft nur muted die 4.5:1 (5.0:1). */
  color: var(--muted);
  letter-spacing: 0.04em;
}

/* ============================================================
   App-Seite (Regal-Platzhalter)
   ============================================================ */

.page-app {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px 22px 14px;
}

/* Glas-Topbar */
.topbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 18px;
  background: rgba(255, 255, 255, 0.58);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid rgba(255, 255, 255, 0.75);
  border-radius: 20px;
  box-shadow: var(--shadow-md);
  padding: 12px 20px;
  /* Schmale Fenster (Feinschliff-Backlog, Media-Explorer-Audit): Buttons
     brechen um, statt über den Rand hinauszulaufen (wie die Kartenköpfe,
     Commit 2987214). */
  flex-wrap: wrap;
  row-gap: 8px;
}

.topbar .spacer {
  margin-left: auto;
}

/* Hauptfläche: zentriert die Leer-/Fehlerkarte; das Bücher-Grid dockt per
   align-self oben an (genau EIN Kind ist sichtbar — regal.ts schaltet um). */
.shelf {
  flex: 1;
  display: grid;
  place-items: center;
  padding: 24px 0;
}

.empty-state {
  width: min(460px, 100%);
  padding: 52px 44px 44px;
  box-shadow: var(--shadow-lg);
  text-align: center;
}

.empty-state .badge {
  width: 74px;
  height: 74px;
  border-radius: 50%;
  background: var(--sage-soft);
  border: 1px solid var(--sage);
  display: grid;
  place-items: center;
  margin: 0 auto 22px;
  color: var(--accent);
}

.empty-state .badge [data-icon] {
  width: 32px;
  height: 32px;
}

.empty-state h1 {
  font-family: var(--font-serif);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: 0.005em;
  margin-bottom: 10px;
}

.empty-state .lead {
  font-size: 15px;
  color: var(--muted);
  line-height: 1.6;
  margin-bottom: 26px;
}

.hint-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--faint);
  background: var(--sage-soft);
  border: 1px dashed var(--sage-mid);
  border-radius: var(--radius-pill);
  padding: 7px 15px;
}

.hint-chip [data-icon] {
  width: 15px;
  height: 15px;
  color: var(--sage-mid);
}

.hint-chip .book-num {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
}

/* Fehlerkarte: gleiche Bühne wie die Leerkarte, Badge in Gedecktrot */
.empty-state .badge--danger {
  background: var(--danger-soft);
  border-color: var(--danger-border);
  color: var(--danger);
}

/* ============================================================
   Bücherregal (Etappe 1, Task 6)
   ============================================================ */

/* Galerie-Grid: schwebende Buch-Karten auf der Leinwand */
.book-grid {
  width: min(1140px, 100%);
  align-self: start;
  justify-self: center;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 18px;
  padding: 4px 2px 20px;
}

/* Buch-Karte: links der stilisierte Buchrücken (Akzentleiste), innen
   Kopfzeile (Mono-Nummer + Status-Chip), Serif-Titel, Thema, Öffnen-Pille.
   overflow hidden schneidet den Rücken bündig in die Kartenrundung. */
.book-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-height: 178px;
  padding: 18px 20px 18px 31px;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.book-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

/* Buchrücken: schmale Leiste im Akzentverlauf, mit Lichtkante links und
   leichter Falzschattierung rechts — bewusst CSS statt PDF-Thumbnail
   (Livebild kommt in Etappe 2). */
.book-spine {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 11px;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%);
  /* rgba(6,42,29,.3): abgedunkelter --accent-deep-Ton für den Falz —
     bewusst kein Token (einmalige Verwendung) */
  box-shadow:
    inset 1.5px 0 0 rgba(255, 255, 255, 0.22),
    inset -2px 0 3px rgba(6, 42, 29, 0.3);
}

.book-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

/* Cover-Thumbnail (Etappe 2, Task 5): Seite 1 des Print-PDFs, gerendert von
   thumb.js in ein Canvas. Der Anker bleibt hidden, bis das Rendern gelang —
   Lade- UND Fallback-Ästhetik ist der Buchrücken (.book-spine). Schmaler
   Salbei-Rahmen + kleiner Schatten lassen die Miniatur wie ein aufgelegtes
   Blatt auf der Karte wirken. */
.book-cover {
  margin: 3px 0 1px;
}

.book-cover canvas {
  display: block;
  /* Puffer wird in Gerätepixeln gerendert (~180px × dpr); hier zählt nur
     die CSS-Breite — auf schmalen Karten klemmt min() sie auf die Karte. */
  width: min(180px, 100%);
  height: auto;
  background: var(--card);
  border: 1px solid var(--sage);
  border-radius: 4px;
  box-shadow: var(--shadow-sm);
}

.book-card-num {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.09em;
  color: var(--muted);
}

.book-card-title {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.005em;
  line-height: 1.3;
  margin-top: 1px;
}

.book-card-thema {
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.book-card-foot {
  margin-top: auto;
  padding-top: 8px;
  display: flex;
}

/* Öffnen ist ein Link in Pillen-Optik */
a.pill-btn {
  text-decoration: none;
}

.book-card-foot .pill-btn {
  padding: 7px 15px 7px 17px;
  font-size: 13.5px;
}

.book-card-foot .pill-btn [data-icon] {
  transition: transform 0.18s ease;
}

.book-card-foot .pill-btn:hover [data-icon] {
  transform: translateX(2px);
}

/* Status-Chips: farbcodierte Pastelltöne, Text dunkel auf hell.
   Kontraste (WCAG 2.x, berechnet): idee 7.44:1, manuskript 7.48:1,
   layout 6.63:1, review 7.25:1, veroeffentlicht 6.67:1 — alle >= 4.5:1. */
.status-chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid;
  border-radius: var(--radius-pill);
  padding: 4px 11px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
  flex: none;
}

.status-chip--idee {
  color: #414d45;
  background: #e9ece9;
  border-color: #d6dbd6;
}

.status-chip--manuskript {
  color: #2e4a66;
  background: #dfe9f4;
  border-color: #c8d9ea;
}

.status-chip--layout {
  color: #6b4d14;
  background: #f7ecd2;
  border-color: #ecdcb0;
}

.status-chip--review {
  color: #54406e;
  background: #ebe4f4;
  border-color: #dacfec;
}

.status-chip--veroeffentlicht {
  color: #0e5c40;
  background: #dcefe2;
  border-color: #c2e2cd;
}

/* ============================================================
   Neues-Buch-Dialog (natives <dialog>, Galerie-Karte)
   ============================================================ */

.dialog-card {
  /* UA-Defaults ersetzen: gleiche Karten-Optik wie das Regal */
  /* Falle: der globale *-Reset (margin: 0) überschreibt das UA-Stylesheet
     `dialog { margin: auto }` — ohne dieses margin klebt jedes <dialog>
     oben links in seiner fixed-inset(0)-Box. margin: auto zentriert das
     Modal wieder vertikal UND horizontal (gilt für ALLE App-Dialoge). */
  margin: auto;
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-lg);
  padding: 30px 30px 26px;
  width: min(430px, calc(100vw - 40px));
}

.dialog-card[open] {
  animation: rise 0.3s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

.dialog-card::backdrop {
  background: rgba(30, 46, 36, 0.34);
  backdrop-filter: blur(2.5px);
}

.dialog-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.dialog-head {
  margin-bottom: 6px;
}

.dialog-head h2 {
  font-family: var(--font-serif);
  font-size: 21px;
  font-weight: 600;
  letter-spacing: 0.005em;
}

.dialog-sub {
  font-size: 13px;
  color: var(--muted);
  margin-top: 3px;
}

.field-hint {
  font-size: 12px;
  color: var(--faint);
  line-height: 1.4;
}

.label-optional {
  font-size: 10.5px;
  font-weight: 400;
  color: var(--faint);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  margin-left: 4px;
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 8px;
}

/* Zentrales Modal (modal.ts): kompakte Karte für bestaetigeModal/eingabeModal
   (Ersatz für confirm/alert/prompt — Projektregel). Erbt Optik/Animation von
   .dialog-card, nur schmaler als der Neues-Buch-Dialog. */
.modal-card {
  max-width: 26rem;
}

/* Eingabefeld/-Label wie .input-field, hier ohne umschließenden Wrapper
   (modal.ts hat kein <div class="input-field">, das Label steht direkt vor
   dem Feld). */
.modal-eingabe-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.modal-eingabe {
  font-family: var(--font-sans);
  font-size: 15.5px;
  color: var(--ink);
  background: #fbfdfb;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  padding: 11px 14px;
  width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.modal-eingabe:hover {
  border-color: var(--sage-mid);
}

.modal-eingabe:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

/* Gefahr-Knopf (endgültiges Löschen, gefaehrlich: true) — dieselbe Bauart wie
   .pill-btn--primary, nur in der Fehler-Rottönung statt Tannengrün. */
.pill-btn--gefahr {
  background: linear-gradient(150deg, var(--danger) 0%, #7c322b 100%);
  border-color: #7c322b;
  color: #fff;
  box-shadow: 0 10px 22px -8px rgba(168, 67, 58, 0.55), var(--shadow-sm);
}

.pill-btn--gefahr:hover {
  box-shadow: 0 14px 28px -8px rgba(168, 67, 58, 0.6), var(--shadow-md);
}

/* Bislang wurde .pill-btn--gefahr nur textlich verwendet (modal.ts hat kein
   Icon im Bestätigen-Knopf) — der Papierkorb ist die erste Stelle mit einem
   Icon IN einem Gefahr-Knopf, daher fehlte dieses Gegenstück zu
   .pill-btn--primary [data-icon] bislang (sonst bliebe das Icon grün auf
   rotem Grund, geerbt von der Basisregel .pill-btn [data-icon]). */
.pill-btn--gefahr [data-icon] {
  color: #fff;
}

/* Papierkorb-Dialog (papierkorb.ts, Task 10) — erbt Karten-Optik/Animation von
   .dialog-card, breiter als der zentrale .modal-card (mehrzeilige Liste statt
   einer Frage). Zeilen im gleichen Karten-Duktus wie .dateien-eintrag
   (Sage-Rahmen statt Trennlinie), damit Regal und Werkstatt denselben Dialog
   konsistent zeigen. */
.papierkorb-dialog {
  max-width: 42rem;
  width: min(42rem, 92vw);
}

.papierkorb-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 55vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.papierkorb-eintrag {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px 10px;
  padding: 10px 12px;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  background: var(--sage-soft);
}

/* Nur das Typ-Icon (Nadel/Blatt) — bewusst NICHT [data-icon] allgemein, sonst
   überschriebe das auch die Aktions-Icons (Wiederherstellen/Löschen) in ihrer
   Knopf-Farbe (.pill-btn/.pill-btn--gefahr [data-icon]). */
.papierkorb-typ-icon {
  display: inline-flex;
  color: var(--accent);
}
.papierkorb-typ-icon svg {
  width: 18px;
  height: 18px;
}

.papierkorb-text {
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  padding: 0;
  font-size: 13px;
  color: var(--ink);
}

.papierkorb-wann {
  font-size: 11.5px;
  color: var(--faint);
  white-space: nowrap;
}

.papierkorb-crop {
  grid-column: 2;
  max-height: 4rem;
  max-width: 12rem;
  border-radius: 6px;
  border: 1px solid var(--sage);
}

.papierkorb-aktionen {
  grid-column: 2 / 4;
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}

/* Statusleiste */
.statusbar {
  flex: none;
  display: flex;
  justify-content: center;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  /* Eine Nuance dunkler als das Karten-Weiß (Frank, 2026-07-06):
     canvas-mid-Ton statt reinem Weiß, Glas-Effekt bleibt. */
  background: rgba(228, 237, 227, 0.78);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-sm);
  padding: 7px 18px;
  font-size: 12.5px;
  color: var(--muted);
}

.status-pill b {
  color: var(--ink);
  font-weight: 600;
}

.status-pill .mid {
  color: var(--sage-mid);
}

.pulse {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  position: relative;
  flex: none;
}

.pulse::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  opacity: 0;
  animation: ping 2.2s ease-out infinite;
}

@keyframes ping {
  0% {
    transform: scale(0.5);
    opacity: 0.7;
  }
  70%,
  100% {
    transform: scale(1.3);
    opacity: 0;
  }
}

/* Gestaffelte Einblendung */
.topbar.float {
  animation-delay: 0.02s;
}

.empty-state.float {
  animation-delay: 0.12s;
}

.statusbar.float {
  animation-delay: 0.22s;
}

.login-card.float {
  animation-delay: 0.02s;
}

.login-footer.float {
  animation-delay: 0.16s;
}

/* ============================================================
   Buch-Werkstatt (Etappe 1, Task 7)
   ============================================================ */

/* Topbar-Überschrift: Serif-Buchtitel + Status-Chip neben der Zurück-Pille */
.wk-heading {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding-left: 4px;
}

.wk-titel {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 600;
  letter-spacing: 0.005em;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Werkstatt-Bühne: PDF-Vorschau, Terminal und Marker laufen als
   gridstack.js-Kacheln (12 Spalten, float-Modus — siehe .werkstatt und
   .grid-stack-item-content weiter unten, Spec 2026-07-06); die Positionierung
   übernimmt gridstack, hier nur noch die Karten-eigene Flex-Innerei. */
.viewer-card {
  display: flex;
  flex-direction: column;
  /* min-height:0, sonst wächst die Karte auf ihren Inhalt (Bühne) und
     sprengt die Kachel. */
  min-height: 0;
  overflow: hidden;
}

.viewer-toolbar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--sage-soft);
  /* Schmale Kacheln (Minimum 2 Spalten, Frank 2026-07-06): Werkzeuggruppen
     brechen um, statt sich zu überlappen. */
  flex-wrap: wrap;
  row-gap: 6px;
}

/* Musterkapitel-Leiste (Etappe 2, Task 4): Varianten-Pillen A/B/C + „Zurück
   zum Buch" über der Toolbar, dezent akzentgetönt abgesetzt. */
.muster-leiste {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 14px;
  padding: 10px 16px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--sage-soft);
}

.muster-buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Aktive Variante: gefüllte Akzent-Pille (aria-pressed trägt den Zustand,
   die Optik folgt dem pill-btn--primary-Duktus). */
.muster-variante[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: #f2f8f4;
  box-shadow: var(--shadow-accent);
}

.muster-seiten {
  font-size: 11.5px;
  color: var(--faint);
}

.muster-variante[aria-pressed="true"] .muster-seiten {
  color: rgba(242, 248, 244, 0.75);
}

.muster-hinweis {
  font-size: 12.5px;
  color: var(--muted);
}

.toolbar-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Runde Werkzeug-Buttons (nur Icon) für Blättern und Zoom */
.tool-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--sage);
  background: var(--card);
  color: var(--accent);
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.tool-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

.tool-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Gedrückter Werkzeug-Toggle (z. B. Satzspiegel-Overlay ein): gefüllter
   Akzent-Knopf — sichtbar anders als der Ruhezustand. */
.tool-btn--aktiv {
  background: var(--accent);
  border-color: var(--accent-deep);
  color: #fff;
  box-shadow: var(--shadow-sm);
}

.tool-btn--aktiv:hover:not(:disabled) {
  color: #fff;
}

.tool-btn [data-icon] {
  width: 16px;
  height: 16px;
}

.page-indicator {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--muted);
}

.page-indicator input {
  width: 46px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink);
  background: #fbfdfb;
  border: 1px solid var(--sage);
  border-radius: 9px;
  padding: 5px 4px;
  transition: border-color 0.15s ease;
}

.page-indicator input:hover:not(:disabled) {
  border-color: var(--sage-mid);
}

.page-indicator input:disabled {
  opacity: 0.5;
}

.page-sep {
  color: var(--sage-mid);
}

.page-total {
  font-family: var(--font-mono);
  font-size: 13px;
}

/* Raster-Umschalter (Dichte 1·2·4·9·16): Segment-Leiste, aktives Segment als
   erhabene Karte im Akzent. Zahlen als Text (KEINE Emojis, keine Icons). */
.layout-umschalter {
  gap: 3px;
  padding: 3px;
  background: var(--sage-soft);
  border-radius: 12px;
}

.layout-btn {
  min-width: 30px;
  height: 28px;
  padding: 0 8px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.layout-btn:hover:not(:disabled) {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.6);
}

.layout-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.layout-btn[aria-pressed="true"] {
  background: var(--card);
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}

/* Positionsanzeige „Seiten a–b von N": ruhige, monospacige Mitte zwischen
   den Blätter-Knöpfen. */
.blatt-position {
  min-width: 128px;
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Bühne (Etappe 3, Task 1): vertiefte Leinwand-Fläche für die pdfjs-
   PDFViewer-Komponente (virtueller Scroll). Die Komponente verlangt einen
   ABSOLUT positionierten Scroll-Container — .viewer-buehne spannt dafür den
   relativen Rahmen, trägt die Leinwand-Optik und zentriert als Flex-Fläche
   die Hinweiskarten (Laden/Leer/Fehler), die über der Bühne liegen. */
.viewer-buehne {
  position: relative;
  flex: 1;
  display: flex;
  /* min-height als Floor für sehr flache Fenster; KEIN max-height mehr — die
     Bühne füllt jetzt die ganze Karte (Raster passt sich dem Fenster an). */
  min-height: 0;
  background: linear-gradient(180deg, var(--canvas-mid) 0%, var(--canvas-deep) 100%);
  box-shadow: inset 0 2px 8px rgba(30, 46, 36, 0.06);
}

/* Bühne: füllt den relativen Rahmen (.viewer-buehne) absolut aus und trägt das
   Raster-Grid. overflow:hidden ist tragend — die Raster-Ansicht blättert, sie
   scrollt nie (die Seiten fitten je Blatt exakt hinein). */
.viewer-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  padding: 12px;
}

/* Bühne verbergen, solange eine Hinweiskarte gilt: visibility statt
   display:none, damit das Grid seine Maße behält — der RasterViewer misst
   clientWidth/clientHeight fürs Fitten (display:none brächte sie auf 0). */
.viewer-stage[data-verdeckt] {
  visibility: hidden;
}

/* Raster-Grid: füllt die Bühne, verteilt die Zellen gleichmäßig (1fr) und
   zentriert deren Inhalt. Der RasterViewer setzt grid-template-columns/-rows
   je Dichte (1·2·4·9·16) zur Laufzeit; gap trennt die Blätter dezent. */
#wk-grid {
  display: grid;
  gap: var(--raster-gap, 10px);
  width: 100%;
  height: 100%;
  place-items: center;
}

/* Zelle: zentriert die (skaliert eingepasste) Seite und klemmt jeden
   Rest-Überstand ab (kein Scroll, kein Überlappen der Nachbarn). */
.raster-zelle {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* Galerie-Optik der Seiten: schwebende Blätter im --paper-Ton auf der
   Salbei-Leinwand. position:relative ist PFLICHT — das Marker-Overlay
   (marker.ts) positioniert seine Pins/Rahmen absolut IN der .page. */
.page {
  position: relative;
  background: var(--paper);
  border-radius: 2px;
  box-shadow: var(--shadow-lg);
}

/* Bühnen-Hinweise: Laden / noch kein PDF / Fehler. position:relative +
   z-index heben sie über den absolut positionierten Scroll-Container —
   der ist zwar verdeckt (visibility), aber positioniert und läge sonst
   in der Malreihenfolge obenauf. */
.stage-note {
  margin: auto;
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: 460px;
  padding: 26px;
  text-align: center;
  font-size: 14.5px;
  color: var(--muted);
}

.stage-note h2 {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
}

.stage-note .badge {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: var(--card);
  border: 1px solid var(--sage);
  display: grid;
  place-items: center;
  color: var(--accent);
  box-shadow: var(--shadow-sm);
}

.stage-note .badge [data-icon] {
  width: 26px;
  height: 26px;
}

.stage-note .badge--danger {
  background: var(--danger-soft);
  border-color: var(--danger-border);
  color: var(--danger);
}

.stage-note .pill-btn {
  margin-top: 6px;
}

/* ============================================================
   Marker (Etappe 3, Task 4)
   ============================================================ */

/* Schwebender Stift-Button auf der PDF-Bühne (Design §7): runder Galerie-
   Knopf oben rechts, aktiv als gefüllte Akzent-Fläche (aria-pressed).
   right > Scrollbar-Breite, damit er die Bühnen-Scrollbar nicht verdeckt. */
.stift-btn {
  position: absolute;
  top: 14px;
  right: 26px;
  z-index: 3;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--sage);
  background: var(--card);
  color: var(--accent);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: var(--shadow-md);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.stift-btn:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.stift-btn[aria-pressed="true"] {
  background: linear-gradient(150deg, var(--accent) 0%, var(--accent-deep) 100%);
  border-color: var(--accent-deep);
  color: #fff;
  box-shadow: var(--shadow-accent), var(--shadow-sm);
}

.stift-btn [data-icon] {
  width: 20px;
  height: 20px;
}

/* Markieren-Modus: Fadenkreuz auf den Seiten; der Textlayer wird
   zeigerdurchlässig, damit Klick/Drag nicht in der Textauswahl landet. */
.viewer-stage.markieren-aktiv {
  cursor: crosshair;
}

.markieren-aktiv .textLayer {
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

/* Overlay pro Seite: absolut aufgespannt, komplett zeigerdurchlässig —
   marker.ts baut es bei jedem pagerendered NEU auf (virtueller Scroll
   zerstört Seiten; Positionen in px des aktuellen Zooms). */
.marker-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
}

/* Muster-Ansicht: Marker gehören zum Hauptbuch — Overlays komplett aus
   (marker.ts setzt die Klasse auf der Bühne, solange eine Variante offen ist). */
.marker-verborgen .marker-overlay {
  display: none;
}

/* Satzspiegel-Overlay (Spec 2026-07-07): Textflächen-Rahmen als Bildschirm-
   Hilfe über jeder gerenderten Seite (alle Layouts 1/2/4). satzspiegel.ts
   setzt das Div absolut IN die .page (position:relative dort).
   pointer-events:none — der Markieren-Modus behält seine Klicks. Liegt UNTER
   dem Marker-Overlay (z-index 4), damit Pins und Rahmen-Marker obenauf
   sichtbar bleiben. Dezente, zurückhaltende Grau-Linie (kein Akzent-Grün),
   kein Fill; die feine Lichtkante hebt sie leise vom Papier ab. */
.satzspiegel-rahmen {
  position: absolute;
  z-index: 3;
  box-sizing: border-box;
  border: 1px solid rgba(90, 90, 90, 0.15);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35);
  pointer-events: none;
}

/* Punkt-Marker: Pin, dessen Nadelspitze auf den markierten Punkt zeigt. */
.marker-pin {
  position: absolute;
  width: 26px;
  height: 26px;
  transform: translate(-50%, -100%);
  color: var(--accent);
  filter: drop-shadow(0 2px 3px rgba(30, 46, 36, 0.35));
}

.marker-pin [data-icon] {
  width: 100%;
  height: 100%;
}

/* Erledigt: grüner Haken in runder Akzent-Plakette statt Pin (sichtbar bis
   zum Reload — schlicht, kein Ausblenden). */
.marker-pin[data-zustand="erledigt"] {
  width: 22px;
  height: 22px;
  padding: 3px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  transform: translate(-50%, -50%);
  filter: none;
  box-shadow: var(--shadow-sm);
}

/* Veraltet: gedimmt (der Rahmen zusätzlich gestrichelt, s. u.). */
.marker-pin[data-zustand="veraltet"] {
  color: var(--faint);
  opacity: 0.55;
}

/* Rahmen-Marker: Akzent-Rand mit hauchdünner Lichtkante. */
.marker-rahmen {
  position: absolute;
  border: 2px solid var(--accent);
  border-radius: 3px;
  background: rgba(14, 110, 79, 0.08);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5);
}

.marker-rahmen[data-zustand="veraltet"] {
  border-style: dashed;
  border-color: var(--faint);
  background: rgba(95, 113, 102, 0.06);
  opacity: 0.55;
}

.marker-rahmen[data-zustand="erledigt"] {
  border-color: var(--accent);
  background: transparent;
}

/* Haken-Plakette an der Ecke eines erledigten Rahmens. */
.marker-rahmen-haken {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-sm);
}

.marker-rahmen-haken [data-icon] {
  width: 11px;
  height: 11px;
}

/* Ghost-Rechteck während des Aufziehens (und der Pin-Entwurf, solange das
   Popover offen ist): gestrichelte Vorschau im Akzent. */
.marker-ghost {
  position: absolute;
  border: 2px dashed var(--accent);
  border-radius: 3px;
  background: rgba(14, 110, 79, 0.1);
  pointer-events: none;
  z-index: 5;
}

.marker-pin--entwurf {
  z-index: 5;
  opacity: 0.85;
}

/* Kommentar-Popover: kleine Galerie-Karte, absolut auf der Bühne (marker.ts
   klemmt sie an die Ränder). */
.marker-popover {
  position: absolute;
  z-index: 6;
  width: min(300px, calc(100% - 24px));
  display: flex;
  flex-direction: column;
  gap: 9px;
  background: var(--card);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
  padding: 14px;
  animation: rise 0.25s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

.marker-popover-label {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.02em;
}

.marker-popover textarea {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink);
  background: #fbfdfb;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  padding: 9px 11px;
  resize: vertical;
  min-height: 64px;
}

.marker-popover textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}

.marker-popover-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.marker-popover .pill-btn {
  padding: 7px 14px;
  font-size: 13px;
}

/* ---------- Marker-Karte (rechte Spalte, unter dem Terminal) ---------- */

.marker-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

.marker-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--sage-soft);
  /* Schmale Kacheln: Kopf bricht um, statt dass sich Titel und
     Abarbeiten-Knopf überlappen (Franks Screenshot 2026-07-06). */
  flex-wrap: wrap;
  row-gap: 6px;
}

/* Kopf-Button klappt den Karten-Körper ein/aus (aria-expanded + hidden). */
.marker-toggle {
  /* NICHT schrumpfen lassen (flex-shrink 0): mit min-width:0 schrumpfte der
     Button unter seine Inhaltsbreite, der „offen"-Zähler lief sichtbar über
     den Abarbeiten-Knopf, und der flex-wrap der Kopfzeile griff nie
     (Franks Screenshot 2026-07-06). Ohne Schrumpfen erzwingt eine schmale
     Kachel den Umbruch. */
  flex: 1 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: 0;
  padding: 4px 2px;
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  border-radius: 8px;
}

.marker-toggle > [data-icon] {
  color: var(--accent);
}

.marker-titel {
  font-family: var(--font-serif);
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.marker-zaehler {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  white-space: nowrap;
}

.marker-chevron {
  margin-left: auto;
  color: var(--sage-mid);
  transition: transform 0.18s ease;
}

.marker-toggle[aria-expanded="true"] .marker-chevron {
  transform: rotate(90deg);
}

.marker-abarbeiten {
  flex: none;
  padding: 7px 14px;
  font-size: 13px;
}

/* Karten-Körper: scrollt intern, damit viele Marker den Rest der Karte nicht
   sprengen. KEIN max-height mehr (Spec 2026-07-06) — die Kachel-Höhe legt
   Frank per gridstack fest, der Körper füllt sie bis zum Rand.
   flex:1 + min-height:0 sind PFLICHT (bekannte Flexbox-Falle, vgl.
   .werkstatt): als Flex-Kind hätte der Körper min-height:auto und würde nie
   unter seine Inhaltshöhe schrumpfen — overflow:auto griffe dann nie, die
   Karte (overflow:hidden) schnitte die Liste stattdessen unerreichbar ab. */
.marker-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 12px 14px;
}

.marker-leer {
  font-size: 13.5px;
  color: var(--muted);
}

.marker-liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Kompaktzeile (Spec 2026-07-06): Mini-Thumb + Seite + Chip + 1-Zeilen-
   Kommentar bilden den Sprung-Button zur Seite; Pfeil/Papierkorb sind
   eigene Geschwister-Buttons rechts in der Zeile. */
.marker-zeile {
  display: flex;
  align-items: center;
  gap: 6px;
}

.marker-sprung {
  flex: 1;
  min-width: 0; /* Kommentar-Ellipse braucht schrumpfbaren Flex-Kontext */
  display: flex;
  /* Umbruch-Erlaubnis gegen die 0px-Falle: die festen flex:none-Nachbarn
     (Mini 44px + Seite + Chip) verbrauchen in schmalen Kacheln die ganze
     Breite — mit min-width:0 würde der Kommentar auf 0px schrumpfen und
     unsichtbar. Mit wrap + min-width am Kommentar bricht er stattdessen
     als volle zweite Zeile um (dort weiter einzeilig mit Ellipse). */
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font: inherit;
  text-align: left;
  color: var(--ink);
  background: var(--sage-soft);
  border: 1px solid var(--sage);
  border-radius: 14px 14px 14px 4px;
  padding: 6px 10px;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.marker-sprung:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

.marker-eintrag[data-zustand="veraltet"] .marker-sprung {
  opacity: 0.62;
  border-style: dashed;
}

.marker-eintrag[data-zustand="erledigt"] .marker-sprung {
  background: var(--card);
}

.marker-mini {
  flex: none;
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--sage);
}

.marker-mini--leer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--faint);
  background: var(--sage-soft);
}

.marker-seite {
  flex: none;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Status-Chips der Marker: offen (Akzent), veraltet (gedimmtes Badge),
   erledigt (grüner Haken) — Duktus wie die Buch-Status-Chips. */
.marker-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid;
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  flex: none;
}

.marker-chip--offen {
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-color: var(--sage);
}

.marker-chip--veraltet {
  /* Design-Tokens statt Hexwerte (T4-Review-Mitnahme f): gedimmt in der
     Salbei-Familie — passend zu Pin/Rahmen im veraltet-Zustand (--faint). */
  color: var(--faint);
  background: var(--sage-soft);
  border-color: var(--sage);
}

.marker-chip--erledigt {
  color: #0e5c40;
  background: #dcefe2;
  border-color: #c2e2cd;
}

.marker-chip [data-icon] {
  width: 11px;
  height: 11px;
}

/* Einzeilig mit Ellipse (Spec 2026-07-06) — füllt den Restplatz der Zeile.
   min-width: 10ch statt 0: unter ~10 Zeichen Restplatz bricht der Kommentar
   dank flex-wrap des Sprung-Buttons als volle zweite Zeile um, statt auf
   0px zusammengedrückt zu verschwinden. flex-basis 0 (nicht auto), damit
   der Umbruch an den 10ch hängt und NICHT an der Textlänge — sonst rutscht
   jeder lange Kommentar selbst in breiten Kacheln in die zweite Zeile. */
.marker-kommentar {
  flex: 1 1 0;
  min-width: 10ch;
  font-size: 13.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Aufklapp-Pfeil (Spec 2026-07-06): eigener Zeilen-Button neben dem
   Sprung-Button, dreht sich beim Öffnen des Detail-Bereichs. */
.marker-aufklappen {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  color: var(--muted);
  padding: 4px;
}

.marker-aufklappen [data-icon] {
  transition: transform 0.15s ease;
  display: inline-flex;
}

.marker-aufklappen--offen [data-icon] {
  transform: rotate(90deg);
}

/* Löschknopf je Eintrag (Task 9): jetzt Zeilen-Button statt Overlay
   (Spec 2026-07-06) — gleicher Duktus wie .dateien-aktion--danger. */
.marker-loeschen {
  flex: none;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  color: var(--muted);
}

.marker-loeschen:hover {
  color: var(--danger);
  background: var(--danger-soft);
}

.marker-loeschen [data-icon] svg {
  width: 15px;
  height: 15px;
}

/* Detail-Bereich (Spec 2026-07-06): unter der Kompaktzeile, eingerückt
   hinter das Mini-Thumb; Bild wird lazy beim ersten Aufklappen gebaut. */
.marker-detail {
  padding: 6px 8px 10px 58px;
}

/* Großes Crop-Bild — kommt ausschließlich im Detail-Bereich vor. */
.marker-detail .marker-crop {
  display: block;
  max-width: 100%;
  border: 1px solid var(--sage);
  border-radius: 8px;
  background: #fff;
  box-shadow: var(--shadow-sm);
}

.marker-detail-kommentar {
  margin: 6px 0 0;
  white-space: pre-wrap;
}

/* Snippet-Auszug: zwei Zeilen mit Ellipsis (Textumgebung der Stelle). */
.marker-snippet {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.marker-card.float {
  animation-delay: 0.24s;
}

/* typst/pandoc-Fehlerdetail aus dem 422 — Mono, umbruchfest, intern scrollbar */
.error-detail {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.55;
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid var(--danger-border);
  border-radius: var(--radius-input);
  padding: 12px 14px;
  max-width: 100%;
  max-height: 180px;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  text-align: left;
}

.error-detail:empty {
  display: none;
}

/* ============================================================
   Claude-Terminal (Etappe 2, Task 3)
   ============================================================ */

/* Dunkle Karte im Galerie-Stil: gleiche Rundung und Schatten wie die weißen
   Karten, aber Grün-Anthrazit — hier arbeitet Claude am Manuskript. Flache
   Fläche statt Verlauf, damit der xterm-Hintergrund (--term-bg) nahtlos in
   die Karte übergeht. position:relative trägt die Fehler-Überlagerung. */
.terminal-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--term-bg);
  border-color: rgba(255, 255, 255, 0.07);
}

.terminal-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--term-bg-head);
  border-bottom: 1px solid var(--term-border);
  /* Schmale Kacheln: Buttons brechen unter den Titel um (kein Überlappen). */
  flex-wrap: wrap;
  row-gap: 6px;
}

.terminal-title {
  font-family: var(--font-serif);
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--term-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Verbindungs-Punkt: grün = verbunden, grau = getrennt, rot = Fehler
   (terminal.ts schaltet über data-zustand um). */
.term-status {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--term-muted);
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.term-status[data-zustand="verbunden"] {
  background: #55c48f;
  box-shadow: 0 0 0 3px rgba(85, 196, 143, 0.22);
}

.term-status[data-zustand="fehler"] {
  background: #e07a6e;
  box-shadow: 0 0 0 3px rgba(224, 122, 110, 0.2);
}

/* Werkzeugleiste über dem xterm (Clear/Reset/Claude Code starten). Dunkel wie
   der Terminal-Kopf; kompakte Knöpfe mit flex-wrap, damit die Leiste auch im
   schmalen Fenster umbricht statt zu clippen (Karte ist frei skalierbar). */
.term-actions {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--term-bg-head);
  border-bottom: 1px solid var(--term-border);
}

.term-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--term-ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--term-border);
  border-radius: var(--radius-pill);
  padding: 6px 12px;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.term-btn [data-icon] {
  width: 14px;
  height: 14px;
  color: var(--term-cursor);
}

.term-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  transform: translateY(-1px);
}

.term-btn:active {
  transform: none;
}

.term-btn:disabled {
  opacity: 0.5;
  cursor: default;
  transform: none;
}

/* Primär = „Claude Code starten": heller Salbei-Akzent auf Dunkel. */
.term-btn--primary {
  color: #08130d;
  background: var(--term-cursor);
  border-color: var(--term-cursor);
}

.term-btn--primary [data-icon] {
  color: #08130d;
}

.term-btn--primary:hover {
  background: #93d6b6;
  border-color: #93d6b6;
}

/* Bühne des xterm: füllt die restliche Karte; min-height:0 erlaubt dem
   Grid-Stretch, die Karte auf Viewer-Höhe zu klemmen (fit-Addon misst
   dieses Element). Rechts weniger Padding — dort liegt die Scrollbar. */
.terminal-body {
  flex: 1;
  min-height: 0;
  padding: 10px 4px 12px 12px;
}

.terminal-body .xterm {
  height: 100%;
}

/* Fehlerkarte: legt sich über die ganze Terminal-Karte, bis „Erneut
   verbinden" klappt. Die Retry-Pille ist die normale helle pill-btn —
   bewusst als Lichtpunkt auf der dunklen Fläche. */
.terminal-error {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  text-align: center;
  background: rgba(16, 24, 20, 0.88);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

.terminal-error-text {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--term-ink);
  max-width: 320px;
}

/* Toast-Pillen (Live-Updates, „Build läuft bereits"): unten mittig über der
   Statusleiste, Galerie-Glas-Optik, verschwinden von selbst (viewer.ts). */
.toast-stapel {
  position: fixed;
  bottom: 58px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  z-index: 60;
  pointer-events: none;
}

.toast-pille {
  display: inline-flex;
  align-items: center;
  background: rgba(255, 255, 255, 0.85);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-md);
  padding: 8px 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  animation: rise 0.3s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

/* Fehler-Variante (z. B. fehlgeschlagener Screenshot-Upload): dezent rot,
   damit sie sich von der Erfolgs-Pille abhebt. */
.toast-pille-fehler {
  background: rgba(185, 49, 34, 0.14);
  border-color: rgba(185, 49, 34, 0.35);
  color: #8f2418;
}

.viewer-card.float {
  animation-delay: 0.1s;
}

.terminal-card.float {
  animation-delay: 0.18s;
}

/* Terminal-Spalte rutscht auf schmalen Fenstern unter den Viewer. Die
   Kachel-Anordnung selbst regelt gridstack (Kacheln bleiben, wo Frank sie
   hinlegt) — hier nur noch Mindesthöhen, damit einzelne Karten auf schmalen
   Bildschirmen nicht zu sehr schrumpfen. */
@media (max-width: 960px) {
  .viewer-buehne {
    min-height: 320px;
  }

  /* Gestapelt streckt kein Viewer mehr die Karte — feste Arbeitshöhe. */
  .terminal-body {
    min-height: 340px;
  }
}

/* ============================================================
   Kapitel-Editor (Etappe 4, Task 4)
   ============================================================ */

/* Dreispaltige Bühne: Kapitel-Liste (links) · Textfeld (Mitte) · Wording-
   Wächter (rechts). Jede Spalte ist eine Karte, die intern scrollt. */
.editor {
  flex: 1;
  display: grid;
  grid-template-columns:
    clamp(190px, 19vw, 260px)
    minmax(0, 1fr)
    clamp(280px, 26vw, 380px);
  gap: 16px;
  align-items: stretch;
  min-height: 0;
}

/* Statusanzeige in der Topbar („gespeichert 12:04" / „ungespeicherte …"). */
.ed-status {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}

.ed-status[data-art="dirty"] {
  color: var(--danger);
}

.ed-status[data-art="gespeichert"] {
  color: var(--accent-deep);
}

.editor-spalten-titel {
  font-family: var(--font-serif);
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.editor-leer {
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.5;
}

/* ---------- Kapitel-Liste (links) ---------- */

.editor-kapitel {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 12px;
  overflow: hidden;
}

.kapitel-liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 5px;
  overflow: auto;
  min-height: 0;
}

/* Ein Kapitel: die ganze Zeile ist der Öffnen-Button; das aktive Kapitel
   (aria-current) trägt die gefüllte Akzent-Fläche. */
.kapitel-knopf {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: none;
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 8px 10px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.kapitel-knopf:hover {
  background: var(--sage-soft);
}

.kapitel-knopf[aria-current="true"] {
  background: var(--accent-soft);
  border-color: var(--sage);
}

.kapitel-titel {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
}

.kapitel-datei {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--faint);
}

.kapitel-knopf[aria-current="true"] .kapitel-datei {
  color: var(--accent-deep);
}

/* ---------- Textfeld (Mitte) ---------- */

.editor-haupt {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
}

.editor-textwrap {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}

/* Markdown-Rohtext: monospace, interner Scroll; Umbruch schaltet der
   Topbar-Knopf „Umbruch" (textarea.wrap soft/off, Standard: soft).
   Ruhiger Papierton wie die gerenderte Seite. */
.editor-textarea {
  flex: 1;
  width: 100%;
  min-height: 0;
  resize: none;
  border: 0;
  border-radius: var(--radius-card);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 13.5px;
  line-height: 1.6;
  padding: 18px 20px;
  tab-size: 2;
  /* KEIN white-space hier: Autoren-CSS überstimmt das wrap-Attribut der
     Textarea. Der Umbruch-Toggle (editor.ts) schaltet textarea.wrap
     soft/off — der Browser leitet daraus selbst pre-wrap bzw. pre ab. */
  overflow: auto;
}

.editor-textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.editor-textarea:disabled {
  background: var(--card);
}

/* Platzhalter über dem leeren Textfeld, bis ein Kapitel geöffnet ist. */
.editor-platzhalter {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  padding: 26px;
  color: var(--muted);
  font-size: 14.5px;
}

.editor-platzhalter .badge {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: var(--sage-soft);
  border: 1px solid var(--sage);
  display: grid;
  place-items: center;
  color: var(--accent);
}

.editor-platzhalter .badge [data-icon] {
  width: 26px;
  height: 26px;
}

/* ---------- Wording-Wächter (rechts) ---------- */

.editor-wording {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.editor-wording-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--sage-soft);
}

.editor-wording-zaehler {
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--accent-deep);
  background: var(--accent-soft);
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  white-space: nowrap;
}

.editor-wording-body {
  overflow: auto;
  padding: 12px 14px;
  min-height: 0;
}

.wording-liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

/* Befund-Karte: die ganze Karte springt im Textfeld an die Fundstelle. Der
   linke Rand codiert den Schweregrad. */
.wording-sprung {
  display: flex;
  flex-direction: column;
  gap: 5px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: var(--sage-soft);
  border: 1px solid var(--sage);
  border-left: 3px solid var(--sage-mid);
  border-radius: 10px;
  padding: 9px 12px;
  cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.wording-sprung:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

/* Schweregrad-Codierung (Design-Tokens): fehler=danger, warnung=amber,
   hinweis=faint/sage. Linke Kante + Chip tragen die Farbe. */
.wording-eintrag[data-schweregrad="fehler"] .wording-sprung {
  border-left-color: var(--danger);
}

.wording-eintrag[data-schweregrad="warnung"] .wording-sprung {
  border-left-color: var(--amber);
}

.wording-eintrag[data-schweregrad="hinweis"] .wording-sprung {
  border-left-color: var(--faint);
}

.wording-kopf {
  display: flex;
  align-items: center;
  gap: 8px;
}

.wording-chip {
  display: inline-flex;
  align-items: center;
  border: 1px solid;
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  flex: none;
}

.wording-chip--fehler {
  color: var(--danger);
  background: var(--danger-soft);
  border-color: var(--danger-border);
}

.wording-chip--warnung {
  color: var(--amber);
  background: var(--amber-soft);
  border-color: var(--amber-border);
}

.wording-chip--hinweis {
  color: var(--faint);
  background: var(--sage-soft);
  border-color: var(--sage);
}

.wording-ort {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.wording-regel {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--accent-deep);
}

.wording-erklaerung {
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink);
}

.wording-empfehlung {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
  font-style: italic;
}

/* ---------- Suchen & Ersetzen-Dialog ---------- */

.dialog-card--breit {
  width: min(560px, calc(100vw - 40px));
}

.such-optionen {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
}

.check-field {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--muted);
  cursor: pointer;
}

.check-field input {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

.such-treffer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 1px solid var(--sage-soft);
  padding-top: 12px;
}

.such-treffer-kopf {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
}

.such-treffer-liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 300px;
  overflow: auto;
}

/* Ein Suchtreffer: Datei + Zeile:Spalte oben, Kontextzeile darunter. Klick
   öffnet das Kapitel an der Stelle. */
.treffer-knopf {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  text-align: left;
  font: inherit;
  color: var(--ink);
  background: var(--sage-soft);
  border: 1px solid var(--sage);
  border-radius: 9px;
  padding: 8px 11px;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.treffer-knopf:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-sm);
}

.treffer-ort {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.03em;
  color: var(--accent-deep);
}

.treffer-kontext {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.45;
  color: var(--muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.editor-kapitel.float {
  animation-delay: 0.1s;
}

.editor-haupt.float {
  animation-delay: 0.16s;
}

.editor-wording.float {
  animation-delay: 0.22s;
}

/* Editor auf schmalen Fenstern: die drei Spalten stapeln. */
@media (max-width: 960px) {
  .editor {
    grid-template-columns: 1fr;
    grid-auto-rows: auto;
  }

  .editor-textwrap {
    min-height: 340px;
  }
}

/* ---------- Bewegung reduzieren ---------- */

@media (prefers-reduced-motion: reduce) {
  * {
    animation: none !important;
    transition: none !important;
  }
}

/* ---------- Schmale Fenster ---------- */

@media (max-width: 700px) {
  .page-app {
    padding: 12px 12px 10px;
    gap: 12px;
  }

  .topbar {
    padding: 10px 14px;
    gap: 10px;
    border-radius: 16px;
  }

  .topbar .pill-btn {
    padding: 8px 13px;
    font-size: 13px;
  }

  .brand-sub {
    display: none;
  }

  .empty-state {
    width: 100%;
    padding: 40px 24px 34px;
  }

  .book-grid {
    gap: 12px;
    padding-bottom: 12px;
  }

  .viewer-toolbar {
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    padding: 10px 12px;
  }

  /* Auf schmalen Bühnen die Blätter enger zusammenrücken. */
  #wk-grid {
    gap: 6px;
  }

  .dialog-card {
    padding: 24px 20px 20px;
  }

  .page-login {
    padding: 20px 14px;
  }

  .login-wrap {
    width: 100%;
  }

  .login-card {
    padding: 36px 24px 30px;
  }
}

/* ---------- KDP-Export-Modal (Etappe 5, Task 7) ---------- */

/* Breiter als der Standard-Dialog: die Prüf-Checkliste braucht Platz für die
   Detail-Texte. Sonst erbt das Modal die Galerie-Karten-Optik von .dialog-card. */
.export-dialog {
  width: min(560px, calc(100vw - 40px));
}

/* Lade-Zustand während PDF+EPUB gebaut werden (analog zur Status-Pille). */
.export-laeuft {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 4px;
  color: var(--muted);
  font-size: 14px;
}

/* Checkliste der Prüfergebnisse — bulletlos, jede Zeile eine Prüfung. */
.export-checkliste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 46vh;
  overflow-y: auto;
  margin: 2px 0;
}

.export-eintrag {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: start;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--sage);
  border-left-width: 3px;
  border-radius: var(--radius-input);
  background: var(--sage-soft);
}

/* Schweregrad-Codierung (Design-Tokens wie die Wording-Einträge):
   bestanden=accent, warnung=amber, blocker=danger. */
.export-eintrag[data-status="bestanden"] {
  border-color: var(--sage);
  border-left-color: var(--accent);
}
.export-eintrag[data-status="warnung"] {
  border-color: var(--amber-border);
  border-left-color: var(--amber);
  background: var(--amber-soft);
}
.export-eintrag[data-status="blocker"] {
  border-color: var(--danger-border);
  border-left-color: var(--danger);
  background: var(--danger-soft);
}

.export-symbol {
  display: inline-flex;
  align-items: center;
  margin-top: 1px;
  color: var(--muted);
}
.export-symbol svg {
  width: 17px;
  height: 17px;
}
.export-eintrag[data-status="bestanden"] .export-symbol {
  color: var(--accent);
}
.export-eintrag[data-status="warnung"] .export-symbol {
  color: var(--amber);
}
.export-eintrag[data-status="blocker"] .export-symbol {
  color: var(--danger);
}

.export-eintrag-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.export-pruefung {
  font-weight: 600;
  font-size: 13.5px;
  color: var(--ink);
}

.export-detail {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--muted);
  overflow-wrap: anywhere;
}

/* Der Download-Link liegt in der Aktionsleiste — er soll wie die anderen
   Primär-Knöpfe aussehen (a-Element statt button). */
.export-download {
  text-decoration: none;
}

/* ---------- Dateien-Panel + Drag & Drop (Etappe 5, Task 10) ---------- */

/* Schwebende Galerie-Karte oben rechts, unter der Topbar. Fixe Position, damit
   sie unabhängig vom Bühnen-Layout schwebt; dateien.ts toggelt [hidden]. */
.dateien-panel {
  position: fixed;
  top: 84px;
  right: 20px;
  z-index: 40;
  /* 500 statt 400 px: Franks Wunsch vom 2026-07-07 (mehr Platz im Panel). */
  width: min(500px, calc(100vw - 40px));
  max-height: min(72vh, 660px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 16px 18px;
  background: var(--card);
  border: 1px solid var(--sage);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-lg);
}

.dateien-head {
  display: flex;
  align-items: center;
  gap: 8px;
}
.dateien-head > [data-icon] {
  display: inline-flex;
  color: var(--accent);
}
.dateien-head > [data-icon] svg {
  width: 18px;
  height: 18px;
}
.dateien-titel {
  font-family: var(--font-serif);
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}
.dateien-head .spacer {
  flex: 1;
}
.dateien-upload {
  padding: 6px 12px;
  font-size: 13px;
}

/* Der assets-Pfad des Buchs (rein informativ, Mono). */
.dateien-pfad {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--faint);
  overflow-wrap: anywhere;
}

.dateien-status {
  padding: 6px 2px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
}

/* Datei-Liste: scrollt intern, damit viele Dateien das Panel nicht sprengen. */
.dateien-liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  overflow-y: auto;
}

.dateien-eintrag {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  background: var(--sage-soft);
}

.dateien-icon {
  display: inline-flex;
  color: var(--accent);
}
.dateien-icon svg {
  width: 18px;
  height: 18px;
}

.dateien-meta {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.dateien-name {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.dateien-groesse {
  font-size: 11.5px;
  color: var(--faint);
}

/* Ordner-Namen sind anklickbar → in den Unterordner navigieren. */
.dateien-name--ordner {
  color: var(--accent);
  cursor: pointer;
}
.dateien-name--ordner:hover {
  text-decoration: underline;
}
/* „Zurück"-Zeile (eine Ebene höher). */
.dateien-eintrag--hoch {
  cursor: pointer;
}
.dateien-eintrag--hoch .dateien-name {
  color: var(--faint);
}
.dateien-eintrag--hoch:hover {
  background: var(--sage);
}

.dateien-aktionen {
  display: inline-flex;
  gap: 4px;
}
/* Kompaktere Werkzeug-Buttons je Zeile (Basis: .tool-btn). */
.dateien-aktion {
  width: 30px;
  height: 30px;
  text-decoration: none;
}
.dateien-aktion [data-icon] svg {
  width: 15px;
  height: 15px;
}
.dateien-aktion--danger:hover:not(:disabled) {
  color: var(--danger);
  border-color: var(--danger-border);
}

/* Dropzone-Overlay über der PDF-Bühne, während Bilder herübergezogen werden.
   Zeigerdurchlässig — die Drag-Zählung in dateien.ts läuft über die Bühne
   selbst, nicht über dieses Overlay. */
.dropzone-overlay {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: rgba(14, 110, 79, 0.12);
}
.dropzone-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 22px 30px;
  border: 2px dashed var(--accent);
  border-radius: var(--radius-card);
  background: var(--card);
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
  box-shadow: var(--shadow-md);
}
.dropzone-inner [data-icon] {
  display: inline-flex;
}
.dropzone-inner [data-icon] svg {
  width: 28px;
  height: 28px;
}

/* Auf schmalen Fenstern spannt das Panel fast über die volle Breite. */
@media (max-width: 720px) {
  .dateien-panel {
    top: auto;
    bottom: 16px;
    right: 16px;
    left: 16px;
    width: auto;
    max-height: 60vh;
  }
}

/* === Werkstatt-Kacheln auf gridstack.js (Spec 2026-07-06) ==================
   Die drei Karten (PDF-Vorschau, Terminal, Marker) laufen als frei ordbare/
   größenveränderbare Kacheln über gridstack.js (12 Spalten, float-Modus —
   Kacheln bleiben liegen, Nachbarn weichen live aus statt zu überlappen).
   Ersetzt das Eigenbau-Fenstersystem (fenster.ts, entfernt) — bewusste
   Bibliotheks-Ausnahme auf Franks Wunsch. gridstack.css bringt die
   Positionierung der .grid-stack-item-Elemente selbst mit (position:relative
   am Container, position:absolute je Item); hier nur die Container-Höhe
   (Sicherheitsnetz gegen Seiten-Scroll) und die Karten-Optik. */
.werkstatt {
  flex: 1;
  /* min-height:0 bricht die Flexbox-Falle: als flex-Kind hätte .werkstatt
     min-height:auto (= min-content) und würde NICHT unter seinen Inhalt
     schrumpfen → die Bühne bläht sich auf Seitenhöhe auf und die Seite rutscht
     unter den sichtbaren Bereich. Mit 0 füllt sie exakt den zugeteilten Platz. */
  min-height: 0;
  overflow: hidden;
}

/* gridstack-Item füllt die Karte; die Karte selbst flext auf die volle
   Item-Höhe (statt ihrer natürlichen Inhaltshöhe). Spezifität bewusst auf
   das Niveau von gridstack.min.css gezogen (.grid-stack > .grid-stack-item >
   .grid-stack-item-content, drei Klassen) — sonst gewinnt das Fremd-CSS mit
   overflow-y:auto gegen unser overflow:hidden. Zusätzlich lädt werkstatt.html
   das Fremd-CSS VOR style.css, damit bei gleicher Spezifität unsere Regel
   die Kaskade gewinnt. */
.grid-stack > .grid-stack-item > .grid-stack-item-content {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.grid-stack > .grid-stack-item > .grid-stack-item-content > .card {
  flex: 1;
  min-height: 0;
}

/* Drag-Platzhalter (Frank-Referenz 2026-07-06): gestrichelte Umrandung in
   Tannengrün, abgerundet wie die Karten. gridstack.min.css gibt dem
   .placeholder-content nur graues rgba(0,0,0,.1) (2-Klassen-Selektor —
   unsere 3 Klassen gewinnen); die Insets (top/right/bottom/left aus den
   --gs-item-margin-*-Variablen) bleiben unangetastet. Grünton var(--accent)
   (#0e6e4f), als Fläche auf 6 % abgeschwächt (Muster wie --accent-ring). */
.grid-stack > .grid-stack-placeholder > .placeholder-content {
  border: 2px dashed var(--accent);
  border-radius: var(--radius-card);
  background: rgba(14, 110, 79, 0.06);
}

/* Griffleiste je Kachel (wie zuvor unter fenster.ts, Optik unverändert):
   erste Zeile IN der Karte — initKacheln prependet sie dort, damit sie deren
   Rundung/overflow erbt (außerhalb gäbe es sichtbare Ecken-Dreiecke oben).
   Die Titelzeile ist der Drag-Handle für gridstack (initKacheln setzt
   handle: ".fenster-leiste"). */
.fenster-leiste {
  flex: none;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 12px;
  cursor: move;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  background: rgba(255, 255, 255, 0.5);
  border-bottom: 1px solid var(--sage-soft);
}
/* dunkle Terminal-Karte: Leiste passend abtönen */
.terminal-card > .fenster-leiste {
  background: rgba(255, 255, 255, 0.06);
  border-bottom-color: rgba(255, 255, 255, 0.08);
}
.terminal-card .fenster-titel { color: rgba(255, 255, 255, 0.72); }
.fenster-griff-punkte {
  width: 10px;
  height: 16px;
  color: var(--faint);
  background-image: radial-gradient(currentColor 1.1px, transparent 1.3px);
  background-size: 5px 5px;
  background-position: center;
}
.fenster-titel {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted);
}
/* „Layout zurücksetzen"-Knopf in der Topbar */
.pill-btn.wk-layout-reset { font-size: 12.5px; }

/* === Marker-Status-Filter (Franks Wunsch) ================================
   Togglebare Pillen oben in der Marker-Karte: Offen · Veraltet · Erledigt mit
   Zähler. Aktiv (aria-pressed) = wird gezeigt; ausgeschaltet = gedimmt +
   durchgestrichen, Marker dieses Status verschwinden aus der Liste. */
.marker-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-bottom: 12px;
}
.marker-filter-pille {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 999px;
  cursor: pointer;
  transition: opacity 0.12s ease, background 0.12s ease, border-color 0.12s ease;
}
.marker-filter-pille:hover { filter: brightness(0.97); }
.marker-filter-zahl {
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.7);
  padding: 0 6px;
  border-radius: 999px;
}
/* Ausgeschaltet: gedimmt, durchgestrichen, neutrale Fläche. */
.marker-filter-pille--aus {
  color: var(--muted);
  background: var(--sage-soft);
  border-color: var(--sage);
  opacity: 0.6;
  text-decoration: line-through;
}

/* === Media-Explorer (Spec 2026-07-07) ======================================
   Großes, dynamisches <dialog> (media-explorer.ts) — erbt Karten-Optik/
   Animation von .dialog-card, deutlich breiter/höher als die übrigen Dialoge
   (Grid/Liste statt einer einzelnen Frage/Liste). Aufbau: Kopf (Brotkrumen +
   Aktionen), darunter zweispaltiger Rumpf (Haupt links, Info-Leiste 280px
   rechts). */
.media-explorer {
  width: min(1100px, 94vw);
  height: 86vh;
  max-width: none;
  max-height: none;
  padding: 22px 24px 20px;
}

.me-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* Die Karte selbst hat eine feste Höhe (s. o.) — ohne min-height:0 würde
     dieser Flex-Container auf seinen Inhalt (Grid/Liste) wachsen und die
     internen Scrollbereiche unten könnten nie greifen (bekannte Flexbox-
     Falle, vgl. .werkstatt/.terminal-buehne). */
  height: 100%;
  min-height: 0;
}

.me-head {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 0;
}
.me-head h2 {
  font-size: 17px;
}
.me-head .spacer {
  flex: 1;
}

.me-brotkrumen {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 12.5px;
}
.me-brotkrumen-segment {
  background: none;
  border: none;
  padding: 2px 4px;
  border-radius: 6px;
  color: var(--accent);
  cursor: pointer;
}
.me-brotkrumen-segment:hover:not(:disabled) {
  background: var(--accent-soft);
}
.me-brotkrumen-segment[aria-current="true"] {
  color: var(--ink);
  font-weight: 600;
  cursor: default;
}
.me-brotkrumen-trenner {
  color: var(--faint);
}

.me-umschalter {
  display: inline-flex;
  gap: 4px;
}

.me-status {
  flex: none;
  padding: 6px 2px;
  font-size: 13px;
  color: var(--muted);
}

/* Der Datei-Input (#me-datei-input) braucht keine eigene Regel — das
   hidden-Attribut im Markup versteckt ihn bereits (wie #wk-dateien-input). */

/* Rumpf: Haupt (Grid/Liste) links, Info-Leiste rechts. min-height:0 auf dem
   Rumpf UND auf .me-haupt ist Pflicht, sonst wächst die Karte statt intern zu
   scrollen (dieselbe Falle wie überall sonst in der App). */
.me-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 16px;
}

.me-haupt {
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
}

/* Grid-Ansicht: Kacheln ~140px, so viele Spalten wie passen. */
.me-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
}

.me-kachel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  background: var(--sage-soft);
  cursor: pointer;
  text-align: center;
  transition: box-shadow 0.15s ease, border-color 0.15s ease;
}
.me-kachel:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-sm);
}
/* Ausgewählter Eintrag (Info-Leiste zeigt ihn): dezenter Akzent-Rahmen +
   -Tönung — bleibt beim Grid↔Liste-Wechsel erhalten (markiereAuswahl). */
.me-kachel--aktiv {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: var(--shadow-sm);
}

.me-kachel-vorschau {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 84px;
  border-radius: 8px;
  background: #fff;
  overflow: hidden;
  color: var(--accent);
}
.me-kachel-vorschau img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.me-kachel-vorschau [data-icon] svg {
  width: 30px;
  height: 30px;
}

.me-kachel-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.me-kachel-unter {
  font-size: 11px;
  color: var(--faint);
}

/* Listen-Ansicht: Spalten Name/Größe/Maße/DPI/Geändert. */
.me-liste {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.me-liste th {
  text-align: left;
  padding: 6px 8px;
  color: var(--muted);
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--sage);
}
.me-liste-zeile {
  cursor: pointer;
}
.me-liste-zeile:hover {
  background: var(--accent-soft);
}
/* Zeilen sind per tabindex fokussierbar (Enter/Leertaste = Klick) — sichtbarer
   Fokus-Ring nach innen, damit er im Scrollbereich nicht abgeschnitten wird. */
.me-liste-zeile:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
/* Ausgewählte Zeile — Gegenstück zu .me-kachel--aktiv. */
.me-liste-zeile--aktiv {
  background: var(--accent-soft);
}
.me-liste-zeile td {
  padding: 7px 8px;
  border-bottom: 1px solid var(--sage-soft);
  color: var(--ink);
}
.me-liste-name {
  display: flex;
  align-items: center;
  gap: 8px;
}
.me-liste-name [data-icon] {
  display: inline-flex;
  color: var(--accent);
}
.me-liste-name [data-icon] svg {
  width: 15px;
  height: 15px;
}

/* Info-Leiste: eigener Scrollbereich, damit lange Aktionslisten die Karte
   nicht sprengen. */
.me-info {
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--sage);
  border-radius: var(--radius-card);
  background: var(--sage-soft);
}

.me-info-bild {
  width: 100%;
  max-height: 160px;
  object-fit: contain;
  border-radius: 8px;
  background: #fff;
  border: 1px solid var(--sage);
}
.me-info-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100px;
  color: var(--accent);
}
.me-info-icon svg {
  width: 36px;
  height: 36px;
}

.me-info-name {
  font-family: var(--font-serif);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.me-info-daten {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12.5px;
}
.me-info-daten > div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.me-info-daten dt {
  color: var(--muted);
}
.me-info-daten dd {
  color: var(--ink);
  text-align: right;
  overflow-wrap: anywhere;
}

/* DPI-Ampel: ok = Akzent-Töne (KDP-Grenze erreicht), niedrig = --danger-Töne,
   unbekannt = neutrale Sage-Fläche ("–", kein eingebetteter DPI-Header). */
.me-dpi-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
}
.me-dpi-badge--ok {
  color: var(--accent-deep);
  background: var(--accent-soft);
}
.me-dpi-badge--niedrig {
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid var(--danger-border);
}
.me-dpi-badge--unbekannt {
  color: var(--muted);
  background: var(--sage);
}

.me-info-aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: auto;
  padding-top: 6px;
}
.me-info-aktionen .pill-btn {
  padding: 6px 10px;
  font-size: 12.5px;
}

@media (max-width: 720px) {
  .media-explorer {
    width: calc(100vw - 20px);
    height: 92vh;
  }
  .me-body {
    grid-template-columns: 1fr;
    overflow-y: auto;
  }
  .me-haupt {
    overflow-y: visible;
  }
  .me-info {
    overflow-y: visible;
  }
}

/* ============================================================
   Buchdaten-Maske (Spec 2026-07-07, buchdaten.ts) — Metadaten-Modal
   der Werkstatt. Erbt Optik/Animation von .dialog-card; nur Kopf
   (read-only) und Format-Checkboxen brauchen eigene Regeln. Viele
   Felder → das Formular scrollt intern statt über den Viewport.
   ============================================================ */

.buchdaten-dialog .dialog-form {
  max-height: calc(100vh - 80px);
  overflow-y: auto;
}

/* Schreibgeschützter Kopf: Nummer + Slug (dauerhafte ID, nicht editierbar). */
.buchdaten-kopf {
  display: flex;
  gap: 22px;
  padding: 10px 14px;
  background: #f4f8f4;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
}

.buchdaten-kopf dt {
  font-size: 11px;
  font-weight: 600;
  color: var(--faint);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.buchdaten-kopf dd {
  font-size: 15px;
  color: var(--ink);
  margin-top: 2px;
}

/* Formate: zwei Checkboxen nebeneinander, im .input-field-Rahmen der Optik. */
.buchdaten-formate {
  display: flex;
  flex-direction: column;
  gap: 8px;
  border: none;
  padding: 0;
  margin: 0;
}

.buchdaten-formate legend {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: 0.02em;
  padding: 0;
}

.buchdaten-formate label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  color: var(--ink);
  cursor: pointer;
}

.buchdaten-formate input {
  width: 17px;
  height: 17px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* Roadmap-Button: Statusfarbe als linker Punkt + dezenter Rahmen. */
.wk-roadmap-punkt { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-right: 6px; background: var(--roadmap-farbe, #b0b0b0); }
.roadmap-rot   { --roadmap-farbe: #c0392b; }
.roadmap-gelb  { --roadmap-farbe: #e0a423; }
.roadmap-gruen { --roadmap-farbe: #2e8b57; }
.roadmap-blau  { --roadmap-farbe: #2b6cb0; }
/* Roadmap-Modal deutlich breiter als der schmale .dialog-card-Default (430px):
   die Checkliste (5 Phasen/19 Aufgaben) fließt in ZWEI Spalten — nutzt die
   Breite und kürzt den hohen Scroll; eine Phase bricht nie zwischen den Spalten. */
.roadmap-dialog { width: min(900px, 94vw); }
.roadmap-dialog #rm-phasen { columns: 2; column-gap: 40px; }
.roadmap-fortschritt { height: 6px; border-radius: 3px; background: rgba(0,0,0,0.08); overflow: hidden; margin: 4px 0 18px; }
.roadmap-fortschritt > span { display: block; height: 100%; background: var(--roadmap-farbe, #2e8b57); transition: width 0.2s; }
.roadmap-phase { margin: 0 0 18px; break-inside: avoid; }
.roadmap-phase > h3 { font-size: 14px; margin: 0 0 8px; padding-bottom: 4px; border-bottom: 1px solid rgba(0,0,0,0.08); }
.roadmap-item { display: flex; align-items: flex-start; padding: 4px 0; line-height: 1.35; flex-wrap: wrap; }
/* Label = Checkbox + Text mit klarem Abstand (der gap der .roadmap-item wirkt
   sonst nur zum Bild, nicht INNERHALB des Labels → Text klebte an der Box). */
.roadmap-item label { display: flex; align-items: flex-start; gap: 10px; width: 100%; cursor: pointer; }
.roadmap-item input { margin-top: 3px; flex-shrink: 0; }
/* Ads-Hilfebild bricht auf eine EIGENE Zeile unter das Label und nutzt die
   volle Spaltenbreite. min-width:0 ist entscheidend: als Flex-Kind schrumpft
   das 1188-px-Bild sonst NICHT unter seine Eigenbreite (min-width:auto) und
   erzeugt einen horizontalen Scrollbalken. */
.roadmap-ads-hilfe { flex-basis: 100%; width: 100%; max-width: 100%; min-width: 0; margin-top: 8px; border: 1px solid rgba(0,0,0,0.1); border-radius: 6px; cursor: zoom-in; }
/* Lightbox: Klick aufs Ads-Bild zeigt es groß (bis 92vw/92vh), Klick schließt. */
.roadmap-lightbox { margin: auto; border: none; background: transparent; padding: 0; max-width: 92vw; max-height: 92vh; }
.roadmap-lightbox::backdrop { background: rgba(0, 0, 0, 0.82); }
.roadmap-lightbox img { display: block; max-width: 92vw; max-height: 92vh; width: auto; height: auto; border-radius: 8px; cursor: zoom-out; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5); }
/* Schmale Fenster: eine Spalte (die Zwei-Spalten-Optik braucht Platz). */
@media (max-width: 640px) { .roadmap-dialog #rm-phasen { columns: 1; } }
.book-card-roadmap { display: inline-flex; align-items: center; font-size: 12px; color: var(--muted, #666); margin-left: 8px; }

/* ── Buchplanung (12.08.2026) ─────────────────────────────────────────────
   Fahrplan-Dialog am Topbar-Knopf des Regals (ui/planung.ts). Breiter als der
   Papierkorb, weil je Zeile Titel UND Kennzahl stehen; der Rumpf scrollt, der
   Kopf mit der Zusammenfassung bleibt sichtbar. */
.planung-dialog {
  max-width: 56rem;
  width: min(56rem, 94vw);
}

.planung-body {
  max-height: 62vh;
  overflow-y: auto;
  /* Platz fuer den Scrollbalken, damit er die Zeilen nicht überdeckt. */
  padding-right: 4px;
}

.planung-gruppe {
  margin: 18px 0 8px;
}
.planung-gruppe:first-child {
  margin-top: 0;
}
.planung-gruppe-titel {
  margin: 0;
  font-size: 0.95rem;
  color: var(--accent-deep);
}
.planung-gruppe-text {
  margin: 2px 0 0;
  font-size: 0.82rem;
  color: var(--muted);
}

.planung-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Zeile: Zeichen · Rang · Titel/Untertext · Status. Die mittlere Spalte nimmt
   den Rest; min-width:0 laesst lange Titel dort umbrechen statt das Raster zu
   sprengen. */
.planung-zeile {
  display: grid;
  grid-template-columns: auto 2.2rem 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border: 1px solid var(--sage);
  border-radius: var(--radius-input);
  background: var(--card);
}

.planung-haken {
  display: inline-flex;
  color: var(--faint);
}
.planung-haken svg {
  width: 17px;
  height: 17px;
}

.planung-marke {
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  color: var(--faint);
  text-align: right;
}

.planung-mitte {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.planung-titel {
  color: var(--ink);
}
.planung-unter {
  font-size: 0.78rem;
  color: var(--muted);
}

.planung-status {
  font-size: 0.78rem;
  color: var(--faint);
  white-space: nowrap;
}

/* Erledigt: gruen abgehakt (Uli). Der Haken traegt die Farbe, die Zeile nur
   einen dezenten Grundton — sonst erschlaegt ein Block aus 50 Zeilen das Auge. */
.planung-zeile--erschienen {
  border-color: var(--accent-soft);
  background: var(--accent-soft);
}
.planung-zeile--erschienen .planung-haken {
  color: var(--accent);
}
.planung-zeile--erschienen .planung-status {
  color: var(--accent-deep);
}

.planung-zeile--in_arbeit {
  border-color: var(--amber-border);
  background: var(--amber-soft);
}
.planung-zeile--in_arbeit .planung-haken,
.planung-zeile--in_arbeit .planung-status {
  color: var(--amber);
}

/* Schmale Fenster: Status unter den Titel, damit nichts abgeschnitten wird. */
@media (max-width: 640px) {
  .planung-zeile {
    grid-template-columns: auto 2.2rem 1fr;
  }
  .planung-status {
    grid-column: 3;
    white-space: normal;
  }
  .planung-aktionen {
    grid-column: 3;
  }
}

/* ── Buchplanung: Bearbeiten (12.08.2026) ────────────────────────────────
   Die Werkzeuge je Zeile bleiben blass, bis die Zeile berührt wird — bei 55
   Zeilen wäre eine dauerhaft sichtbare Knopfreihe unruhig. Auf Tastatur-Fokus
   erscheinen sie ebenfalls (:focus-within), sonst wären sie ohne Maus
   unerreichbar. */
.planung-aktionen {
  display: flex;
  gap: 2px;
  opacity: 0.25;
  transition: opacity 0.12s ease-in-out;
}
.planung-zeile:hover .planung-aktionen,
.planung-zeile:focus-within .planung-aktionen {
  opacity: 1;
}
.planung-aktion svg {
  width: 15px;
  height: 15px;
}

/* Aufgeklappte Zeile: das Formular nimmt die volle Breite. */
.planung-zeile--formular {
  display: block;
  border-color: var(--accent);
  background: var(--paper);
}

.planung-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  align-items: flex-end;
}

.planung-feld {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 12rem;
  min-width: 0;
}
/* Titel und Notiz brauchen mehr Platz als Gruppe und Kennzahl. */
.planung-feld--breit {
  flex: 3 1 20rem;
}
.planung-feld-label {
  font-size: 0.74rem;
  color: var(--muted);
}
.planung-feld input,
.planung-feld select {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--sage-mid);
  border-radius: var(--radius-input);
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 0.88rem;
}
.planung-feld input:focus,
.planung-feld select:focus {
  outline: 2px solid var(--accent-ring);
  outline-offset: 1px;
  border-color: var(--accent);
}

.planung-form-aktionen {
  display: flex;
  gap: 6px;
  flex: 0 0 auto;
}

/* „Titel hinzufügen" steht unter der jeweiligen Gruppe, zurückhaltend. */
.planung-hinzu {
  margin: 6px 0 2px;
  font-size: 0.82rem;
}

/* Erläuterung unter einem Eingabefeld der Buchdaten-Maske (12.08.2026) —
   für Felder, deren Zweck sich aus dem Namen nicht erschließt (Kindle-Kennung,
   Kurztitel). */
.feld-hinweis {
  margin: 3px 0 0;
  font-size: 0.76rem;
  color: var(--muted);
}

/* Gruppen-Überschrift mit hinterlegter Erläuterung (12.08.2026): Der Fließtext
   unter jeder der fünf Gruppen war bei 50 Zeilen zu viel Masse. Die Auskunft
   hängt jetzt am Überfahren — der Mauszeiger zeigt an, dass da etwas ist. */
.planung-gruppe-titel[title] {
  cursor: help;
}
