/* Officevibe-inspiriertes Editorial-Theme: warmes Cremepapier, zwei Blautöne,
   Serif-Display mit Kursiv-Akzent. Fraunces ersetzt Martinaplantijn, Inter bleibt Inter.

   Fonts werden selbst gehostet (DSGVO + Performance), Latin-Subset, variable Fonts. */

@import url('/static/tokens.css');

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('/static/fonts/fraunces-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 400 600;
  font-display: swap;
  src: url('/static/fonts/fraunces-italic-latin.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/inter-latin.woff2') format('woff2');
}

:root {
  /* Farben: siehe tokens.css (gemeinsam mit den öffentlichen Seiten) */

  /* Typografie */
  --font-serif: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* Typo-Skala — einzige erlaubte Schriftgrößen */
  --text-xs: 12px;   /* Uppercase-Labels: Eyebrow, th, Badges */
  --text-sm: 14px;   /* Meta, Labels, Nav, kleine Buttons */
  --text-base: 16px; /* Fließtext, Inputs, Buttons */
  --text-lg: 20px;   /* h2 */
  --text-xl: 28px;   /* Stat-Zahlen */
  --text-2xl: 40px;  /* h1 */

  /* Form */
  --radius-card: 16px;
  --radius-input: 12px;
  --radius-pill: 100px;
  --shadow-card: 0 4px 24px rgba(12, 23, 84, 0.08);
  --focus-ring: 2px solid var(--cobalt);
}

* { box-sizing: border-box; }

/* Sprungziele (#log, Skip-Link) dürfen nicht unter der stehenden Kopfleiste
   landen — die Höhe der Leiste ist hier als Scroll-Reserve hinterlegt. */
html { scroll-padding-top: 80px; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--charcoal);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: 1.6;
}

a { color: var(--cobalt); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- Fokus — sichtbar für Tastatur, unaufdringlich für Maus ---------- */

:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
  border-radius: 4px;
}
button:focus-visible, .btn:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 3px;
}
.card.dark :focus-visible, pre.log :focus-visible { outline-color: var(--paper); }

/* ---------- Skip-Link & Screenreader-Utilities ---------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 8px;
  z-index: 100;
  background: var(--ink-navy);
  color: var(--paper);
  padding: 10px 20px;
  border-radius: var(--radius-pill);
}
.skip-link:focus { left: 8px; text-decoration: none; }

/* Klassen mit eigenem display (flex, grid …) überschreiben sonst das
   hidden-Attribut aus dem Browser-Stylesheet. */
[hidden] { display: none !important; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Kopfleiste ----------
   Bleibt beim Scrollen stehen: Entwurfs- und Log-Seiten werden lang, und der
   Weg zurück zur Navigation soll kein Scroll-Marathon sein. Der leichte
   Schleier plus Unschärfe hält sie vom Inhalt getrennt, ohne eine harte
   Kante über die ganze Breite zu ziehen. */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--canvas) 88%, transparent);
  border-bottom: 1px solid var(--cream-border);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
}
@supports not (backdrop-filter: blur(1px)) {
  .topbar { background: var(--canvas); }
}

.topbar-inner {
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: 1160px;
  margin: 0 auto;
  padding: 12px 32px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  color: var(--charcoal);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.02em;
}
.brand:hover { text-decoration: none; }
.brand-badge {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 9px;
  background: var(--ink-navy);
  color: var(--paper);
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
}

.mainnav {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  /* Auf schmalen Viewports wandert die Navigation in eine horizontale
     Scrollspur — besser als ein Umbruch, der die Leiste doppelt so hoch macht
     und den Inhalt nach unten drückt. */
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.mainnav::-webkit-scrollbar { display: none; }

.mainnav a {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  min-height: 38px;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  color: var(--graphite);
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 150ms ease, color 150ms ease;
}
.mainnav a svg { flex: none; color: var(--smoke); transition: color 150ms ease; }
.mainnav a:hover { text-decoration: none; background: var(--cream-border); color: var(--charcoal); }
.mainnav a:hover svg { color: var(--graphite); }
.mainnav a[aria-current="page"] {
  background: var(--lavender);
  color: var(--ink-navy);
  font-weight: 600;
}
.mainnav a[aria-current="page"] svg { color: var(--cobalt); }

/* Abmelden ist keine sechste Arbeitsseite — es steht abgesetzt am Rand
   und tritt farblich zurück, damit es niemand versehentlich trifft. */
.topbar-logout {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  min-height: 38px;
  margin-left: auto;
  padding: 0 14px;
  border-radius: var(--radius-pill);
  color: var(--stone);
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  transition: background-color 150ms ease, color 150ms ease;
}
.topbar-logout svg { flex: none; }
.topbar-logout:hover { text-decoration: none; background: var(--cream-border); color: var(--charcoal); }

/* ---------- Layout & Überschriften ---------- */

main { max-width: 1160px; margin: 0 auto; padding: 40px 32px 96px; }

/* Seitenkopf (_ui.html): Eyebrow, Display-Zeile, Fließtext, Aktionsspalte. */
.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 32px;
}
.page-head-text { min-width: 0; }
.page-head h1 { margin-bottom: 0; }
.page-head .lede { margin: 14px 0 0; }
.page-head-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }

/* Rücksprung über dem Titel: der Pfeil zeigt zurück, deshalb gedreht —
   ein eigenes Icon für dieselbe Form wäre nur mehr zu pflegen. */
.backlink { margin: 0 0 16px; font-size: var(--text-sm); }
.backlink a { display: inline-flex; align-items: center; gap: 6px; color: var(--stone); }
.backlink a:hover { color: var(--cobalt); }
.backlink svg { transform: rotate(180deg); }

/* Abschnitt ohne eigene Kartenfläche — trägt nur den Rhythmus. */
.section { margin-bottom: 40px; }
.section > .card-head { margin-bottom: 16px; }

/* Zustandsleiste unter dem Titel: Badges und Faktenchips in einer Zeile. */
.meta-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: -16px 0 32px;
}
.meta-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  background: var(--paper);
  border: 1px solid var(--cream-border);
  color: var(--stone);
  font-size: var(--text-xs);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.meta-chip svg { flex: none; color: var(--smoke); }
.meta-chip.is-star { color: var(--amber-text); }
.meta-chip.is-star svg { color: var(--amber-dot); }

.eyebrow {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--charcoal);
  margin: 0 0 16px;
}

h1 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--text-2xl);
  line-height: 1.1;
  letter-spacing: -0.8px;
  color: var(--charcoal);
  margin: 0 0 32px;
}
h1 em {
  font-style: italic;
  font-weight: 400;
}

h2 {
  font-size: var(--text-lg);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.4;
  margin: 40px 0 16px;
  color: var(--charcoal);
}
h3 {
  font-size: var(--text-base);
  font-weight: 600;
  margin: 0 0 8px;
  color: var(--charcoal);
}

.lede { color: var(--graphite); max-width: 640px; margin: -16px 0 32px; }

/* ---------- Karten ---------- */

.card {
  background: var(--paper);
  border: 1px solid var(--cream-border);
  border-radius: var(--radius-card);
  padding: 32px;
  margin-bottom: 24px;
}
.card > h2:first-child { margin-top: 0; }

.card.dark {
  background: var(--ink-navy);
  border-color: var(--ink-navy);
  color: var(--paper);
}
.card.dark .muted { color: var(--lavender); }
.card.dark .stat { color: var(--paper); }

.card.accent { border: 1.5px solid var(--cobalt); }

.card.nested {
  background: var(--canvas);
  border: 1px solid var(--cream-border);
  padding: 24px;
  margin-bottom: 16px;
}

/* Ausgeschlossene Artikel: Deckkraft allein trägt keine Bedeutung —
   das Badge „Nicht enthalten" kommt im Template dazu. */
.card.excluded { opacity: 0.65; background: var(--canvas); }

/* ---------- Flash-Meldungen ----------
   Symbol + Text: die Farbe allein trägt die Bedeutung nie. Kein Auto-Dismiss —
   die Meldung quittiert eine gerade ausgelöste Aktion und darf nicht
   wegblitzen, bevor sie gelesen ist. Schließen geht per Knopf. */

.flash {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 14px 14px 18px;
  margin-bottom: 24px;
  background: var(--sage-bg);
  border: 1px solid var(--sage-dot);
  border-radius: var(--radius-input);
  color: var(--sage-text);
  animation: rise 260ms ease-out backwards;
}
.flash-icon { display: flex; flex: none; margin-top: 1px; }
.flash-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.flash-close {
  flex: none;
  width: 32px;
  height: 32px;
  margin: -4px -4px -4px 0;
  background: transparent;
  border: none;
  color: currentColor;
  opacity: 0.7;
}
.flash-close:hover { background: rgba(0, 0, 0, 0.06); opacity: 1; }

.flash.error {
  background: var(--terracotta-bg);
  border-color: var(--terracotta-border);
  color: var(--terracotta-text);
}

/* ---------- Badges ---------- */

.badge {
  display: inline-block;
  padding: 3px 12px;
  border-radius: var(--radius-pill);
  font-size: var(--text-xs);
  font-weight: 600;
  background: var(--lavender);
  color: var(--ink-navy);
}
.badge.sent, .badge.draft_ready { background: var(--sage-bg); color: var(--sage-text); }
.badge.running { background: var(--amber-bg); color: var(--amber-text); }
.badge.failed, .badge.cancelled { background: var(--terracotta-bg); color: var(--terracotta-text); }
.badge.pending { background: var(--lavender); color: var(--ink-navy); }

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

label {
  display: block;
  color: var(--graphite);
  font-size: var(--text-sm);
  font-weight: 500;
  margin: 16px 0 6px;
}
input[type="text"], input[type="email"], input[type="password"],
input[type="time"], input[type="number"],
select, textarea {
  width: 100%;
  background: var(--paper);
  color: var(--charcoal);
  border: 1px solid var(--smoke);
  border-radius: var(--radius-input);
  padding: 10px 14px;
  font: inherit;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--cobalt);
  box-shadow: 0 0 0 3px rgba(37, 69, 255, 0.25);
}
.card.nested input, .card.nested select, .card.nested textarea { background: var(--paper); }
textarea { min-height: 90px; resize: vertical; }

/* Select: geschlossener Zustand gestylt, Popup bleibt nativ (Barrierefreiheit) */
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%230c1754' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 42px;
}

/* ---------- Auswahlgruppen (ersetzen Dropdowns bei wenigen Optionen) ----------
   Native Radios bleiben erhalten (Tastatur, Screenreader, Formular-POST),
   sind aber visuell durch die Labels ersetzt. */

fieldset.field {
  border: none;
  padding: 0;
  margin: 16px 0 0;
  min-width: 0;
}
fieldset.field > legend {
  color: var(--graphite);
  font-size: var(--text-sm);
  font-weight: 500;
  padding: 0;
  margin-bottom: 6px;
}
.field-hint {
  color: var(--stone);
  font-size: var(--text-sm);
  margin: 8px 0 0;
}

/* Segmented Control — kompakte Pillen für kurze, gleichrangige Optionen */
.segmented {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 4px;
  background: var(--canvas);
  border: 1px solid var(--cream-border);
  border-radius: var(--radius-pill);
}
.segmented > label {
  flex: 1 1 0;
  display: flex;
  margin: 0;
  cursor: pointer;
}
.segmented input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}
.segment-text {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  color: var(--graphite);
  font-size: var(--text-sm);
  font-weight: 500;
  text-align: center;
  user-select: none;
  transition: background-color 150ms ease, color 150ms ease, box-shadow 150ms ease;
}
.segmented > label:hover .segment-text { background: var(--lavender); }
.segmented input:checked + .segment-text {
  background: var(--cobalt);
  color: var(--paper);
  font-weight: 600;
  box-shadow: var(--shadow-card);
}
.segmented > label:hover input:checked + .segment-text { background: var(--cobalt-deep); }
.segmented input:focus-visible + .segment-text {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

/* Option Cards — Optionen mit erklärendem Text */
.option-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}
.option-cards > label {
  margin: 0;
  cursor: pointer;
}
.option-cards input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}
.option-body {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  height: 100%;
  padding: 14px 44px 14px 16px;
  background: var(--paper);
  border: 1px solid var(--smoke);
  border-radius: var(--radius-input);
  transition: border-color 150ms ease, background-color 150ms ease, box-shadow 150ms ease;
}
.option-cards > label:hover .option-body { border-color: var(--cobalt); }
.option-cards input:checked + .option-body {
  border-color: var(--cobalt);
  box-shadow: inset 0 0 0 1px var(--cobalt), var(--shadow-card);
  background: var(--lavender);
}
.option-cards input:focus-visible + .option-body {
  outline: var(--focus-ring);
  outline-offset: 2px;
}
.option-title {
  color: var(--ink-navy);
  font-size: var(--text-base);
  font-weight: 600;
}
.option-desc {
  color: var(--stone);
  font-size: var(--text-sm);
  line-height: 1.5;
}
/* Häkchen: Platz ist immer reserviert (kein Layout-Shift beim Wechsel) */
.option-check {
  position: absolute;
  top: 14px;
  right: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--cobalt);
  color: var(--paper);
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 150ms ease, transform 150ms ease;
}
.option-cards input:checked + .option-body .option-check {
  opacity: 1;
  transform: scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .segment-text, .option-body, .option-check { transition: none; }
}

input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--cobalt);
  flex: none;
}
/* Checkbox mit klickbarem Label in einer Zeile */
label.check {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 500;
  cursor: pointer;
  min-height: 44px;
  margin: 8px 0 0;
}

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

button, .btn {
  /* inline-flex statt inline-block: Buttons tragen Icon + Text nebeneinander,
     gap ersetzt Abstands-Hacks und zentriert das SVG optisch zur Grundlinie. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--cobalt);
  color: var(--paper);
  border: none;
  border-radius: var(--radius-pill);
  padding: 10px 24px;
  font: inherit;
  font-size: var(--text-base);
  font-weight: 500;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
button:hover, .btn:hover { background: var(--cobalt-deep); text-decoration: none; }
button:disabled { opacity: 0.5; cursor: default; }

button.secondary, .btn.secondary {
  background: transparent;
  color: var(--graphite);
  border: 1px solid var(--smoke);
}
button.secondary:hover, .btn.secondary:hover { background: var(--cream-border); border-color: var(--smoke); }

button.danger, .btn.danger {
  background: transparent;
  color: var(--terracotta-text);
  border: 1.5px solid var(--terracotta-border);
}
button.danger:hover, .btn.danger:hover { background: var(--terracotta-bg); }

button.small, .btn.small { padding: 6px 14px; font-size: var(--text-sm); }

/* Icon-Buttons (Pfeile, Stern, Grip): feste Zielfläche, SVG erbt Textfarbe */
button.icon-btn, .btn.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
}
.icon-btn svg, .btn svg { display: block; }

/* Ladezustand: JS setzt aria-busy beim Absenden (base.html) */
button[aria-busy="true"] {
  opacity: 0.7;
  cursor: progress;
}
button[aria-busy="true"]::after {
  content: '';
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: 8px;
  vertical-align: -1px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin: 16px 0; }

/* ---------- Empfänger-Liste ----------
   Ersetzt die Tabelle: eine Zeile pro Person, Zustand doppelt kodiert
   (Schalterstellung + Text), damit Farbe nie allein die Bedeutung trägt. */

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}
.card-head h2 { margin: 0; }
.card-head-note { margin: 0; color: var(--stone); font-size: var(--text-sm); }

.recipients { list-style: none; margin: 0 0 24px; padding: 0; }
.recipient {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 10px 12px;
  border-radius: var(--radius-input);
  transition: background-color 150ms ease;
}
.recipient + .recipient { box-shadow: inset 0 1px 0 var(--cream-border); }
.recipient:hover { background: var(--canvas); }

.recipient-avatar {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--lavender);
  color: var(--ink-navy);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
}
.recipient.is-admin .recipient-avatar { background: var(--cobalt); color: var(--paper); }
.recipient.is-off .recipient-avatar { background: var(--cream-border); color: var(--stone); }
.recipient-avatar svg { display: block; }

.recipient-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.recipient-mail {
  font-weight: 500;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.recipient.is-off .recipient-mail { color: var(--stone); }
.recipient-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  color: var(--stone);
  font-size: var(--text-xs);
}
.meta-sep { color: var(--smoke); }
.dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--smoke);
  flex: none;
}
.dot-on { background: var(--sage-dot); }
.dot-off { background: var(--smoke); }
.dot-alert { background: var(--terracotta-border); }

.recipient-controls { display: flex; align-items: center; gap: 2px; }
.recipient-controls form { display: flex; }
.recipient-controls .icon-btn { width: 44px; height: 44px; }

.empty-note {
  margin: 0 0 24px;
  padding: 24px;
  background: var(--canvas);
  border: 1px dashed var(--smoke);
  border-radius: var(--radius-input);
  color: var(--stone);
  text-align: center;
}

/* Schalter: nativer Submit-Button, aria-pressed trägt den Zustand */
button.switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 12px 0 8px;
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  color: var(--stone);
  font-size: var(--text-sm);
  font-weight: 500;
}
button.switch:hover { background: var(--cream-border); }
.switch-track {
  position: relative;
  width: 42px;
  height: 24px;
  flex: none;
  border-radius: var(--radius-pill);
  background: var(--smoke);
  transition: background-color 150ms ease;
}
.switch-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--paper);
  box-shadow: 0 1px 3px rgba(12, 23, 84, 0.35);
  transition: transform 150ms ease;
}
button.switch[aria-pressed="true"] { color: var(--sage-text); }
button.switch[aria-pressed="true"] .switch-track { background: var(--sage-dot); }
button.switch[aria-pressed="true"] .switch-knob { transform: translateX(18px); }
.switch-label { min-width: 46px; text-align: left; white-space: nowrap; }

/* Geister-Buttons: erst im Hover/Fokus flächig, Zielfläche immer 40px */
button.ghost {
  background: transparent;
  border: none;
  color: var(--stone);
}
button.ghost:hover { background: var(--cream-border); color: var(--charcoal); }
button.ghost.is-on { color: var(--amber-text); }
button.ghost.ghost-danger:hover { background: var(--terracotta-bg); color: var(--terracotta-text); }

/* ---------- Themen-Liste ----------
   Gleiche Sprache wie die Empfänger-Liste: eine Zeile pro Thema, Zustand
   doppelt kodiert (Schalter + Text). Die Bearbeitung liegt in einem
   aufklappbaren Panel (disclosure.js) — sonst wären sechs Themen sechs
   Textwände und die Reihenfolge nicht mehr überschaubar. */

.section-note { max-width: 62ch; margin: 0 0 20px; }

.topics { list-style: none; margin: 0 0 24px; padding: 0; }
.topic { border-radius: var(--radius-input); transition: background-color 150ms ease; }
.topic + .topic { box-shadow: inset 0 1px 0 var(--cream-border); }
/* Die offene Karte hat schon einen Rahmen — sonst stünden zwei Linien übereinander */
.topic.is-open + .topic { box-shadow: none; }
.topic:hover { background: var(--canvas); }
.topic.is-open {
  background: var(--canvas);
  box-shadow: inset 0 0 0 1px var(--cream-border);
}

.topic-head {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
}

/* Die Nummer ist keine Deko: sie zeigt die Round-Robin-Reihenfolge,
   die das Sortieren überhaupt erst bedeutsam macht. */
.topic-index {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--lavender);
  color: var(--ink-navy);
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.topic.is-off .topic-index { background: var(--cream-border); color: var(--stone); }

.topic-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Deutsche Komposita sind lang: lieber sauber trennen als mitten im Wort
   umbrechen (lang="de" steht im html-Element). */
.topic-title {
  font-weight: 500;
  line-height: 1.35;
  overflow-wrap: break-word;
  hyphens: auto;
}
.topic.is-off .topic-title { color: var(--stone); }
.topic-meta {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 6px;
  color: var(--stone);
  font-size: var(--text-xs);
  min-width: 0;
}
.topic-count { white-space: nowrap; }
/* Erste Suchanfrage als Vorschau — schneidet ab, statt die Zeile zu sprengen */
.topic-preview {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topic-preview::before { content: '· '; color: var(--smoke); }

.topic-controls { display: flex; align-items: center; gap: 2px; }
.topic-controls form { display: flex; }
.topic .switch-label { min-width: 58px; }

button.topic-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: var(--radius-pill);
  font-weight: 500;
}
.topic-toggle svg { transition: transform 150ms ease; }
.topic-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }

.topic-panel { padding: 0 12px 16px; }
.topic-panel .actions { margin-bottom: 0; }
.topic-fields { display: flex; flex-direction: column; gap: 4px; }
.topic-fields label { margin-top: 12px; }
.topic-fields textarea { min-height: 72px; }

/* Löschen sitzt rechts außen, klar abgesetzt von „Speichern“ */
.topic-actions .danger { margin-left: auto; }

/* Hinzufügen-Leiste: abgesetzt vom Bestand, eine Zeile auf Desktop */
.recipient-add, .topic-add {
  padding: 20px;
  background: var(--canvas);
  border: 1px solid var(--cream-border);
  border-radius: var(--radius-input);
}
.add-row { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 12px; }
.add-field { flex: 1 1 260px; min-width: 0; }
.add-field label { margin-top: 0; }
.add-field input { height: 44px; }
.add-submit { display: inline-flex; align-items: center; gap: 8px; height: 44px; }

label.chip-check {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  margin: 0;
  padding: 0 16px;
  background: var(--paper);
  border: 1px solid var(--smoke);
  border-radius: var(--radius-pill);
  color: var(--graphite);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
}
label.chip-check:hover { border-color: var(--cobalt); }
label.chip-check:has(input:checked) {
  background: var(--lavender);
  border-color: var(--cobalt);
  color: var(--ink-navy);
  font-weight: 500;
}
label.chip-check:has(input:focus-visible) {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

.topic-add h3 { margin: 0; }
.topic-add .actions { margin-bottom: 0; }
.topic-add input, .topic-add textarea { background: var(--paper); }

@media (max-width: 760px) {
  .recipient {
    grid-template-columns: auto minmax(0, 1fr);
    row-gap: 10px;
  }
  .recipient-controls { grid-column: 1 / -1; justify-content: flex-start; }
  .add-row > * { flex: 1 1 100%; }
  /* Griff + Nummer bleiben in Zeile 1, die Bedienelemente rutschen darunter */
  .topic-head {
    grid-template-columns: auto auto minmax(0, 1fr);
    gap: 8px;
    padding: 8px 4px;
  }
  .topic-controls { grid-column: 1 / -1; justify-content: flex-start; }
  /* Die Vorschau bliebe hier ein Zwei-Wort-Fragment — der Titel trägt die Zeile */
  .topic-preview { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .recipient, .topic, .topic-toggle svg,
  .switch-track, .switch-knob, label.chip-check { transition: none; }
}

/* ---------- Drag & Drop (Themen, Artikel) ---------- */

/* Der Griff steht in einer Zeile links neben dem Titelfeld. */
.title-row { display: flex; align-items: center; gap: 8px; }
.title-row input { flex: 1; min-width: 0; }

.drag-handle {
  flex: none;
  cursor: grab;
  color: var(--stone);
  touch-action: none;
}
.drag-handle:active { cursor: grabbing; }
[draggable="true"].dragging {
  opacity: 0.6;
  outline: 2px dashed var(--cobalt);
  outline-offset: 4px;
}
.drop-target { outline: 2px solid var(--cobalt); outline-offset: 4px; }

/* ---------- Log-Viewer (Ink Navy) ---------- */

pre.log {
  background: var(--ink-navy);
  border: none;
  border-radius: var(--radius-card);
  color: var(--lavender);
  padding: 24px;
  font-size: 13px;
  line-height: 1.55;
  overflow-x: auto;
  white-space: pre-wrap;
  max-height: 420px;
  overflow-y: auto;
}

/* ---------- Vorschau ---------- */

iframe.preview {
  width: 100%;
  height: 780px;
  border: 1px solid var(--cream-border);
  border-radius: var(--radius-card);
  background: #fff;
  box-shadow: var(--shadow-card);
}

/* ---------- Raster & Utilities ---------- */

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; }
@media (max-width: 760px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
  main { padding: 24px 16px 72px; }
  h1 { font-size: 32px; }
  .topbar-inner { gap: 12px; padding: 10px 16px; }
  /* Weiche Kante an beiden Enden: sie zeigt, dass die Leiste weitergeht.
     Ein abgeschnittenes Wort an einer harten Kante liest sich wie ein Fehler. */
  .mainnav {
    mask-image: linear-gradient(90deg, transparent, #000 14px,
                                #000 calc(100% - 14px), transparent);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 14px,
                                        #000 calc(100% - 14px), transparent);
  }
  /* Der Wortmarken-Text weicht dem Menü — das Zeichen bleibt als Anker. */
  .brand-name { display: none; }
  .topbar-logout span { display: none; }
  .topbar-logout { padding: 0 10px; }
  .page-head { margin-bottom: 24px; }
  .meta-bar { margin-top: -8px; }
}

.muted { color: var(--stone); font-size: var(--text-sm); }
.stat {
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: 500;
  letter-spacing: -0.5px;
  color: var(--ink-navy);
}

/* ---------- Login ---------- */

/* Zweiteilig: Markenseite in Ink-Navy links, Formular auf Papier rechts.
   Unter 820px klappt das Ganze zu einer Spalte, die Markenseite schrumpft
   auf das Logo-Lockup. */

.login-body {
  /* Zwei weiche Farbschleier auf dem Canvas — ersetzen ein Hintergrundbild
     (kein zusätzlicher Request, keine CLS). */
  background:
    radial-gradient(60% 55% at 12% 8%, rgba(37, 69, 255, 0.09), transparent 70%),
    radial-gradient(50% 50% at 88% 92%, rgba(240, 233, 225, 0.9), transparent 70%),
    var(--canvas);
}

.login-wrap {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px 16px;
}

.login-shell {
  display: grid;
  grid-template-columns: 1fr 1fr;
  width: 100%;
  max-width: 920px;
  background: var(--paper);
  border: 1px solid var(--cream-border);
  border-radius: 24px;
  box-shadow: 0 18px 50px rgba(12, 23, 84, 0.12);
  overflow: hidden;
}

/* ---- Markenseite ---- */

.login-brand {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding: 48px 40px;
  background: var(--ink-navy);
  color: var(--paper);
}
.login-mark {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.login-mark-badge {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: none;
  border-radius: 10px;
  background: var(--cobalt);
  color: var(--paper);
  font-family: var(--font-serif);
  font-size: 22px;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
}
.login-brand-quote {
  margin: auto 0 0;
  font-family: var(--font-serif);
  font-size: 34px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.6px;
}
.login-brand-quote em { font-style: italic; color: var(--lavender); }
.login-brand-note {
  margin: 0;
  /* Der Claim ist eine Zeile — kein Umbruch, auch wenn die Spalte eng wird. */
  white-space: nowrap;
  font-size: var(--text-sm);
  color: var(--lavender);
}

/* ---- Formularseite ---- */

.login-panel { padding: 48px 40px; }
.login-panel h1 { font-size: 32px; margin-bottom: 12px; }
.login-lead {
  margin: 0 0 28px;
  color: var(--stone);
  font-size: var(--text-sm);
}
.login-form label { margin-top: 0; }

.login-error {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.login-error svg { flex: none; margin-top: 3px; }

/* Eingabefeld mit Schloss-Symbol links und Sichtbarkeits-Schalter rechts.
   Das Feld selbst bleibt ein natives input — Padding schafft nur Platz. */
.input-affix { position: relative; display: flex; align-items: center; }
.input-affix input { padding-left: 42px; padding-right: 48px; height: 48px; }
.input-affix-icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  color: var(--stone);
  pointer-events: none;
}
.input-affix-btn {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  color: var(--stone);
  cursor: pointer;
}
/* Ohne display:block erbt das Inline-SVG die Zeilenbox samt Unterlängen-
   Reserve — das Icon säße dadurch ~4px zu hoch im Button. */
.input-affix-btn svg { display: block; }
.input-affix-btn:hover { background: var(--canvas); color: var(--charcoal); }

.login-hint {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 0;
  font-size: var(--text-sm);
  color: var(--amber-text);
}

.login-submit {
  width: 100%;
  margin-top: 24px;
  padding: 13px 24px;
  font-weight: 600;
}

.login-foot {
  margin: 24px 0 0;
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--stone);
}

@media (max-width: 820px) {
  .login-shell {
    grid-template-columns: 1fr;
    max-width: 440px;
    border-radius: 20px;
  }
  .login-brand { padding: 24px 28px; gap: 0; }
  .login-brand-quote, .login-brand-note { display: none; }
  .login-panel { padding: 32px 28px 36px; }
  .login-panel h1 { font-size: 28px; }
}

/* ==================== Listenseiten ====================
   Entwürfe, Läufe und die Dedupe-Historie teilen sich eine Zeilensprache —
   dieselbe, die Empfänger und Themen in der Konfiguration schon sprechen.
   Tabellen wären hier falsch: die Spalten trugen je einen englischen
   Datenbankschlüssel, brachen auf dem Handy und ließen sich nicht filtern. */

/* ---------- Werkzeugleiste über der Liste ---------- */

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 16px;
  margin-bottom: 20px;
}
.toolbar-status { margin: 0; font-variant-numeric: tabular-nums; }

.chip-group { display: flex; flex-wrap: wrap; gap: 6px; }

/* Filterpille. Der Zustand steht in aria-pressed — die Farbe wiederholt ihn. */
button.chip, .chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 14px;
  background: transparent;
  border: 1px solid var(--cream-border);
  border-radius: var(--radius-pill);
  color: var(--graphite);
  font-size: var(--text-sm);
  font-weight: 500;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease, color 150ms ease;
}
button.chip svg { flex: none; color: var(--smoke); }
button.chip:hover { background: var(--cream-border); color: var(--charcoal); }
button.chip[aria-pressed="true"] {
  background: var(--ink-navy);
  border-color: var(--ink-navy);
  color: var(--paper);
  font-weight: 600;
}
button.chip[aria-pressed="true"] svg { color: var(--lavender); }
button.chip[aria-pressed="true"]:hover { background: var(--charcoal); border-color: var(--charcoal); }

.chip-count {
  display: inline-grid;
  place-items: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--lavender);
  color: var(--ink-navy);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
button.chip[aria-pressed="true"] .chip-count {
  background: rgba(255, 255, 255, 0.22);
  color: var(--paper);
}

/* Suchfeld: die Lupe sitzt im Feld, das Label ist visuell versteckt —
   Platzhalter plus Symbol sagen hier genug, das Feld steht allein. */
.search-field { position: relative; display: flex; align-items: center; flex: 1 1 340px; max-width: 440px; }
.search-field input {
  height: 40px;
  padding-left: 40px;
  border-color: var(--cream-border);
  background: var(--canvas);
  font-size: var(--text-sm);
}
.search-field input:focus { background: var(--paper); }
.search-icon {
  position: absolute;
  left: 13px;
  display: flex;
  color: var(--smoke);
  pointer-events: none;
}

/* ---------- Zeilen ---------- */

.rows { list-style: none; margin: 0; padding: 0; }
.row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 12px;
  border-radius: var(--radius-input);
  transition: background-color 150ms ease;
}
.row + .row { box-shadow: inset 0 1px 0 var(--cream-border); }
.row:hover { background: var(--canvas); }
/* Zeilen mit Fehlerkasten sind mehrzeilig — Symbol und Aktionen gehören
   dann auf die Höhe des Titels, nicht in die optische Mitte des Blocks. */
.row:has(.row-error) { align-items: start; }
.row:has(.row-error) .row-dot { margin-top: 8px; }
/* Beim Filtern verschwinden Zeilen — die Trennlinie der Folgezeile
   darf dann nicht als Kante über einer Lücke stehen bleiben. */
.row[hidden] + .row { box-shadow: none; }

.row-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 12px;
  background: var(--lavender);
  color: var(--ink-navy);
}
.row.is-test .row-icon { background: var(--amber-bg); color: var(--amber-text); }

/* Statuspunkt für Läufe: wiederholt nur, was das Badge ausschreibt. */
.row-dot {
  width: 9px;
  height: 9px;
  flex: none;
  margin: 0 15px;
  border-radius: 50%;
  background: var(--smoke);
}
.row-dot.dot-sent, .row-dot.dot-draft_ready { background: var(--sage-dot); }
.row-dot.dot-running { background: var(--amber-dot); animation: pulse-dot 1.8s ease-in-out infinite; }
.row-dot.dot-failed, .row-dot.dot-cancelled { background: var(--terracotta-border); }

.row-text { min-width: 0; }
.row-title {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  color: var(--ink-navy);
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.row-title svg { flex: none; color: var(--smoke); }
.row-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 3px 0 0;
  color: var(--stone);
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}
.row-flag { display: inline-flex; align-items: center; gap: 5px; }
.row-flag svg { flex: none; }
.row-kind { letter-spacing: 0.08em; text-transform: uppercase; }

/* Der Fehlergrund ist der Anlass, die Seite zu öffnen — er bekommt eine
   eigene Zeile statt einer abgeschnittenen Tabellenspalte. */
.row-error {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin: 8px 0 0;
  padding: 8px 12px;
  background: var(--terracotta-bg);
  border-radius: 8px;
  color: var(--terracotta-text);
  font-size: var(--text-xs);
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.row-error svg { flex: none; margin-top: 2px; }

.row-actions { display: flex; align-items: center; gap: 6px; }
.row-actions form { display: flex; }
.row-actions-spacer { display: block; width: 40px; }

/* ---------- Leerzustände ----------
   Sagen, was fehlt und was als Nächstes zu tun ist. Eine graue
   Tabellenzeile „Noch keine Läufe." tut weder das eine noch das andere. */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 44px 24px;
  background: var(--canvas);
  border: 1px dashed var(--smoke);
  border-radius: var(--radius-card);
  text-align: center;
}
.empty-state-icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-bottom: 6px;
  border-radius: 14px;
  background: var(--paper);
  border: 1px solid var(--cream-border);
  color: var(--smoke);
}
.empty-state-title { margin: 0; color: var(--charcoal); font-weight: 600; }
.empty-state-hint { max-width: 46ch; margin: 0; color: var(--stone); font-size: var(--text-sm); }

@media (max-width: 760px) {
  .row {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 12px;
    row-gap: 10px;
    padding: 12px 4px;
  }
  .row-actions { grid-column: 1 / -1; justify-content: flex-start; }
  .row-actions-spacer { display: none; }
  /* Der Punkt braucht keine 40px-Spur wie ein Symbol — hier zählt jede
     Textbreite, deutsche Zeilen brechen sonst dreimal. */
  .row-dot { margin: 0 4px; }
  .row:has(.row-error) .row-dot { margin-top: 7px; }
  /* Nachrangige Meta-Angaben treten auf schmalen Viewports zurück. */
  .meta-wide { display: none; }
  .search-field { max-width: none; }
  .toolbar { align-items: stretch; }
}

/* ==================== Entwurfs-Detail ==================== */

/* Versandleiste: die drei folgenschweren Aktionen stehen beieinander und
   abgesetzt vom Bearbeiten — nicht zwischen den Textfeldern versteckt.
   „Jetzt senden" ist die einzige primäre Aktion der Seite. */
.send-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px 32px;
}
.send-bar-text { min-width: 0; flex: 1 1 320px; }
.send-bar-text h2 { margin: 0 0 6px; }
.send-bar-text p { margin: 0; max-width: 56ch; }
.send-bar-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.send-bar-actions form { display: flex; }

.article-list { display: flex; flex-direction: column; gap: 16px; }
.article-card { margin-bottom: 0; padding: 24px; }
/* Drei Zeilen Zusammenfassung passen selten in 90px — das Feld wirkt sonst
   abgeschnitten, obwohl es nur scrollt. */
.article-card textarea { min-height: 112px; }

.article-head {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  align-items: end;
  gap: 12px;
}
.article-head .drag-handle { margin-bottom: 2px; }
.article-head-field { min-width: 0; }
.article-head-field label { margin-top: 0; }
.article-head .chip-check { margin-bottom: 0; }

/* Die Nummer zeigt die Reihenfolge in der Mail — sie macht das Sortieren
   erst überprüfbar. */
.article-index {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin-bottom: 3px;
  border-radius: 50%;
  background: var(--lavender);
  color: var(--ink-navy);
  font-family: var(--font-serif);
  font-size: var(--text-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.article-card.excluded .article-index { background: var(--cream-border); color: var(--stone); }

.article-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 12px 0 0;
}
.article-title { font-size: var(--text-lg); font-weight: 500; line-height: 1.3; }
.article-summary { margin: 12px 0; color: var(--graphite); max-width: 72ch; }

/* Vorschau: die Mehrheit liest Newsletter auf dem Handy — die schmale
   Ansicht ist kein Extra, sondern der Regelfall, den man geprüft haben will. */
.preview-frame {
  --preview-max: 100%;
  max-width: var(--preview-max);
  margin: 0 auto;
  transition: max-width 220ms ease;
}
.preview-frame[data-width="mobile"] { --preview-max: 400px; }

@media (max-width: 760px) {
  /* Griff und Nummer teilen sich eine Zeile mit dem Schalter, das Titelfeld
     bekommt die volle Breite darunter — sonst bleiben davon 55 % übrig. */
  .article-head {
    grid-template-columns: auto auto minmax(0, 1fr);
    align-items: center;
    row-gap: 14px;
  }
  .article-head-field { grid-row: 2; grid-column: 1 / -1; }
  .article-head .chip-check { grid-column: 3; justify-self: end; }
  .send-bar-actions > * { flex: 1 1 100%; }
  .send-bar-actions button { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .row, button.chip, .preview-frame, .mainnav a, .topbar-logout { transition: none; }
}

/* ==================== Dashboard ====================
   Aufbau von oben nach unten nach Dringlichkeit: Was passiert gerade (Hero),
   wann passiert das Nächste (Momente), was liegt an (Entwürfe), was war
   (Log, Läufe). Aktionen stehen in einer eigenen Spalte, damit die Lesespur
   nicht ständig zwischen „ansehen" und „auslösen" springt. */

/* ---------- Hero: der Systemzustand in einem Satz ---------- */

.hero {
  --hero-accent: var(--sage-dot);
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 24px;
  padding: 32px 36px;
  margin-bottom: 16px;
  border-radius: var(--radius-card);
  background: var(--ink-navy);
  color: var(--paper);
  overflow: hidden;
  animation: rise 320ms ease-out backwards;
}
.hero[data-state="running"] { --hero-accent: var(--amber-dot); }
.hero[data-state="pending"] { --hero-accent: var(--cobalt); }

/* Farbschleier in der Zustandsfarbe statt eines zweiten Kartenhintergrunds —
   der Zustand ist so schon aus dem Augenwinkel erkennbar. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 120% at 100% 0%, var(--hero-accent), transparent 62%);
  opacity: 0.28;
  pointer-events: none;
}
.hero > * { position: relative; }

.hero-body { min-width: 0; }

.hero-kicker {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 12px;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--lavender);
}
.hero-dot {
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--hero-accent);
}
.hero[data-state="running"] .hero-dot { animation: pulse-dot 1.8s ease-in-out infinite; }

.hero-headline {
  margin: 0;
  font-family: var(--font-serif);
  font-size: 32px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -0.5px;
  color: var(--paper);
}
.hero-headline em { font-style: italic; color: var(--lavender); }

.hero-sub {
  margin: 10px 0 0;
  max-width: 52ch;
  font-size: var(--text-sm);
  color: var(--lavender);
}

/* Auf Navy trägt der Cobalt-Button zu wenig Kontrast — daher Glas statt Fläche.
   Die primäre Aktion der Seite bleibt „Jetzt generieren" in der Seitenspalte. */
.hero-action {
  flex: none;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: var(--paper);
  font-weight: 500;
}
.hero-action:hover { background: rgba(255, 255, 255, 0.22); }
.hero-action:focus-visible { outline-color: var(--paper); }

/* ---------- Momente: die drei Termine ---------- */

.moments {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin: 0 0 24px;
  padding: 0;
}
.moment {
  padding: 20px 24px;
  background: var(--paper);
  border: 1px solid var(--cream-border);
  border-radius: var(--radius-card);
  animation: rise 320ms ease-out backwards;
  animation-delay: calc(60ms + var(--i, 0) * 60ms);
}
.moment:nth-child(2) { --i: 1; }
.moment:nth-child(3) { --i: 2; }

.moment-label {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--stone);
}
.moment-label svg { flex: none; color: var(--smoke); }

.moment-value {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--text-xl);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.5px;
  color: var(--ink-navy);
  /* Ziffern gleicher Breite: die Karten „zappeln" beim Neuladen nicht */
  font-variant-numeric: tabular-nums;
}
.moment-num { font-size: 34px; }
.moment-rel { margin: 6px 0 0; font-size: var(--text-sm); color: var(--stone); }

/* ---------- Zweispaltiges Raster: Inhalt links, Aktionen rechts ---------- */

.dash-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 24px;
  align-items: start;
}
.dash-main, .dash-rail { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
/* Die Spalten setzen den Abstand per gap — die Karten-Marge würde ihn verdoppeln */
.dash-grid .card { margin-bottom: 0; }
/* Klebt unterhalb der stehenden Kopfleiste, nicht darunter verschwindend. */
.dash-rail { position: sticky; top: 80px; }
.dash-rail .card { padding: 24px; }

.card-head-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-sm);
  font-weight: 500;
}
.card-head-link svg { flex: none; }

/* ---------- Offene Entwürfe ---------- */

.draft-list { list-style: none; margin: 0; padding: 0; }
.draft-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 12px;
  border-radius: var(--radius-input);
  transition: background-color 150ms ease;
}
.draft-item + .draft-item { box-shadow: inset 0 1px 0 var(--cream-border); }
.draft-item:hover { background: var(--canvas); }

.draft-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: var(--lavender);
  color: var(--ink-navy);
}
.draft-item.is-test .draft-icon { background: var(--amber-bg); color: var(--amber-text); }

.draft-text { min-width: 0; }
.draft-title { font-weight: 600; color: var(--ink-navy); }
.draft-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 3px 0 0;
  font-size: var(--text-xs);
  color: var(--stone);
}
.draft-send { display: inline-flex; align-items: center; gap: 5px; }
.draft-send svg { flex: none; }
.draft-open { flex: none; }

/* ---------- Log ---------- */

.log-card .card-head { align-items: center; }
.log-run { font-family: var(--font-serif); color: var(--stone); font-variant-numeric: tabular-nums; }
.log-tools { display: flex; align-items: center; gap: 12px; }

.live-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  background: var(--amber-bg);
  color: var(--amber-text);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.live-dot {
  width: 7px;
  height: 7px;
  flex: none;
  border-radius: 50%;
  background: var(--amber-dot);
  animation: pulse-dot 1.8s ease-in-out infinite;
}

/* ---------- Läufe ---------- */

.run-list { list-style: none; margin: 0; padding: 0; }
.run-item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-input);
  transition: background-color 150ms ease;
}
.run-item + .run-item { box-shadow: inset 0 1px 0 var(--cream-border); }
.run-item:hover { background: var(--canvas); }

/* Der Punkt wiederholt nur, was das Badge daneben ausschreibt —
   Farbe trägt hier nie allein die Bedeutung. */
.run-dot { width: 9px; height: 9px; flex: none; border-radius: 50%; background: var(--smoke); }
.run-dot.dot-sent, .run-dot.dot-draft_ready { background: var(--sage-dot); }
.run-dot.dot-running { background: var(--amber-dot); animation: pulse-dot 1.8s ease-in-out infinite; }
.run-dot.dot-failed, .run-dot.dot-cancelled { background: var(--terracotta-border); }

.run-id { font-weight: 600; color: var(--ink-navy); font-variant-numeric: tabular-nums; }
.run-kind {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stone);
}
.run-time { display: flex; flex-direction: column; margin-left: auto; text-align: right; }
.run-rel { font-size: var(--text-sm); color: var(--graphite); }
.run-abs { font-size: var(--text-xs); color: var(--stone); font-variant-numeric: tabular-nums; }
.run-link { flex: none; color: var(--stone); }

/* ---------- Seitenspalte: Aktionen ---------- */

.rail-lead { margin: 0 0 16px; }
.rail-actions { display: flex; flex-direction: column; gap: 10px; }
.rail-actions form { display: flex; }
.rail-btn { width: 100%; }
.rail-hint {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 14px 0 0;
  font-size: var(--text-sm);
  color: var(--amber-text);
}
.rail-hint svg { flex: none; margin-top: 3px; }

/* ---------- Verbindungstest ---------- */

.diag-summary { margin: 16px 0 0; font-size: var(--text-sm); font-weight: 600; color: var(--stone); }
.diag-summary:empty { display: none; }
.diag-summary.is-ok { color: var(--sage-text); }
.diag-summary.is-fail { color: var(--terracotta-text); }

.diag-list { list-style: none; display: flex; flex-direction: column; gap: 6px; margin: 12px 0 0; padding: 0; }
.diag-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 10px;
  padding: 10px 12px;
  background: var(--canvas);
  border-radius: var(--radius-input);
  animation: rise 260ms ease-out backwards;
  animation-delay: calc(var(--i, 0) * 45ms);
}
.diag-item.is-ok { background: var(--sage-bg); }
.diag-item.is-fail { background: var(--terracotta-bg); }

.diag-icon { display: flex; margin-top: 1px; }
.diag-item.is-ok .diag-icon { color: var(--sage-text); }
.diag-item.is-fail .diag-icon { color: var(--terracotta-text); }

.diag-text { min-width: 0; }
.diag-name { margin: 0; font-size: var(--text-sm); font-weight: 600; color: var(--charcoal); }
.diag-code { font-weight: 500; color: var(--stone); font-variant-numeric: tabular-nums; }
.diag-detail {
  margin: 3px 0 0;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--graphite);
  overflow-wrap: anywhere;
}
.diag-state {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.diag-item.is-ok .diag-state { color: var(--sage-text); }
.diag-item.is-fail .diag-state { color: var(--terracotta-text); }

/* Skelett statt Spinner: die Zeilenhöhe steht schon, das Ergebnis
   ersetzt sie ohne Sprung. */
.diag-item.is-loading { animation: none; }
.sk {
  display: block;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--cream-border) 25%, var(--paper) 37%, var(--cream-border) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}
.sk-icon { width: 18px; height: 18px; border-radius: 50%; }
.sk-line { height: 10px; margin-top: 5px; }
.sk-line.short { width: 45%; margin-top: 2px; }

@keyframes shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }
@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.7); }
}
@keyframes rise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* ---------- Dashboard: schmale Viewports ---------- */

@media (max-width: 1023px) {
  .dash-grid { grid-template-columns: 1fr; }
  /* Aktionen vor die Rückschau: auf dem Handy will man auslösen, nicht scrollen */
  .dash-rail { order: -1; position: static; }
  .dash-rail .card { padding: 32px; }
}

@media (max-width: 760px) {
  .hero { padding: 24px; }
  .hero-headline { font-size: 26px; }
  .hero-action { width: 100%; }
  .moments { grid-template-columns: 1fr; gap: 12px; }
  .moment { padding: 16px 20px; }
  .draft-item { grid-template-columns: auto minmax(0, 1fr); row-gap: 10px; }
  .draft-open { grid-column: 1 / -1; justify-self: start; }
  .run-time { margin-left: 0; text-align: left; flex-direction: row; gap: 8px; align-items: baseline; }
  .run-link { margin-left: auto; }
}

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

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