/* WATTgoesON Kundenportal
   Gestaltet nach der VERBUND Corporate Identity: Brand Guide (Stand Mai 2023)
   plus eine Analyse der computed styles von verbund.com. Die Live-Website
   nutzt VERBUND-Blau praktisch überall (>1000 Treffer in einer Stichprobe)
   und Türkis so gut wie nie (1 Treffer, ein unsichtbarer Skip-Link) – daher
   ist Blau hier die dominante Farbe, mit einem dunkleren Navy-Ton als zweiter
   Stufe für Hover/Akzente statt Türkis. Buttons auf verbund.com haben 4px
   Radius (nicht die scharfen Ecken aus dem Print-Guide). Typografie: Plus
   Jakarta Sans (600/700) für Überschriften und Episodentitel, Inter
   (400/500/600) für Navigation, Fließtext, Buttons, Badges und Labels –
   beide über Google Fonts eingebunden (siehe partials/head.ejs). Das
   VERBUND-Logo selbst wird laut Guide "ausschließlich im Original"
   verwendet und daher hier nicht nachgebaut – die Wortmarke bleibt
   "WATTgoesON".

   Darkmode ist vorerst bewusst deaktiviert (auf Wunsch, für später
   aufgehoben) – alle @media (prefers-color-scheme: dark)-Blöcke im File
   wurden dafür auf das nie zutreffende "dark-disabled" umbenannt. Zum
   Wiederaktivieren einfach überall "dark-disabled" durch "dark" ersetzen. */
:root {
  --bg: #FFFFFF;
  --surface: #FFFFFF;
  --surface-sunken: #f2f6f9;   /* helles Blaugrau, wie auf verbund.com */
  --line: #ccdae8;             /* helles Blaugrau für Rahmen, wie auf verbund.com */
  --line-faded: #e6edf4;       /* --line zu 50% mit Weiß gemischt – sieht wie "--line bei opacity:0.5" aus,
                                   ist aber selbst undurchsichtig (siehe .progress-step.is-locked .progress-dot) */
  --ink: #000000;
  --ink-soft: #545454;         /* sekundärer Text, wie auf verbund.com */
  --primary: #00488e;          /* VERBUND-Blau */
  --primary-dark: #00305e;     /* dunkleres Navy für Hover/zweite Akzentstufe */
  --primary-ink: #FFFFFF;
  --accent: #00a3ae;           /* VERBUND-Türkis – bewusst kaum verwendet */
  --accent-ink: #FFFFFF;
  --success: #1a7c04;          /* VERBUND Aktionsfarbe Grün (digital) */
  --success-ink: #FFFFFF;
  --danger: #880303;           /* VERBUND Aktionsfarbe Rot (digital) */
  --warning: #a15a00;          /* Amber – nur für Kalender-To-Dos Green Forest,
                                   damit sie sich von Dreh (Navy) unterscheiden */
  --event-shoot-bg: rgba(0, 48, 94, 0.08);
  --event-release-bg: rgba(26, 124, 4, 0.08);
  --event-gf-bg: rgba(161, 90, 0, 0.1);
  --event-lc-bg: rgba(0, 163, 174, 0.1);
  --radius: 4px;
  --font-display: 'Plus Jakarta Sans', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', Arial, Helvetica, sans-serif;
}

@media (prefers-color-scheme: dark-disabled) {
  :root {
    --bg: #081524;
    --surface: #0d1f33;
    --surface-sunken: #0a1a2c;
    --line: #22456e;
    --ink: #EDF2F7;
    --ink-soft: #9fb1c4;
    --primary: #5a9ad6;
    --primary-dark: #8fc2ec;
    --primary-ink: #04101d;
    --accent: #2fc3cf;
    --accent-ink: #04101d;
    --success: #4caf3f;
    --success-ink: #04150a;
    --danger: #e2605a;
    --warning: #e3a13d;
    --event-shoot-bg: rgba(143, 194, 236, 0.16);
    --event-release-bg: rgba(76, 175, 63, 0.16);
    --event-gf-bg: rgba(227, 161, 61, 0.16);
    --event-lc-bg: rgba(47, 195, 207, 0.16);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* Episodendetailseite: leicht hellblauer Seitenhintergrund, damit die
   reinweißen Boxen (Fortschritt, Dateien, Informationen) sich abheben. */
body.episode-body { background: var(--surface-sunken); }
/* Kein Abstand zwischen Hero und Seiteninhalt – das Dashboard-Grid zieht
   sich per negativem margin-top selbst ins Header-Bild hinauf (siehe
   .dash-grid). */
body.episode-body .page { padding-top: 0; }
/* Weniger Abstand zwischen Hero-Bild und Suchleiste auf der Episodenübersicht
   (war 48px Seiten-Padding + 28px Toolbar-Margin = 76px). */
body.dashboard-body .page { padding-top: 24px; }

a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-dark); text-decoration: underline; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; margin: 0; text-wrap: balance; color: var(--primary); }
h1 { font-size: 48px; line-height: 1.15; }
input, select, textarea, button { font-family: inherit; font-size: 0.95rem; }
select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23545454' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6,9 12,15 18,9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 13px;
}
@media (prefers-color-scheme: dark-disabled) {
  select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239fb1c4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6,9 12,15 18,9'/%3E%3C/svg%3E");
  }
}

/* --- Icons --- */
.icon { width: 17px; height: 17px; flex-shrink: 0; }
.icon-sm { width: 14px; height: 14px; }
.icon-lg { width: 32px; height: 32px; }

/* --- Topbar --- */
/* Die Leiste selbst bleibt randlos (volle Breite für Hintergrund/Trennlinie),
   der eigentliche Inhalt sitzt in .topbar-inner – mit derselben maximalen
   Breite und demselben seitlichen Abstand wie der Seiteninhalt darunter
   (siehe .page), damit auf breiten Bildschirmen Logo/Navigation links
   genauso weit eingerückt sind wie Überschriften und Karten weiter unten,
   statt (wie zuvor) am äußersten Rand zu kleben während der Inhalt zentriert
   ist. Dieselbe Breite wie .page-wide, damit Episodenübersicht und
   Detailansicht denselben Content-Bereich nutzen (siehe .page-episodes). */
.topbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 30;
}
.topbar-inner {
  display: flex;
  align-items: center;
  gap: 24px;
  max-width: 1320px;
  margin: 0 auto;
  padding: 14px max(20px, env(safe-area-inset-right, 0px)) 14px max(20px, env(safe-area-inset-left, 0px));
  flex-wrap: wrap;
  row-gap: 10px;
}
.topbar-left { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }
.topbar-logo {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.2rem;
  color: var(--ink);
  white-space: nowrap;
  display: flex;
  align-items: center;
}
.topbar-logo:hover { color: var(--primary); text-decoration: none; }
.topbar-logo-img { height: 42px; width: auto; display: block; }
.topbar-divider { width: 1px; height: 20px; background: var(--line); }
.topbar-kind {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.topbar-nav { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; row-gap: 8px; }
.topbar-link {
  display: flex; align-items: center; gap: 7px;
  color: var(--ink-soft); font-weight: 500; font-size: 14px; white-space: nowrap;
  padding: 4px 0; position: relative;
}
.topbar-link:hover { color: var(--primary); text-decoration: none; }
.topbar-link.is-active { color: var(--primary); font-weight: 600; }
.topbar-link.is-active::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -15px;
  height: 2px;
  background: var(--primary);
}

.topbar-settings-toggle { position: relative; }
.topbar-settings-toggle summary { cursor: pointer; list-style: none; }
.topbar-settings-toggle summary::-webkit-details-marker { display: none; }
/* Das eigene SVG-Chevron-Icon (settings-chevron) ist nur bei Tenants mit
   Illustrator-Mockup-Topbar (tenant.topbarDark, z. B. HCW) im Markup
   vorhanden - die zugehörige Unterdrückung des generischen Unicode-Pfeils
   und die Rotation liegen deshalb tenant-gated in partials/head.ejs statt
   hier, damit WATTgoesON unverändert den ursprünglichen ' ▾'/' ▴'-Pfeil
   aus der generischen .dropdown-toggle-Regel weiter unten behält. */
.topbar-settings-menu {
  position: absolute; top: 100%; left: 0; margin-top: 12px; z-index: 20;
  display: flex; flex-direction: column; min-width: 200px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 8px 20px rgba(0, 20, 40, 0.12); padding: 6px;
}
.topbar-settings-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: var(--radius);
  color: var(--ink); font-size: 0.86rem; font-weight: 500;
}
.topbar-settings-item:hover { background: var(--surface-sunken); text-decoration: none; }
.topbar-settings-item.is-active { color: var(--primary); font-weight: 600; }

.topbar-right { display: flex; align-items: center; gap: 14px; margin-left: auto; flex-wrap: wrap; row-gap: 8px; }

.view-as-form { display: flex; align-items: center; }
.view-as-select {
  padding: 7px 32px 7px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background-color: var(--surface-sunken);
  color: var(--ink);
  font-size: 0.82rem;
  font-weight: 600;
}

.preview-banner {
  background: var(--primary-dark);
  color: var(--primary-ink);
  font-size: 0.85rem;
  font-weight: 600;
  padding: 10px max(24px, env(safe-area-inset-right, 0px)) 10px max(24px, env(safe-area-inset-left, 0px));
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.preview-banner-form button {
  background: var(--primary-ink);
  color: var(--primary-dark);
  border: none;
  border-radius: var(--radius);
  padding: 5px 12px;
  font-weight: 600;
  font-size: 0.8rem;
  cursor: pointer;
}

.topbar-user {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.25;
  font-size: 0.85rem;
}
.topbar-username { font-weight: 600; color: var(--ink); }
.topbar-role {
  font-weight: 500;
  font-size: 12px;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.topbar-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--primary-dark); color: var(--primary-ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.8rem; font-weight: 600; flex-shrink: 0;
}
.topbar-logout-form { display: flex; }
.topbar-logout-btn {
  background: none; border: 1px solid var(--line); border-radius: 50%;
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  color: var(--ink-soft); cursor: pointer;
}
.topbar-logout-btn:hover { border-color: var(--primary); color: var(--primary); }

/* --- Page shell --- */
.page {
  max-width: 980px;
  margin: 0 auto;
  padding: 48px max(20px, env(safe-area-inset-right, 0px)) 80px max(20px, env(safe-area-inset-left, 0px));
}
.page-narrow { max-width: 680px; }
.page-wide { max-width: 1320px; }
.page-episodes { max-width: 1320px; }
.page-head { margin-bottom: 32px; }
.page-sub { color: var(--ink-soft); margin: 10px 0 0; max-width: 60ch; }

/* --- Hero (Episodenübersicht) --- */
.hero {
  position: relative;
  min-height: 320px;
  display: flex;
  align-items: center;
  background: linear-gradient(135deg, var(--surface-sunken) 0%, var(--surface) 100%);
  overflow: hidden;
}
.hero::before {
  /* Hintergrundbild: public/images/hero-episodes.webp. Existiert die Datei
     nicht, bleibt es transparent und der Gradient auf .hero bleibt sichtbar.
     Etwas kleiner skaliert und rechtsbündig, damit es nicht über den
     rechten Rand hinaus zugeschnitten wird. */
  content: "";
  position: absolute;
  inset: 0;
  background-image: url('/images/hero-episodes.webp');
  background-size: 92%;
  background-position: right 65%;
  background-repeat: no-repeat;
}
.hero-overlay {
  position: absolute;
  inset: 0;
  /* Verlauf nur horizontal nach links (Textlesbarkeit), schließt früh ab
     damit der Text komplett auf Weiß steht. Keine vertikale Abblendung
     nach unten – dort endet das Bild mit einer harten Kante. */
  background: linear-gradient(100deg, var(--bg) 0%, var(--bg) 40%, rgba(255,255,255,0.95) 48%, rgba(255,255,255,0) 65%);
}
.hero-content {
  position: relative;
  z-index: 1;
  /* Zentriert auf dieselbe Breite wie .page-episodes darunter, mit demselben
     seitlichen Abstand wie .page – sorgt für eine gemeinsame linke Kante mit
     Topbar und den Episoden-Kacheln weiter unten. */
  padding: 40px max(20px, env(safe-area-inset-right, 0px)) 40px max(20px, env(safe-area-inset-left, 0px));
  max-width: 1320px;
  margin: 0 auto;
  width: 100%;
}
.hero-eyebrow {
  display: block;
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--primary);
  margin-bottom: 8px;
}
.hero-content h1 { color: var(--ink); margin-bottom: 10px; }
.hero-content p { color: var(--ink-soft); max-width: 60ch; margin: 0; font-size: 16px; line-height: 1.6; }

/* Nur bei Tenants mit Kategorien (Multi-Tenant-Plan Phase 3, z. B. HCW) –
   zeigt den Pfad vom Dashboard-Wurzel bis zur aktuellen Kategorie/Episode. */
.category-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: 13px; color: var(--ink-soft); margin-bottom: 12px; }
.category-breadcrumb a { color: var(--ink-soft); text-decoration: none; }
.category-breadcrumb a:hover { color: var(--primary); text-decoration: underline; }
.category-breadcrumb .icon { width: 13px; height: 13px; flex-shrink: 0; }
.category-breadcrumb a:last-child { color: var(--ink); font-weight: 600; }

/* --- Toolbar (Suche/Filter/Ansicht) --- */
.toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 16px 0 24px;
}
.toolbar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 220px;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink-soft);
}
.toolbar-search .icon { color: var(--ink-soft); }
.toolbar-search input {
  border: none; outline: none; background: none; flex: 1;
  font-size: 0.9rem; color: var(--ink); padding: 0;
}
.toolbar-select {
  padding: 10px 34px 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background-color: var(--surface);
  color: var(--ink);
  font-size: 0.88rem;
  font-weight: 600;
}
.toolbar-add { white-space: nowrap; border-radius: 999px; gap: 6px; }
.view-toggle { display: flex; gap: 2px; border: 1px solid var(--line); border-radius: 999px; padding: 3px; margin-left: auto; }
.view-toggle-btn {
  width: 34px; height: 34px; border-radius: 999px; border: none; background: none;
  color: var(--ink-soft); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.view-toggle-btn.is-active { background: var(--primary); color: var(--primary-ink); }

/* --- Episode grid / cards (dashboard) --- */
.episode-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 20px;
}
.episode-card[hidden] { display: none; }
.episode-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  transition: box-shadow .15s, transform .15s;
  overflow: hidden;
}
.episode-card:hover { box-shadow: 0 8px 24px rgba(0,30,60,0.12); transform: translateY(-2px); text-decoration: none; }
.episode-card-thumb {
  position: relative;
  aspect-ratio: 2.3 / 1;
  background-size: cover;
  background-position: center;
  background-color: var(--surface-sunken);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 12px;
  overflow: hidden;
}
.episode-card-thumb-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--line);
  font-size: 1.1rem;
}
.episode-card-number {
  position: relative;
  background: rgba(8,20,36,0.55);
  color: #fff;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 3px 10px;
  border-radius: 999px;
}
.status-pill-overlay { box-shadow: 0 1px 4px rgba(0,0,0,0.25); }
.status-pill-overlay.status-geplant { background: rgba(255,255,255,0.92); color: #10242b; border: none; }

.episode-card-body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 8px; flex: 1; position: relative; }
.episode-card-text { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.episode-card-body h2 { font-family: var(--font-display); font-weight: 600; font-size: 20px; line-height: 1.4; color: var(--ink); padding-right: 36px; }
.episode-card-meta { display: flex; flex-direction: column; gap: 5px; margin-top: 2px; }
.meta-item { display: flex; align-items: center; gap: 6px; font-size: 0.84rem; color: var(--ink-soft); }
.meta-item .icon { color: var(--ink-soft); }
.meta-deadline { color: var(--primary-ink); background: var(--primary-dark); padding: 3px 9px; border-radius: 999px; width: fit-content; font-weight: 600; }
.meta-deadline .icon { color: var(--primary-ink); }
.episode-card-arrow {
  position: absolute;
  right: 16px;
  bottom: 16px;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--surface-sunken);
  color: var(--primary);
  display: flex; align-items: center; justify-content: center;
}

.status-pill {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 4px 10px;
  border-radius: 999px;
  width: fit-content;
}
.status-geplant { background: var(--surface-sunken); color: var(--ink-soft); border: 1px solid var(--line); }
.status-in_produktion { background: var(--primary-dark); color: var(--primary-ink); }
.status-veroeffentlicht { background: var(--success); color: var(--success-ink); }
.action-review_comment { background: #f5c518; color: #3d2e00; }
.action-video_upload { background: var(--primary); color: var(--primary-ink); }
.action-photo_upload { background: var(--primary); color: var(--primary-ink); }
.action-audio_upload { background: var(--primary); color: var(--primary-ink); }
.action-settings { background: var(--accent); color: var(--accent-ink); }
.action-login { background: var(--surface-sunken); color: var(--ink-soft); }

/* List-Ansicht – bewusst sehr einfach gehalten: keine übereinandergelegten
   Badges auf einer winzigen Thumbnail mehr (das brach bei langen Status-
   Texten wie "IN PRODUKTION" regelmäßig um/überlappte). Nummer + Status
   stehen hier stattdessen als ganz normale Inline-Elemente im Textbereich,
   die Thumbnail ist nur noch reines Bild ohne Overlays. */
.episode-card-list-meta { display: none; }
.episode-grid-list { display: flex; flex-direction: column; gap: 10px; }
.episode-grid-list .episode-card { flex-direction: row; align-items: center; }
.episode-grid-list .episode-card-thumb {
  aspect-ratio: auto;
  width: 72px;
  height: 72px;
  flex-shrink: 0;
  align-self: center;
  padding: 0;
}
.episode-grid-list .episode-card-thumb-empty { font-size: 0.6rem; text-align: center; }
.episode-grid-list .episode-card-number,
.episode-grid-list .status-pill-overlay {
  display: none;
}
.episode-grid-list .episode-card-list-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}
.episode-grid-list .episode-card-number-plain { font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); }
.episode-grid-list .episode-card-body {
  flex-direction: row;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  flex: 1;
  min-width: 0;
}
.episode-grid-list .episode-card-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.episode-grid-list .episode-card-body h2 { padding-right: 0; font-size: 1rem; }
.episode-grid-list .episode-card-meta { flex-direction: row; flex-wrap: wrap; gap: 14px; margin-top: 0; }
.episode-grid-list .episode-card-arrow { position: static; flex-shrink: 0; }

.episode-grid-empty { color: var(--ink-soft); padding: 40px 0; text-align: center; }

/* Kategorie-Kachel (Multi-Tenant-Plan Phase 3, z. B. HCW Department/
   Studiengang-Browser) – wiederverwendet .episode-card ohne Thumbnail,
   braucht etwas mehr Innenabstand, damit sie nicht zu dünn wirkt. */
.category-tile .episode-card-body { padding: 24px; }
.category-tile .episode-card-body h2 { padding-right: 36px; }
/* Department-/Studiengang-Farbe (c.effectiveColor, siehe categoryColor() in
   server.js) als Akzentstreifen - fällt auf --primary zurück, wenn der
   Tenant keine Kategorie-Farben pflegt (--category-color dann ungesetzt). */
.category-tile { border-top: 4px solid var(--category-color, var(--primary)); }
.category-tile .episode-card-arrow { color: var(--category-color, var(--primary)); }

.empty-state {
  text-align: center;
  padding: 60px 20px;
  border: 1px dashed var(--line);
  color: var(--ink-soft);
}

/* --- Dateien-Übersicht --- */
#files-groups { display: flex; flex-direction: column; gap: 28px; margin-top: 24px; }
.files-group[hidden] { display: none; }
.files-group-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 14px;
  color: var(--ink);
}
.files-group-header:hover { text-decoration: none; }
.files-group-header:hover .files-group-name { color: var(--primary); }
.files-group-thumb {
  width: 44px; height: 44px; flex-shrink: 0; border-radius: var(--radius);
  background: var(--surface-sunken) center/cover no-repeat;
  display: flex; align-items: center; justify-content: center; color: var(--line);
}
.files-group-title { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.files-group-number { font-size: 0.72rem; font-weight: 600; color: var(--ink-soft); }
.files-group-name { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; color: var(--ink); transition: color .15s; }

.files-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px;
}
.file-tile {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
}
.file-tile[hidden] { display: none; }
.file-tile-link { position: absolute; inset: 0; z-index: 1; }
.file-tile-icon {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius);
  background: var(--surface-sunken) center/cover no-repeat;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink-soft);
}
.file-tile-icon .icon { width: 22px; height: 22px; }
.file-tile-icon-video { color: var(--primary); }
.file-tile-info { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.file-tile-label {
  font-size: 0.85rem; font-weight: 600; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.file-tile-sub { font-size: 0.74rem; color: var(--ink-soft); }
.file-tile-download {
  width: 28px; height: 28px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff;
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  box-shadow: 0 2px 8px rgba(0,20,40,0.35);
}
.file-tile-download .icon { width: 14px; height: 14px; }
.file-tile-download:hover { background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%); color: #fff; text-decoration: none; }
/* Normalfall: Button sitzt direkt im Tile, oben rechts. Beim Video sitzt die
   Positionierung stattdessen auf dem .video-download-Wrapper, damit das
   Auflösungsmenü relativ dazu aufklappt (siehe video-download.js). Der
   Wrapper bekommt einen deutlich höheren z-index als normale Download-
   Buttons, sonst legen sich benachbarte Kacheln über das aufgeklappte
   Auflösungsmenü (das visuell über die eigene Kachel hinausragt).  */
.file-tile > .file-tile-download {
  position: absolute;
  z-index: 2;
  right: 8px;
  top: 8px;
}
.file-tile-download-wrap {
  position: absolute;
  z-index: 10;
  right: 8px;
  top: 8px;
}
.file-tile-download-wrap .video-download-menu { top: 36px; right: 0; left: auto; z-index: 10; }
/* .file-tile ist ein Grid-/Flex-Item mit position:relative – dadurch bildet
   JEDE Kachel laut Spec automatisch einen eigenen Stacking-Context, egal
   welchen z-index ihre Kinder haben. Ein hoher z-index auf dem Menü allein
   reicht deshalb nicht, es bleibt in der eigenen Kachel "gefangen" und
   nachfolgende Kacheln (später im DOM) malen trotzdem darüber. Fix: die
   Kachel mit offenem Menü bekommt selbst einen höheren z-index. */
.file-tile:has(.video-download-menu:not([hidden])) { z-index: 20; }
.files-empty { color: var(--ink-soft); padding: 40px 0; text-align: center; }

/* Reine Listenansicht – keinerlei Bildervorschau, kompakte Zeilen statt Kacheln. */
#files-groups.is-list .files-group-thumb { display: none; }
#files-groups.is-list .files-grid {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
#files-groups.is-list .file-tile {
  flex-direction: row;
  align-items: center;
  gap: 12px;
  border: none;
  border-radius: 0;
  padding: 10px 14px;
}
#files-groups.is-list .file-tile-icon { display: none; }
#files-groups.is-list .file-tile-info { flex: 1; min-width: 0; }
#files-groups.is-list .file-tile-label { white-space: normal; }
#files-groups.is-list .file-tile-download,
#files-groups.is-list .file-tile-download-wrap {
  position: relative;
  z-index: 2;
  top: auto;
  right: auto;
  margin-left: auto;
  flex-shrink: 0;
}
#files-groups.is-list .file-tile-download-wrap { z-index: 10; }
#files-groups.is-list .file-tile-download-wrap .video-download-menu { top: 36px; right: 0; z-index: 10; }

/* --- Platzhalterseiten (Kalender, Dateien) --- */
.placeholder-block {
  text-align: center;
  padding: 80px 20px;
  color: var(--ink-soft);
}
.placeholder-icon {
  width: 64px; height: 64px; border-radius: 50%;
  background: var(--surface-sunken); color: var(--primary);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 20px;
}
.placeholder-block h1 { color: var(--ink); margin-bottom: 10px; }
.placeholder-block p { max-width: 50ch; margin: 0 auto; }

/* --- Episode detail: Hero-Header --- */
.episode-hero {
  position: relative;
  min-height: 300px;
  display: flex;
  align-items: flex-start;
  background: linear-gradient(135deg, var(--surface-sunken) 0%, var(--surface) 100%);
  background-size: cover;
  background-position: center;
}
.episode-hero-overlay {
  position: absolute;
  inset: 0;
  /* Nach links nur aufhellen, nie ganz deckend – das Foto soll überall
     durchscheinen, nur hell genug für guten Textkontrast. */
  background: linear-gradient(100deg, rgba(255,255,255,0.82) 0%, rgba(255,255,255,0.68) 28%, rgba(255,255,255,0.32) 52%, rgba(255,255,255,0) 76%);
}
@media (prefers-color-scheme: dark-disabled) {
  .episode-hero-overlay { background: linear-gradient(100deg, rgba(8,21,36,0.82) 0%, rgba(8,21,36,0.68) 28%, rgba(8,21,36,0.32) 52%, rgba(8,21,36,0) 76%); }
}
/* Rechte Kante genauso ausgerichtet wie die linke Kante von Topbar/Hero-Text
   (siehe .episode-hero-content): auf der Höhe der rechten Kante des
   zentrierten 1320px-Inhaltscontainers, statt (wie zuvor) fix am
   Viewport-Rand zu kleben. (100% - 1320px) / 2 + 20px ist exakt der Abstand
   zwischen Viewport-Rand und der rechten Kante dieses Containers auf breiten
   Bildschirmen; auf schmaleren Bildschirmen (Container = volle Breite)
   greift stattdessen der normale 20px/Safe-Area-Rand. */
.episode-hero-edit { position: absolute; top: 24px; right: max(20px, env(safe-area-inset-right, 0px), calc((100% - 1320px) / 2 + 20px)); z-index: 5; }
.episode-hero-edit .episode-edit-body {
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 10;
  width: min(440px, calc(100vw - 40px));
  margin-top: 8px;
}
.episode-hero-edit .episode-edit-body .form-card { padding: 22px; box-shadow: 0 8px 24px rgba(0,20,40,0.18); }
.episode-hero-edit .episode-edit-body .danger-zone { margin-top: 12px; flex-direction: column; align-items: flex-start; gap: 10px; }
.episode-hero-edit .episode-edit-body .danger-zone .btn { align-self: flex-end; }
.episode-hero-content {
  position: relative;
  z-index: 1;
  /* Oben auf gleicher Höhe wie der Bearbeiten-Button (top: 24px dort). */
  /* Zentriert auf dieselbe Breite wie .page-wide darunter, mit demselben
     seitlichen Abstand wie .page – sorgt für eine gemeinsame linke Kante mit
     Topbar und den Karten (Fortschritt, Dateien, …) weiter unten. Die
     Textspalte selbst bleibt schmal (siehe h1/meta/desc unten), damit das
     Hero-Foto rechts weiter sichtbar bleibt. */
  padding: 24px max(20px, env(safe-area-inset-right, 0px)) 56px max(20px, env(safe-area-inset-left, 0px));
  max-width: 1320px;
  margin: 0 auto;
  width: 100%;
  min-width: 0;
}
.episode-hero-content h1 {
  color: var(--primary);
  margin: 10px 0 10px;
  max-width: 640px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.episode-hero-meta { display: flex; flex-wrap: wrap; gap: 16px; margin: 0; max-width: 640px; color: var(--ink-soft); font-size: 0.92rem; }
.episode-hero-meta span { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.episode-hero-meta .icon { color: var(--primary); flex-shrink: 0; }
.episode-hero-desc { color: var(--ink-soft); max-width: 64ch; margin: 12px 0 0; }

/* --- Progress-Bar (Timeline) --- */
.progress-bar {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 24px 30px;
  background: var(--surface);
  box-sizing: border-box;
  position: relative;
  /* Schatten kommt generisch von .dash-grid > .dash-widget > .progress-bar
     (gilt für alle 4 Widget-Karten gleich, siehe .dash-grid-Kommentar) – der
     Hero-Überlapp sitzt jetzt am Grid selbst (margin-top auf .dash-grid),
     nicht mehr fix hier, da jedes Widget an die oberste Stelle wandern kann. */
}
.progress-bar h2 { font-size: 1.1rem; margin: 0 0 20px; color: var(--primary); font-family: var(--font-display); font-weight: 600; }
.progress-timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.progress-dot {
  position: relative;
  z-index: 1;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 700;
  color: #fff;
}
.progress-dot .icon { width: 13px; height: 13px; stroke-width: 3; display: block; }
.progress-step.is-done .progress-dot, .progress-branch.is-done .progress-dot { background: var(--primary-dark); border-color: var(--primary-dark); }
.progress-step.is-active .progress-dot, .progress-branch.is-active .progress-dot { border-color: var(--primary); }
/* Bewusst KEIN opacity mehr (machte den eigentlich blickdichten weißen
   Kreis durchscheinend, wodurch die Verbindungslinie dahinter sichtbar
   durch den Kreis "durchschien") – stattdessen direkt die bereits
   blass-gemischte Randfarbe, sieht identisch blass aus, bleibt aber
   undurchsichtig. */
.progress-step.is-locked .progress-dot, .progress-branch.is-locked .progress-dot { border-color: var(--line-faded); }
.progress-body { flex: 1; min-width: 0; padding-top: 1px; }
.progress-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.progress-label { font-family: var(--font-display); font-weight: 600; font-size: 0.95rem; color: var(--ink); }
.progress-step.is-locked .progress-label, .progress-branch.is-locked .progress-label { color: var(--ink-soft); }
.progress-due { font-size: 0.78rem; color: var(--ink-soft); white-space: nowrap; }
.progress-body form { margin-top: 8px; }

/* Horizontale Variante: 5 Schritte nebeneinander, verbunden durch eine
   waagrechte Linie durch die Punkte. Der Statement-Trailer-Infozweig steht
   als eigene Karte darunter (passt wegen des größeren Formulars nicht in
   eine schmale Spalte). */
.progress-track-wrap { position: relative; }
/* Die Linie ist ein echtes Element (statt ::before), weil die Farbverläufe
   pro Segment (welcher Abschnitt schon erledigt ist) serverseitig berechnet
   und als --track-stops inline mitgegeben werden – ::before kann kein
   style-Attribut vom Server bekommen. Läuft bewusst ungebrochen UNTER allen
   Punkten durch (auch gesperrten) – die sind jetzt alle blickdicht (siehe
   .progress-dot), die Linie scheint also nirgends sichtbar durch. */
.progress-track {
  position: absolute;
  z-index: 0;
  top: 11px;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(to right, var(--track-stops));
}
.progress-node-dot {
  position: absolute;
  z-index: 1;
  top: 5px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--primary);
  background: var(--surface);
  box-sizing: border-box;
}
/* Der End-Punkt bekommt dieselbe Drei-Zustände-Optik wie die normalen
   Schritte (blass/blauer Umriss/voll eingefärbt) – der Start-Punkt bleibt
   immer blau umrandet (Basisfarbe oben), da er direkt gefüllt wird, sobald
   seine Bedingung zutrifft, ohne Zwischenzustand. */
.progress-node-dot.is-locked { border-color: var(--line-faded); }
.progress-node-dot.is-active { border-color: var(--primary); }
.progress-node-dot.is-filled { background: var(--primary-dark); border-color: var(--primary-dark); }
.progress-node-start { left: 0; transform: translateX(-50%); }
.progress-node-end { right: 0; transform: translateX(50%); }
.progress-timeline-horizontal {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.progress-timeline-horizontal .progress-step {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
}
.progress-timeline-horizontal .progress-row { flex-direction: column; align-items: center; gap: 4px; }
.progress-timeline-horizontal .progress-due { white-space: normal; }
.progress-timeline-horizontal .progress-body { padding-top: 0; }

.progress-trailer-form { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; max-width: 480px; }
.progress-trailer-form textarea { resize: vertical; min-height: 110px; font-family: inherit; }
.progress-trailer-form button { align-self: flex-start; }
.progress-trailer-readonly { margin: 0 0 6px; font-size: 0.88rem; color: var(--ink); }
.progress-trailer-readonly:last-of-type { margin-bottom: 10px; }

/* Super-Admin: Zurücksetzen-Link + Zieldatum-Edit-Popover */
.progress-reset-form { margin-top: 6px; }
.progress-reset-btn {
  background: none; border: none; padding: 0; cursor: pointer;
  font-size: 0.7rem; color: var(--danger); text-decoration: underline;
}
.progress-due-edit { display: inline-block; position: relative; margin-left: 4px; }
.progress-due-edit summary {
  cursor: pointer; list-style: none; color: var(--ink-soft); font-size: 0.75rem;
  width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center;
}
.progress-due-edit summary::-webkit-details-marker { display: none; }
.progress-due-edit .dropdown-body {
  position: absolute; z-index: 5; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 4px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px; box-shadow: 0 4px 16px rgba(0,0,0,0.15);
  white-space: nowrap;
}

.thumb-row-compact { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.thumb-status { font-size: 0.85rem; color: var(--ink-soft); }

/* --- Hero-/Titelbild-Felder im Bearbeiten-Dropdown --- */
.hero-image-fields {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 20px;
}
.hero-image-field label { display: block; font-size: 12px; font-weight: 500; margin-bottom: 6px; }
.hero-image-field label .field-hint { display: inline; font-weight: 400; margin: 0; }

.dropdown-toggle { display: inline-block; }
.dropdown-toggle summary {
  cursor: pointer;
  list-style: none;
}
.dropdown-toggle summary::-webkit-details-marker { display: none; }
.dropdown-toggle summary::after { content: ' ▾'; }
.dropdown-toggle summary.btn-icon-only::after { content: ''; }
.dropdown-toggle[open] summary::after { content: ' ▴'; }
.dropdown-toggle .dropdown-body { margin-top: 10px; }

.download-all-dialog { width: min(360px, calc(100vw - 48px)); }
.download-all-options { display: flex; flex-direction: column; gap: 8px; }
.download-all-options .btn { justify-content: center; }

/* --- Admin-Dialog "Formate & Container verwalten" (Tab Medien) --- */
/* dialog.modal (höhere Spezifität: Element+Klasse) würde die schlichte
   Klassen-Regel sonst überstimmen – hier bewusst genauso spezifisch
   kombiniert, damit die größere Breite tatsächlich greift. */
dialog.modal.format-admin-dialog { width: min(900px, calc(100vw - 48px)); }
.format-admin-list { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; max-height: 75vh; overflow-y: auto; }
.format-admin-card {
  border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; background: var(--surface);
}
.format-admin-card.is-dragging { opacity: 0.4; }
.format-admin-card-head { display: flex; align-items: center; gap: 8px; }
.format-admin-drag-handle { cursor: grab; color: var(--ink-soft); font-size: 14px; user-select: none; flex-shrink: 0; }
.format-admin-name { font-weight: 600; color: var(--ink); cursor: text; padding: 2px 4px; border-radius: 4px; flex: 1; min-width: 0; }
.format-admin-name:hover { background: var(--surface-sunken); }
.format-admin-rename-input { font: inherit; font-weight: 600; width: 100%; padding: 2px 4px; border: 1px solid var(--primary); border-radius: 4px; }
.format-admin-delete { border: none; background: none; width: 26px; height: 26px; flex-shrink: 0; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: var(--ink-soft); cursor: pointer; }
.format-admin-delete svg { width: 15px; height: 15px; }
.format-admin-delete:hover { background: var(--surface-sunken); color: var(--danger); }
.format-admin-features { display: flex; flex-wrap: wrap; gap: 12px; margin: 8px 0 4px; padding-left: 22px; }
.format-admin-feature-toggle { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-soft); cursor: pointer; }
.format-admin-containers { display: flex; flex-direction: column; gap: 6px; margin: 8px 0; padding-left: 22px; }
.format-admin-container-row { display: flex; flex-direction: column; gap: 4px; padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface-sunken); }
.format-admin-container-row.is-dragging { opacity: 0.4; }
.format-admin-container-row-top { display: flex; align-items: center; gap: 8px; }
.format-admin-container-name { font-weight: 500; font-size: 0.88rem; }
.format-admin-aspect-input { width: 90px; font-size: 0.82rem; padding: 3px 6px; border: 1px solid var(--line); border-radius: 4px; flex-shrink: 0; }
.format-admin-type-select { font-size: 0.78rem; padding: 3px 4px; border: 1px solid var(--line); border-radius: 4px; flex-shrink: 0; color: var(--ink-soft); background: var(--surface); }
.format-admin-type-select:disabled { opacity: 0.55; cursor: not-allowed; }
.format-admin-container-status { flex-shrink: 0; font-size: 0.72rem; font-weight: 600; padding: 2px 7px; border-radius: 99px; white-space: nowrap; }
.format-admin-container-status.is-filled { color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent); }
.format-admin-container-status.is-empty { color: var(--ink-soft); background: var(--surface); border: 1px solid var(--line); }
.format-admin-container-files { padding-left: 30px; display: flex; flex-wrap: wrap; gap: 6px; }
.format-admin-file-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 4px 3px 10px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--line);
  font-size: 0.76rem; color: var(--ink-soft); cursor: grab;
}
.format-admin-file-chip:active { cursor: grabbing; }
.format-admin-file-chip.is-dragging { opacity: 0.4; }
.format-admin-file-chip .format-admin-file-delete { width: 20px; height: 20px; }
.format-admin-file-chip .format-admin-file-delete svg { width: 12px; height: 12px; }
.format-admin-container-row.is-file-drop-target {
  outline: 2px dashed var(--primary); outline-offset: 2px; background: color-mix(in srgb, var(--primary) 10%, var(--surface-sunken));
}
.format-admin-add-container-wrap { padding-left: 22px; margin-top: 2px; }
.format-admin-add-container { gap: 6px; }
.format-admin-add-container[hidden], .format-admin-add-container-wrap [hidden] { display: none !important; }
.format-admin-add-container input, .format-admin-add-container select { max-width: 160px; }

/* Verwaltungsseite "Produktionsschritte" (/admin/progress-steps) – nutzt
   bewusst dieselben .format-admin-card/-drag-handle/-name/-delete-Klassen
   wie der Formate-Dialog oben (gleiches Karten-/Sortier-Muster), eigene
   Seite statt Dialog, daher ohne die dort nötige max-height/overflow. */
.progress-admin-list { display: flex; flex-direction: column; gap: 14px; }
.progress-admin-step-details { margin-top: 10px; display: block; }
.progress-admin-step-details summary { cursor: pointer; font-size: 0.85rem; color: var(--ink-soft); }
.progress-admin-step-body { display: flex; flex-direction: column; gap: 12px; padding-top: 10px; border-top: 1px solid var(--line); }

/* Verwaltungsseite "Kategorien" (/admin/categories, Multi-Tenant-Plan
   Phase 3) – nutzt ebenfalls .format-admin-card/-name, Kind-Kategorien
   eingerückt + mit linker Linie abgesetzt statt verschachtelter Karten. */
.category-admin-children { margin: 10px 0 0 22px; padding-left: 14px; border-left: 2px solid var(--line); display: flex; flex-direction: column; gap: 10px; }
.category-admin-add-child { gap: 6px; margin-top: 2px; }
.category-admin-add-child input { max-width: 220px; }
.progress-admin-dependency-wrap { display: flex; flex-direction: column; gap: 8px; }
.progress-admin-dependency-title { font-size: 0.82rem; color: var(--ink-soft); margin: 0; }
.progress-admin-dependency-list { display: flex; flex-direction: column; gap: 4px; }
.progress-admin-dependency-row {
  display: flex; align-items: center; gap: 6px; padding: 5px 8px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--surface-sunken); font-size: 0.85rem;
}
.progress-admin-dependency-format { color: var(--ink-soft); }
.progress-admin-dependency-container { font-weight: 500; flex: 1; }
.progress-admin-add-dependency[hidden] { display: none !important; }
.progress-admin-add-dependency input { max-width: 220px; }
#progress-admin-add-form[hidden] { display: none !important; }

.video-download { position: relative; }
.video-download-menu[hidden] { display: none; }
.video-download-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}
.video-download-option {
  padding: 9px 12px;
  font-size: 0.82rem;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.video-download-option:last-child { border-bottom: none; }
.video-download-option:hover { background: var(--surface-sunken); color: var(--primary); }

/* --- Video-Kacheln (Podcast-Video-/Statement-Trailer-Tab) --- */
/* --- Datei-Liste (Episodenseite: "Alle Dateien"/Langform/Statement-Trailer/
   Audios) – eine gemeinsame Zeilen-Darstellung für Video und Audio, siehe
   fileRow() in episode.ejs. --- */
.file-row-list { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius); }
.file-row { display: flex; align-items: center; gap: 14px; padding: 10px 14px; background: var(--surface); flex-wrap: wrap; }
.file-row-empty .file-row-title { color: var(--ink-soft); font-style: italic; font-weight: 500; }
/* Gemeinsame Drop-Ziel-Markierung (JS-Hook, siehe container-dropzone.js) –
   leere Container (zusätzlich .file-row-empty) zeigen den Rahmen dauerhaft
   gestrichelt, bereits befüllte Zeilen bleiben optisch normal und zeigen nur
   beim tatsächlichen Drüberziehen einer Datei einen farbigen Rahmen (neue
   Version wird dann angehängt, nicht ersetzt). */
.file-row-drop-target { transition: outline-color .15s, background .15s; }
.file-row-drop-target.is-dragover { outline: 2px solid var(--primary); outline-offset: -2px; background: var(--surface-sunken); }
/* Falscher Dateityp fürs Drüberschweben erkannt (dataTransfer.items, siehe
   container-dropzone.js) – gedämpft statt der normalen Primärfarbe, damit
   sofort klar ist, dass hier nichts abgelegt werden kann. */
.file-row-drop-target.is-dragover-invalid { outline: 2px solid var(--danger); outline-offset: -2px; opacity: 0.6; }
.file-row-empty.file-row-drop-target { outline: 2px dashed var(--line); outline-offset: -2px; justify-content: space-between; }
/* Ohne .file-row-dropzone-hint (bei schon befüllten Zeilen) wäre ein
   laufender Upload sonst unsichtbar – Rahmen bleibt deshalb auch während
   des Uploads selbst sichtbar, nicht nur beim Drüberziehen. */
.file-row-drop-target.is-uploading { outline: 2px solid var(--primary); outline-offset: -2px; opacity: 0.7; }
.file-row-dropzone-hint { font-size: 0.78rem; color: var(--ink-soft); white-space: nowrap; }
.file-row-dropzone-hint.is-disabled { font-style: italic; }
.file-row-drop-target.is-uploading .file-row-dropzone-hint { color: var(--primary); }
/* kein overflow:hidden auf der Liste (würde das Download-Dropdown-Menü
   abschneiden, siehe .video-download-menu) – stattdessen die Ecken direkt
   an erster/letzter Zeile abrunden. */
.file-row-list > .file-row:first-child { border-radius: var(--radius) var(--radius) 0 0; }
.file-row-list > .file-row:last-child { border-radius: 0 0 var(--radius) var(--radius); }
.file-row-list > .file-row:only-child { border-radius: var(--radius); }

.file-row-thumb {
  position: relative; width: 112px; aspect-ratio: 16 / 9; flex-shrink: 0;
  border-radius: var(--radius); background: var(--surface-sunken); background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center; color: var(--ink-soft); overflow: hidden;
}
.file-row-thumb .icon { width: 24px; height: 24px; }
.file-row-thumb-waveform { background: var(--surface-sunken); color: var(--line); padding: 0 10px; }
.file-row-waveform-icon { width: 100%; height: 60%; stroke: none; fill: var(--accent); opacity: 0.55; }
.file-row-duration {
  position: absolute; right: 6px; bottom: 6px; background: rgba(0,0,0,0.72); color: #fff;
  font-size: 0.66rem; font-weight: 600; padding: 2px 5px; border-radius: 3px; font-variant-numeric: tabular-nums;
}

.file-row-main { display: flex; flex-direction: column; gap: 4px; flex: 1; min-width: 160px; }
.file-row-title { font-size: 0.88rem; font-weight: 600; color: var(--ink); }
.file-row-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.file-row-size { font-size: 0.76rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.file-row-filename { font-size: 0.76rem; color: var(--ink-soft); max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-row-pill {
  font-size: 0.68rem; font-weight: 600; padding: 2px 8px; border-radius: 999px;
  background: var(--event-lc-bg); color: var(--accent);
}
/* Eigene, dezente Farbe je Seitenverhältnis statt überall derselben Pille –
   bewusst nur kühle Töne (Navy/Türkis/Violett/Indigo/Petrol/Graublau),
   keine Signalfarben (Rot/Gelb/Grün), damit nichts nach Warnung aussieht.
   Audio-/Dateiformat-Pillen (WAV, MP3, MOV, MXF, ...) matchen keinen dieser
   Werte und bleiben beim normalen Türkis-Default oben. */
.file-row-pill[data-aspect="16:9"] { background: rgba(0, 72, 142, 0.12); color: #00488e; }
.file-row-pill[data-aspect="1:1"] { background: rgba(0, 131, 140, 0.14); color: #00838c; }
.file-row-pill[data-aspect="9:16"] { background: rgba(91, 63, 140, 0.14); color: #5b3f8c; }
.file-row-pill[data-aspect="4:3"] { background: rgba(58, 74, 133, 0.14); color: #3a4a85; }
.file-row-pill[data-aspect="3:4"] { background: rgba(58, 110, 130, 0.14); color: #3a6e82; }
.file-row-pill[data-aspect="4:5"] { background: rgba(12, 110, 98, 0.14); color: #0c6e62; }

.file-row-version { flex-shrink: 0; }
.file-row-version-select {
  font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); background: var(--surface-sunken);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 5px 9px; cursor: not-allowed;
}
.file-row-version-select:not(:disabled) { cursor: pointer; color: var(--ink); background: var(--surface); }
.file-row-version-select:not(:disabled):hover { border-color: var(--primary); color: var(--primary); }
.file-row-version-select.is-outdated-version {
  background: color-mix(in srgb, var(--warning) 18%, var(--surface));
  border-color: var(--warning);
  color: var(--warning);
}
.file-row-version-select.is-outdated-version:hover { border-color: var(--warning); color: var(--warning); }

/* Eigenes Versions-Dropdown (ersetzt das native <select> für Green Forest) –
   gleiches Popover-Muster wie .video-download-menu oben. */
.file-row-version-dropdown { position: relative; }
.file-row-version-trigger {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.78rem; font-weight: 600; color: var(--ink); background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 5px 9px; cursor: pointer;
}
.file-row-version-trigger:hover { border-color: var(--primary); color: var(--primary); }
.file-row-version-trigger-caret { font-size: 0.7em; line-height: 1; opacity: 0.7; }
.file-row-version-trigger.is-outdated-version {
  background: color-mix(in srgb, var(--warning) 18%, var(--surface));
  border-color: var(--warning);
  color: var(--warning);
}
.file-row-version-menu[hidden] { display: none; }
.file-row-version-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
.file-row-version-item {
  display: flex; flex-direction: column; gap: 3px;
  padding: 8px 12px; border-bottom: 1px solid var(--line);
  background: none; text-align: left; cursor: pointer; color: var(--ink);
}
.file-row-version-item:last-child { border-bottom: none; }
.file-row-version-item:hover { background: var(--surface-sunken); }
.file-row-version-item.is-active { background: color-mix(in srgb, var(--primary) 8%, transparent); cursor: default; }
.file-row-version-item-top { display: flex; align-items: center; gap: 8px; }
.file-row-version-item-num { font-weight: 600; font-size: 0.85rem; }
.file-row-version-item-badge {
  font-size: 0.68rem; font-weight: 600; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  padding: 1px 7px; border-radius: 99px;
}
.file-row-version-item-meta { display: flex; align-items: center; gap: 12px; font-size: 0.76rem; color: var(--ink-soft); }
.file-row-version-item-comments { display: flex; align-items: center; gap: 3px; }
.file-row-version-item-comments .icon { width: 13px; height: 13px; }

.file-row-status-col { display: flex; flex-direction: row; align-items: center; gap: 8px; flex-shrink: 0; }
.file-row-status-pill.is-approved { background: var(--success); color: var(--success-ink); }
.file-row-status-pill.is-review { background: var(--warning); color: #fff; }
.file-row-comments { display: flex; align-items: center; gap: 4px; font-size: 0.76rem; color: var(--ink-soft); }
.file-row-comments .icon { width: 14px; height: 14px; }

.file-row-nolink { font-size: 0.78rem; color: var(--ink-soft); font-style: italic; }
.file-row-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.file-row-delete-form { margin: 0; display: flex; }
.file-row-review-btn { white-space: nowrap; }
.file-row-download-wrap { position: relative; }
.file-row-download-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink); background: var(--surface);
}
.file-row-download-btn:hover { border-color: var(--primary); color: var(--primary); }
.file-row-download-btn .icon { width: 16px; height: 16px; }
.file-row-download-wrap .video-download-menu { left: auto; right: 0; }
.file-row-more-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink-soft); background: var(--surface); cursor: default;
}
.file-row-more-btn .icon { width: 16px; height: 16px; }

.photo-gallery-toggle .photo-grid { margin-top: 12px; }

/* Fotos-Zeile in "Alle Dateien": wie die übrigen Zeilen Teil der Liste,
   klappt per <details> an Ort und Stelle auf statt zum Fotos-Tab zu springen. */
.file-row-photos { padding: 0; flex-direction: column; align-items: stretch; }
.file-row-photos-details[open] { padding-bottom: 4px; }
.file-row-photos-summary {
  display: flex; align-items: center; gap: 14px; padding: 10px 14px; cursor: pointer; list-style: none;
}
.file-row-photos-summary::-webkit-details-marker { display: none; }
.file-row-photos-summary .file-row-download-btn { margin-left: auto; flex-shrink: 0; }
.file-row-photos-chevron { color: var(--ink-soft); flex-shrink: 0; display: inline-flex; }
.file-row-photos-chevron .icon { width: 16px; height: 16px; transition: transform .15s; }
.file-row-photos-details[open] .file-row-photos-chevron .icon { transform: rotate(90deg); }
.file-row-photos-body { padding: 0 14px 14px; }
.file-row-photos-body .photo-gallery { margin-bottom: 8px; }

@media (max-width: 640px) {
  .file-row { flex-wrap: wrap; }
  .file-row-thumb { width: 88px; }
}

/* --- Reiter (Dateien/Informationen) --- */
.tabs-nav {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 24px;
}
.tabs-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 10px 4px;
  margin-bottom: -1px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.92rem;
  color: var(--ink-soft);
  cursor: pointer;
}
.tabs-btn + .tabs-btn { margin-left: 18px; }
.tabs-btn:hover { color: var(--ink); }
.tabs-btn.is-active { color: var(--primary); font-weight: 600; border-bottom-color: var(--primary); }
.tabs-btn .icon { width: 16px; height: 16px; }
.tabs-panel[hidden] { display: none; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 26px;
  margin-bottom: 24px;
}
.card h2 { font-size: 1rem; margin-bottom: 16px; color: var(--primary); font-family: var(--font-display); font-weight: 600; }
.card-empty { color: var(--ink-soft); font-size: 0.9rem; }
.page-head .btn { margin-top: 12px; }
.page-head-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* --- Modal (native <dialog>) --- */
dialog.modal {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 26px;
  width: min(420px, calc(100vw - 48px));
  box-shadow: 0 20px 50px rgba(0, 20, 40, 0.22);
  background: var(--surface);
  color: var(--ink);
}
dialog.modal::backdrop { background: rgba(8, 21, 36, 0.45); }
dialog.modal h2 { font-size: 1.05rem; margin: 0 0 18px; color: var(--primary); font-family: var(--font-display); font-weight: 600; }
.modal-close-x {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 30px;
  height: 30px;
  border: none;
  background: transparent;
  color: var(--ink-soft);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-close-x:hover { background: var(--surface-sunken); color: var(--primary); }
.modal-form { display: flex; flex-direction: column; gap: 14px; }

/* --- User-Log (/admin/activity-log) --- */
.activity-filter-form { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
.activity-filter-form select {
  font-size: 0.85rem; padding: 7px 28px 7px 12px; border: 1px solid var(--line); border-radius: 999px;
  background-color: var(--surface); color: var(--ink); cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b6b7c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6,9 12,15 18,9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 13px;
}
.activity-user-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 7px; vertical-align: middle; }
.activity-table { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
.activity-table th {
  text-align: left; font-size: 0.72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--ink-soft); padding: 0 12px 8px 0;
}
.activity-table td { padding: 9px 12px 9px 0; border-top: 1px solid var(--line); vertical-align: top; }
.activity-table tr:first-child td { border-top: none; }
.activity-when { white-space: nowrap; color: var(--ink-soft); }
.activity-none { color: var(--ink-soft); }
.action-progress_step { background: var(--primary-dark); color: var(--primary-ink); }
.action-links_update { background: var(--accent); color: var(--accent-ink); }
.action-download { background: var(--success); color: var(--success-ink); }
.action-trailer_info { background: var(--accent); color: var(--accent-ink); }

.activity-link-cell { text-align: right; white-space: nowrap; position: relative; }
.activity-link-toggle summary { display: inline-block; padding: 2px 6px; color: var(--ink-soft); }
.activity-link-toggle summary::after { content: '▾'; }
.activity-link-toggle[open] summary::after { content: '▴'; }
/* Schwebt über der Tabelle statt in der schmalen letzten Spalte zu
   quetschen (die Spalte selbst hat keine eigene Breite, nur den Pfeil). */
.activity-link-body {
  position: absolute; top: 100%; right: 0; z-index: 20;
  display: flex; align-items: center; gap: 8px; margin-top: 4px;
  width: 360px; max-width: calc(100vw - 48px);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 10px; box-shadow: 0 8px 20px rgba(0,20,40,0.12);
  white-space: normal; text-align: left;
}
.activity-link-body a { word-break: break-all; font-size: 0.82rem; }
.activity-link-text { white-space: pre-line; font-size: 0.82rem; }
.activity-copy-btn {
  background: none; border: 1px solid var(--line); border-radius: var(--radius);
  width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0; cursor: pointer; color: var(--ink-soft);
}
.activity-copy-btn:hover { color: var(--primary); border-color: var(--primary); }
.activity-copy-btn.is-copied { color: var(--success); border-color: var(--success); }

.activity-pagination { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 20px; }
.activity-pagination-status { font-size: 0.85rem; color: var(--ink-soft); }
.btn.is-disabled { opacity: 0.4; pointer-events: none; }

/* --- Episode detail: frei anordenbares Dashboard-Grid (Produktionsfortschritt/
   Dateien/Drehorte/Gesprächspartner) --- siehe dashboard-layout.js. 12
   Spalten, FESTE Zeilenhöhe (--dash-row, muss mit DASHBOARD_ROW_PX in
   dashboard-layout.js übereinstimmen) statt content-abhängiger Höhe – nur so
   lässt sich beim Verschieben/Resizen exakt auf ganze Zellen einrasten.
   Jedes .dash-widget bekommt grid-column/-row inline aus dashboardLayout
   (episode.ejs widgetStyle()). Ragt bewusst ins Hero-Bild hinein (wie früher
   nur die Progress-Bar) – seit jedes Widget an die oberste Stelle wandern
   kann, sitzt der Überlapp jetzt am Grid selbst, nicht mehr an .progress-bar. */
.dash-grid {
  --dash-row: 24px;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: var(--dash-row);
  gap: 24px;
  position: relative;
  margin-top: -72px;
}
.dash-widget {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.dash-widget > .progress-bar,
.dash-widget > .card,
.dash-widget > .episode-col-files {
  flex: 1;
  height: 100%;
  min-height: 0;
  box-sizing: border-box;
  margin: 0;
  overflow: auto;
  box-shadow: 0 10px 24px rgba(0, 20, 40, 0.08);
}
.episode-col-files {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 26px;
  min-width: 0;
}
.dash-widget-title-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* Handles/Resize-Ecken sind standardmäßig unsichtbar und inert (siehe
   "Layout anordnen"-Button) – erst #dash-grid.is-editing schaltet sie frei,
   damit die Episodenseite im Normalzustand nicht nach Editor aussieht. */
.dash-widget-handle,
.dash-widget-resize { display: none; }
#dash-grid.is-editing .dash-widget-handle,
#dash-grid.is-editing .dash-widget-resize { display: inline-flex; }
.dash-widget-handle {
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--ink-soft);
  cursor: grab;
  border-radius: 6px;
}
.dash-widget-handle:hover { background: var(--surface-sunken); color: var(--primary); }
.dash-widget-resize {
  position: absolute;
  right: 4px;
  bottom: 4px;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  border-right: 2px solid var(--line);
  border-bottom: 2px solid var(--line);
  border-radius: 0 0 4px 0;
  transition: border-color 0.15s;
}
.dash-widget-resize:hover { border-color: var(--primary); }
/* Während eines Drags/Resizes (siehe dashboard-layout.js): is-dragging/
   is-resizing auf dem bewegten Widget selbst (angehoben, über allen anderen,
   kein Transition-"Nachziehen"), is-invalid während die aktuelle, eingeras-
   tete Kandidaten-Position/-Größe mit einem anderen Widget kollidieren würde
   (nicht einfach nichts tun – sichtbares Feedback, warum sich gerade nichts
   übernehmen lässt). */
.dash-widget.is-dragging,
.dash-widget.is-resizing { z-index: 5; }
.dash-widget.is-dragging > *,
.dash-widget.is-resizing > * { transition: none; user-select: none; }
.dash-widget.is-invalid > * { outline: 2px solid var(--danger, #d64545); outline-offset: -2px; }
#dash-grid.is-interacting { cursor: grabbing; }
.dash-edit-toolbar {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 10px 8px 16px;
  box-shadow: 0 12px 32px rgba(0, 20, 40, 0.22);
}
/* [hidden] alleine würde von der eigenen "display: flex" oben überstimmt
   (beide author-level, hidden hat ohne das hier keine höhere Spezifität). */
.dash-edit-toolbar[hidden] { display: none; }
.dash-edit-toolbar-label { font-size: 0.85rem; font-weight: 600; color: var(--primary); margin-right: 4px; white-space: nowrap; }
.dash-edit-cancel { font-size: 1.3rem; line-height: 1; }
.dash-edit-toolbar button:disabled { opacity: 0.35; pointer-events: none; }
.card-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-bottom: 16px;
}
/* dash-widget-Karten können per Resize beliebig schmal werden (siehe
   dashboard-layout.js) – ohne den flex-wrap oben würden Titel und Aktionen
   (z. B. "Alles herunterladen (ZIP)") sich bei wenig Platz überlappen statt
   die Aktionen in eine zweite Zeile zu schieben. */
.card-header-row h2 {
  display: flex; align-items: center; gap: 8px;
  font-size: 1.1rem; margin: 0; color: var(--primary);
  font-family: var(--font-display); font-weight: 600;
}
.card-header-row .btn { flex-shrink: 0; white-space: nowrap; gap: 6px; }
.card-header-row-actions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.external-link { font-size: 0.85rem; font-weight: 600; }

/* --- Fotogalerie --- */
.photo-gallery { margin-bottom: 12px; }
.photo-gallery-status { margin: 0 0 12px; }
.photo-grid[hidden] { display: none; }
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 6px;
}
.photo-thumb {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--surface-sunken);
  border-radius: var(--radius);
}
.photo-thumb::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 56%;
  background: linear-gradient(0deg, rgba(0,10,20,0.45) 0%, rgba(0,10,20,0) 100%);
  opacity: 0;
  transition: opacity .15s;
  pointer-events: none;
}
.photo-thumb:hover::after, .photo-thumb:focus-within::after { opacity: 1; }
.photo-thumb-open {
  display: block;
  width: 100%;
  height: 100%;
  border: none;
  padding: 0;
  margin: 0;
  background: none;
  cursor: pointer;
}
.photo-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .15s;
}
.photo-thumb:hover img { transform: scale(1.06); }
.photo-thumb-download {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 2;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  box-shadow: 0 3px 10px rgba(0,20,40,0.45);
  opacity: 0;
  transform: translateY(5px) scale(0.85);
  transition: opacity .15s, transform .15s, box-shadow .15s;
}
.photo-thumb-download .icon { width: 16px; height: 16px; }
.photo-thumb-download:hover {
  background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 100%);
  box-shadow: 0 4px 14px rgba(0,20,40,0.55);
  color: #fff;
  text-decoration: none;
}
.photo-thumb:hover .photo-thumb-download,
.photo-thumb-download:focus-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
.photo-thumb-delete {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 2;
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  background: rgba(20,20,20,0.55);
  box-shadow: 0 3px 10px rgba(0,20,40,0.45);
  opacity: 0;
  transform: translateY(-5px) scale(0.85);
  transition: opacity .15s, transform .15s, background .15s;
  cursor: pointer;
}
.photo-thumb-delete .icon { width: 16px; height: 16px; }
.photo-thumb-delete:hover { background: var(--danger); }
.photo-thumb:hover .photo-thumb-delete,
.photo-thumb-delete:focus-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}

/* --- Lightbox --- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(8, 15, 24, 0.92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: max(16px, env(safe-area-inset-top, 0px)) max(16px, env(safe-area-inset-right, 0px)) max(16px, env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px));
}
.lightbox[hidden] { display: none; }
.lightbox-image-wrap {
  position: relative;
  flex: 1;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
}
.lightbox-image { max-width: 100%; max-height: 100%; object-fit: contain; }
.lightbox-bar {
  width: 100%;
  max-width: 1100px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 4px;
  color: #fff;
  flex-wrap: wrap;
}
.lightbox-name { font-size: 0.85rem; opacity: 0.85; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lightbox-actions { display: flex; align-items: center; gap: 10px; }
.lightbox-counter { font-size: 0.82rem; opacity: 0.75; font-variant-numeric: tabular-nums; }
.lightbox-btn {
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.3);
  color: #fff;
  border-radius: var(--radius);
  padding: 8px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}
.lightbox-btn:hover { background: rgba(255,255,255,0.22); }
/* z-index nötig: Schließen- und Zurück-Button stehen im Markup VOR
   .lightbox-image-wrap, das (position:relative, volle Breite/Höhe) ohne
   eigenes z-index sonst rein nach DOM-Reihenfolge darüber gestapelt wird –
   die Buttons blieben dadurch sichtbar, aber ihr unsichtbarer, randloser
   Wrapper fing Klicks vorher ab (Weiter-Button kommt im Markup NACH dem
   Wrap und war daher nie betroffen). */
.lightbox-nav {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.3);
  color: #fff;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.3rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox-nav:hover { background: rgba(255,255,255,0.22); }
.lightbox-prev { left: 8px; }
.lightbox-next { right: 8px; }
.lightbox-close {
  position: absolute;
  z-index: 2;
  top: max(14px, env(safe-area-inset-top, 0px));
  right: max(14px, env(safe-area-inset-right, 0px));
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.3);
  color: #fff;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  font-size: 1.1rem;
  cursor: pointer;
}
.lightbox-close:hover { background: rgba(255,255,255,0.22); }

/* --- Lists (deadlines, locations, guests) --- */
.list { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 1px; background: var(--line); border: 1px solid var(--line); }
.list-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
}
.list-item-rich { align-items: flex-start; }
.list-item.is-done .list-item-label { text-decoration: line-through; color: var(--ink-soft); }
.list-item-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.list-item-label { font-weight: 600; }
.list-item-date { font-family: var(--font-body); font-variant-numeric: tabular-nums; font-size: 0.8rem; color: var(--ink-soft); }
.list-item-sub { font-size: 0.85rem; color: var(--ink-soft); }
.list-item-notes { font-size: 0.82rem; color: var(--ink-soft); font-style: italic; }
.list-item-remove {
  background: none; border: none; color: var(--ink-soft); cursor: pointer;
  font-size: 0.9rem; padding: 4px;
}
.list-item-remove:hover { color: var(--danger); }
.list-item-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.list-item-actions .dropdown-toggle { position: relative; }
.list-item-actions .dropdown-body { position: absolute; right: 0; z-index: 6; }
.dropdown-form { margin-bottom: 0; padding: 18px; width: max-content; max-width: min(380px, calc(100vw - 60px)); box-shadow: 0 8px 24px rgba(0,20,40,0.18); }

/* --- Karten-Listen (episode.ejs: Drehorte + Gesprächspartner, gleiches
   Layout-Muster: .location-list/.location-card wird für beide genutzt) --- */
.location-list { display: flex; flex-direction: column; gap: 14px; list-style: none; margin: 0; padding: 0; }
.location-card {
  display: flex;
  border: 1px solid var(--line); border-radius: 10px;
  padding: 14px; background: var(--surface);
}
.location-card-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 1; }
.location-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.location-card-title { font-weight: 700; font-size: 1.05rem; font-family: var(--font-display); color: var(--ink); }
.location-card-actions { flex-shrink: 0; }
.location-card-date {
  display: inline-flex; align-items: center; gap: 6px; width: fit-content;
  font-size: 0.8rem; font-weight: 600; color: var(--ink-soft);
  background: var(--surface-sunken); padding: 5px 10px; border-radius: 99px;
}
.location-card-date .icon { width: 14px; height: 14px; }
.location-card-times { font-size: 0.78rem; color: var(--ink-soft); }
.location-card-address { display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; color: var(--ink-soft); }
.location-card-address .icon { width: 14px; height: 14px; flex-shrink: 0; }
.location-card-route {
  display: inline-flex; align-items: center; gap: 6px; width: fit-content;
  font-size: 0.82rem; font-weight: 600; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  padding: 7px 12px; border-radius: 8px; margin-top: 4px;
  text-decoration: none;
}
.location-card-route:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }
.location-card-route .icon { width: 14px; height: 14px; }

/* Gesprächspartner: E-Mail/Telefon als eigene Pillen (gleiche Optik wie
   .location-card-date), statt wie bisher ein einzelnes "Kontakt"-Freitextfeld. */
.location-card-contact { display: flex; flex-wrap: wrap; gap: 8px; }
.location-card-pill {
  display: inline-flex; align-items: center; gap: 6px; width: fit-content;
  font-size: 0.8rem; color: var(--ink-soft);
  background: var(--surface-sunken); padding: 6px 10px; border-radius: 8px;
  text-decoration: none;
}
.location-card-pill:hover { color: var(--primary); }
.location-card-pill .icon { width: 14px; height: 14px; flex-shrink: 0; }

.location-add-trigger {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border: 2px dashed var(--line); border-radius: 10px;
  padding: 9px; margin-top: 14px; cursor: pointer;
  color: var(--primary); font-weight: 600; font-size: 0.9rem;
}
.dropdown-toggle summary.location-add-trigger::after { content: ''; }
.location-add-trigger:hover { border-color: var(--primary); background: var(--surface-sunken); }
.location-add-trigger-icon {
  width: 22px; height: 22px; border-radius: 50%; flex-shrink: 0;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  display: flex; align-items: center; justify-content: center; color: var(--primary);
}
.location-add-trigger-icon .icon { width: 13px; height: 13px; }
.checkbox {
  width: 20px; height: 20px; border-radius: 3px; border: 2px solid var(--line);
  background: var(--surface); cursor: pointer; flex: none;
}
.checkbox.checked { background: var(--primary); border-color: var(--primary); }

/* --- Admin / Userverwaltung --- */
.user-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.user-card { padding: 16px 18px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.user-card-header { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.user-name-form { display: flex; gap: 6px; align-items: center; flex: 1; min-width: 160px; }
.username-input {
  font-weight: 600; font-size: 0.95rem; padding: 5px 8px; border: 1px solid transparent;
  border-radius: var(--radius); background: none; color: var(--ink); min-width: 140px; flex: 1;
}
.username-input:hover, .username-input:focus { border-color: var(--line); background: var(--surface-sunken); outline: none; }
.user-card-meta { font-size: 0.8rem; color: var(--ink-soft); margin: 2px 0 14px; }

.user-field-row { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; flex-wrap: wrap; }
.user-field-row label {
  display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-soft);
  width: 120px; flex-shrink: 0;
}
.user-field-form { display: flex; gap: 6px; flex: 1; min-width: 220px; align-items: center; }
.user-field-form input { flex: 1; min-width: 140px; font-size: 0.88rem; padding: 7px 10px; }
.color-swatch-form { display: flex; align-items: center; }
.color-swatch {
  width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent;
  padding: 0; cursor: pointer; box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08); flex-shrink: 0;
  transition: transform .12s;
}
.color-swatch:hover { transform: scale(1.12); }
.color-swatch.is-selected { border-color: var(--ink); box-shadow: 0 0 0 2px var(--surface), 0 0 0 3px var(--ink); }
.color-swatch-trigger { cursor: pointer; }
.color-swatch-group {
  box-sizing: border-box;
  display: flex; gap: 7px; align-items: center; flex-wrap: nowrap;
  width: 0; height: 22px; padding: 0; margin-left: 0; overflow: hidden; opacity: 0;
  transition: width .28s ease, height .28s ease, opacity .2s ease, margin-left .28s ease, padding .28s ease;
}
.color-swatch-form.is-expanded .color-swatch-group {
  width: 300px; height: 38px; padding: 8px; margin-left: 4px; opacity: 1;
}
.password-form { position: relative; }
.password-field { font-family: var(--font-body); letter-spacing: 0.04em; }
.password-hold-btn {
  border: 1px solid var(--line); background: var(--surface); border-radius: 999px;
  width: 32px; height: 32px; display: flex; align-items: center; justify-content: center;
  color: var(--ink-soft); cursor: pointer; flex-shrink: 0; -webkit-user-select: none; user-select: none;
  touch-action: none;
}
.password-hold-btn:hover { color: var(--primary); border-color: var(--primary); }
.password-hold-btn.is-active { background: var(--primary); color: var(--primary-ink); border-color: var(--primary); }

.user-notify-toggle { margin-top: 2px; }
.user-notify-toggle summary {
  display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-soft);
}
.user-notify-body { display: flex; flex-direction: column; gap: 12px; padding: 10px 0 0 4px; }

.card-sub { color: var(--ink-soft); font-size: 0.88rem; margin: -8px 0 16px; }
.notify-global-form { margin-bottom: 6px; }
.notify-toggle-form { flex-shrink: 0; }
.toggle-switch-row { display: flex; align-items: center; gap: 8px; cursor: pointer; font-size: 0.86rem; }
.toggle-switch { position: relative; display: inline-block; width: 38px; height: 21px; flex-shrink: 0; }
.toggle-switch input {
  position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer;
}
.toggle-switch input:disabled { cursor: not-allowed; }
.toggle-slider {
  position: absolute; inset: 0; background: var(--line); border-radius: 999px;
  transition: background 0.15s; pointer-events: none;
}
.toggle-slider::before {
  content: ""; position: absolute; width: 15px; height: 15px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform 0.15s;
}
.toggle-switch input:checked + .toggle-slider { background: var(--primary); }
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(17px); }
.toggle-switch input:disabled + .toggle-slider { opacity: 0.5; }

.general-controls-categories { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.toggle-switch-row.is-disabled-by-global { opacity: 0.45; cursor: not-allowed; }

.role-form { display: flex; gap: 6px; align-items: center; }
.role-form select {
  padding: 7px 30px 7px 9px; border: 1px solid var(--line); border-radius: var(--radius);
  background-color: var(--surface); color: var(--ink); font-size: 0.85rem;
}
.badge-self {
  font-size: 12px; font-weight: 500; color: var(--ink-soft);
  background: var(--surface-sunken); padding: 4px 10px; border-radius: var(--radius);
}
.admin-error {
  background: #fdeeec;
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin-bottom: 16px;
  font-weight: 600;
}
@media (prefers-color-scheme: dark-disabled) { .admin-error { background: #2a1210; } }

.btn-danger-text { color: var(--danger); }

/* --- Forms --- */
.inline-form { display: flex; gap: 8px; flex-wrap: wrap; }
.inline-form input { flex: 1; min-width: 140px; }
/* [hidden] alleine würde von der eigenen "display: flex" oben überstimmt
   (beide author-level, hidden hat ohne das hier keine höhere Spezifität) –
   betrifft u. a. #progress-admin-add-form und #category-admin-add-root-form. */
.inline-form[hidden] { display: none; }
.inline-upload { display: flex; gap: 10px; align-items: center; }

/* --- Video-Upload-Widget ("+ Video-Format hinzufügen"-Dropdown) --- */
.video-slot-add { display: flex; flex-direction: column; gap: 10px; min-width: 240px; }
.video-upload-widget { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.video-upload-trigger { cursor: pointer; }
.video-upload-trigger[hidden] { display: none; }
.icon-flip { transform: scaleY(-1); }
.video-upload-progress { display: flex; align-items: center; gap: 8px; width: 100%; }
.video-upload-progress[hidden] { display: none; }
.video-upload-progress-track { flex: 1; height: 6px; border-radius: 999px; background: var(--surface-sunken); overflow: hidden; }
.video-upload-progress-bar { height: 100%; width: 0%; background: var(--primary); transition: width .2s; }
/* Drive-Uploads (Fotos/Audios) liefern kein echtes Fortschritts-Event wie
   der tus-Videoupload – zeigt stattdessen einen pulsierenden Balken. */
.video-upload-progress-bar.is-indeterminate { width: 60%; animation: video-upload-pulse 1.1s ease-in-out infinite; }
@keyframes video-upload-pulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
.video-upload-progress-label { font-size: 0.76rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.video-upload-cancel-btn {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 22px; height: 22px; border: none; border-radius: 999px; background: transparent;
  color: var(--ink-soft); font-size: 0.78rem; cursor: pointer; line-height: 1;
}
.video-upload-cancel-btn:hover { background: var(--surface-sunken); color: var(--danger); }
.video-upload-status { font-size: 0.8rem; margin: 0; }
.video-upload-status.is-error { color: var(--danger); }
.video-slot-or { margin: 0; }

/* --- Generischer Drive-Upload-Button (Fotos/Audio -> Google Drive) --- */
.drive-upload-widget { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; margin-top: 8px; }
.drive-upload-trigger { cursor: pointer; }
.drive-upload-trigger.is-busy { opacity: 0.6; pointer-events: none; }
.drive-upload-status { font-size: 0.8rem; margin: 0; }
.drive-upload-status.is-error { color: var(--danger); }

/* --- Bulk-Video-Upload (Tab "Video-Upload") --- */
.video-bulk-dropzone { margin: 14px 0; border: 2px dashed var(--line); border-radius: var(--radius); transition: border-color .15s, background .15s; }
.video-bulk-dropzone.is-dragover { border-color: var(--primary); background: var(--surface-sunken); }
.video-bulk-dropzone-label {
  display: flex; flex-direction: column; align-items: center; gap: 4px; text-align: center;
  padding: 28px 16px; cursor: pointer; color: var(--ink-soft);
}
.video-bulk-dropzone-label .icon { width: 28px; height: 28px; color: var(--ink-soft); margin-bottom: 4px; }
.video-bulk-dropzone-label strong { color: var(--ink); font-size: 0.95rem; }
.video-bulk-dropzone-label span { font-size: 0.8rem; }
/* --- Allzweck-Drop-Zone (legt beim Drop selbst einen neuen Container an,
   siehe universal-dropzone.js) – unten in jedem Format-Tab, nur Green
   Forest. */
.universal-dropzone {
  margin-top: 10px;
  padding: 8px 14px;
  border: 2px dashed var(--line);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  transition: border-color .15s, background .15s;
}
.universal-dropzone.is-dragover { border-color: var(--primary); background: var(--surface-sunken); }
.universal-dropzone.is-uploading { opacity: 0.65; pointer-events: none; }
.universal-dropzone-circle {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-soft);
  transition: border-color .15s, color .15s;
}
.universal-dropzone-circle svg { width: 13px; height: 13px; }
.universal-dropzone.is-dragover .universal-dropzone-circle { border-color: var(--primary); color: var(--primary); }
.universal-dropzone-text { font-size: 0.78rem; color: var(--ink-soft); text-align: center; }
.universal-dropzone-text[hidden] { display: none; }
.video-bulk-progress-list[hidden] { display: none; }
.video-bulk-progress-list { margin-bottom: 18px; }
.video-bulk-progress-row .file-row-main { gap: 6px; }
.video-bulk-section-title { font-size: 1rem; margin: 0 0 10px; }
.video-bulk-section-title-spaced { margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--line); }
.media-link-add-form { margin: 10px 0 18px; }
.video-upload-row-assign { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.video-upload-assign-select { font-size: 0.82rem; padding: 7px 9px; }
.file-row-reassign-select { font-size: 0.82rem; padding: 7px 9px; }

input[type="text"], input[type="date"], input[type="number"], input[type="password"], select, textarea {
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background-color: var(--surface);
  color: var(--ink);
}
select {
  padding-right: 32px;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

.form-card {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 30px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field label { font-weight: 500; font-size: 12px; }
.form-row-split { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field-hint { font-size: 0.78rem; color: var(--ink-soft); margin: 0; }
.media-link-add-status { margin-top: 6px; }
.media-link-add-status.is-error { color: var(--danger); }
.form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 8px; }

.danger-zone {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  margin-top: 24px; padding: 20px 24px; border: 1px solid var(--danger);
  background: #fdeeec;
  flex-wrap: wrap;
}
@media (prefers-color-scheme: dark-disabled) { .danger-zone { background: #2a1210; } }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 11px 20px; border-radius: var(--radius); border: 1px solid transparent;
  font-weight: 600; font-size: 14px; cursor: pointer; text-decoration: none;
}
.btn-sm { padding: 8px 14px; font-size: 0.82rem; }
.btn-icon-only { padding: 8px; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; }
.btn-icon-only .icon { margin: 0; }
.btn-primary { background: var(--primary); color: var(--primary-ink); }
.btn-primary:hover { background: var(--primary-dark); color: var(--primary-ink); }
.btn-ghost { background: var(--surface); border-color: var(--line); color: var(--ink); }
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-confirm-pending { background: var(--danger) !important; color: #fff !important; border-color: var(--danger) !important; }
.list-item-remove.btn-confirm-pending { color: var(--danger); font-weight: 600; white-space: nowrap; }

/* --- Login --- */
/* Eigene Klasse am <html> statt einem globalen html/body-Reset, damit NUR
   die Login-Seite (ihr eigenes, unabhängiges <html> ohne Layout-Partial)
   nicht scrollbar ist – alle anderen Seiten bleiben unberührt. */
.login-html { height: 100%; overflow: hidden; }
.login-body {
  position: relative;
  height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  overflow: hidden;
  background: #0a1f33;
}
/* Eigene, überdimensionierte Ebene fürs weichgezeichnete Hintergrundfoto
   (statt filter direkt auf .login-body), sonst würde auch die Karte
   mit-weichgezeichnet. inset:-20px + Unschärfe, damit die weichgezeichneten
   Ränder nicht als heller Rand am Viewport-Rand sichtbar werden. */
.login-bg {
  position: absolute; inset: -20px;
  background: url('/images/login-bg.jpg') center / cover no-repeat;
  filter: blur(6px);
}
.login-card {
  position: relative;
  background: var(--surface);
  border-radius: 20px;
  box-shadow: 0 24px 60px rgba(4, 16, 32, 0.35);
  padding: 48px 44px;
  max-width: 440px;
  width: 100%;
  text-align: center;
}
.login-mark { font-family: var(--font-display); font-weight: 700; font-size: 1.9rem; color: var(--primary-dark); }
.login-mark span { color: var(--primary-dark); }
.login-mark-img { height: 48px; width: auto; display: block; margin: 0 auto; }
.login-sub { color: var(--ink-soft); font-size: 0.95rem; margin: 8px 0 32px; }
.login-form { display: flex; flex-direction: column; gap: 16px; text-align: left; }
.login-form label { font-size: 13px; font-weight: 500; }
/* Direktes Kind, NICHT "button" allgemein – sonst bekommt auch der
   Passwort-Augen-Button (verschachtelt im Feld) ungewollt margin-top ab und
   sitzt dadurch nicht mehr mittig im Feld. */
.login-form > button { margin-top: 8px; }
.login-error { color: var(--danger); font-size: 0.85rem; margin: 0; font-weight: 600; }

.login-field { position: relative; display: flex; }
.login-field-icon {
  position: absolute; left: 14px; top: 50%; transform: translateY(-50%);
  color: var(--primary); pointer-events: none;
}
.login-field input {
  flex: 1; padding: 13px 16px 13px 42px; border-radius: 10px;
  background: var(--surface-sunken); border: 1px solid var(--line); font-size: 0.95rem;
}
.login-field input:focus { background: var(--surface); }
.login-password-field input { padding-right: 42px; }
.login-password-toggle {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; border: none; background: none; color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center; cursor: pointer; border-radius: 999px;
}
.login-password-toggle:hover { color: var(--primary); }
.login-remember {
  display: flex !important; flex-direction: row !important; align-items: center; gap: 8px;
  font-size: 13px !important; font-weight: 400 !important; cursor: pointer;
}
.login-remember input { width: auto; margin: 0; }
.login-submit {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 14px 20px; font-size: 1rem; border-radius: 10px;
}

/* --- Kalender --- */
.calendar-card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 20px 20px 24px;
}
.calendar-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.calendar-nav { display: flex; align-items: center; gap: 14px; }
.calendar-nav-btn {
  width: 36px; height: 36px; border-radius: 999px; border: 1px solid var(--line);
  background: none; color: var(--ink); font-size: 1.3rem; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.calendar-nav-btn:hover { background: var(--surface-sunken); }
.calendar-month-label { min-width: 200px; text-align: center; font-size: 1.4rem; }
.calendar-weekdays {
  display: grid; grid-template-columns: repeat(7, 1fr);
  font-size: 0.74rem; font-weight: 600; color: var(--ink-soft); text-transform: uppercase; letter-spacing: 0.04em;
  padding: 0 2px 8px;
  border-bottom: 1px solid var(--line);
}
.calendar-weekdays span { text-align: center; }
.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  grid-auto-rows: minmax(104px, auto);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}
.calendar-day {
  background: var(--surface);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 5px;
  min-width: 0;
}
.calendar-day.is-outside { background: var(--surface-sunken); color: var(--ink-soft); }
.calendar-day.is-outside .calendar-day-num { opacity: 0.55; }
.calendar-day.has-events { cursor: pointer; }
.calendar-day.has-events:hover { background: var(--surface-sunken); }
.calendar-day.is-outside.has-events:hover { background: var(--line-faded); }
.calendar-day-num {
  font-size: 0.8rem; font-weight: 600; width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.calendar-day.is-today .calendar-day-num {
  background: var(--primary); color: var(--primary-ink); border-radius: 50%;
}
.calendar-day-events { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.calendar-event {
  display: block;
  font-size: 0.66rem;
  font-weight: 600;
  line-height: 1.25;
  padding: 2px 5px;
  border-radius: 3px;
  border-left: 3px solid transparent;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--ink);
}
.calendar-event-more {
  display: block;
  font-size: 0.64rem;
  font-weight: 600;
  color: var(--ink-soft);
  padding: 1px 5px;
}
.calendar-event-shoot { background: var(--event-shoot-bg); border-left-color: var(--primary-dark); color: var(--primary-dark); }
.calendar-event-release { background: var(--event-release-bg); border-left-color: var(--success); color: var(--success); }
.calendar-event-todo-gf { background: var(--event-gf-bg); border-left-color: var(--warning); color: var(--warning); }
.calendar-event-todo-lc { background: var(--event-lc-bg); border-left-color: var(--accent); color: var(--accent); }
.calendar-event.is-locked { opacity: 0.55; }
.calendar-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); }
.legend-item { display: flex; align-items: center; gap: 6px; font-size: 0.8rem; color: var(--ink-soft); }
.calendar-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; display: inline-block; }
.dot-shoot { background: var(--primary-dark); }
.dot-release { background: var(--success); }
.dot-gf { background: var(--warning); }
.dot-lc { background: var(--accent); }

/* --- Kalender: "Nächste To-Dos" pro Partei (über dem Kalender) --- */
.todo-overview { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 20px; }
.todo-column {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 16px 18px;
}
.todo-column h2 {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.95rem; margin: 0 0 12px; color: var(--ink);
}
.todo-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; max-height: 280px; overflow-y: auto; }
.todo-item-link {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--radius);
  text-decoration: none; color: var(--ink);
}
.todo-item-link:hover { background: var(--surface-sunken); }
.todo-item-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.todo-item-label { font-size: 0.82rem; font-weight: 600; }
.todo-item-episode { font-size: 0.74rem; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.todo-item-due { font-size: 0.74rem; color: var(--ink-soft); flex-shrink: 0; white-space: nowrap; }
.todo-item.is-urgent .todo-item-link { border-color: var(--danger); background: rgba(136, 3, 3, 0.05); }
.todo-item.is-urgent .todo-item-due { color: var(--danger); font-weight: 700; }
.todo-urgent-badge {
  flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%;
  background: var(--danger); color: #fff; font-size: 0.72rem; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
}
.todo-empty { font-size: 0.84rem; color: var(--ink-soft); padding: 6px 2px; }

/* --- Kalender: Tages-Detail-Popup --- */
.calendar-day-modal { width: min(540px, calc(100vw - 48px)); }
.calendar-day-modal-body { display: flex; flex-direction: column; gap: 10px; max-height: 58vh; overflow-y: auto; margin-bottom: 16px; }
.calendar-day-modal-event { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); }
.calendar-day-modal-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.calendar-day-modal-info { flex: 1; min-width: 0; }
.calendar-day-modal-kind { font-weight: 600; font-size: 0.88rem; }
.calendar-day-modal-episode { font-size: 0.8rem; color: var(--ink-soft); }
.calendar-day-modal-locked-tag { font-size: 0.7rem; color: var(--ink-soft); font-style: italic; margin-top: 2px; }

@media (max-width: 720px) {
  .todo-overview { grid-template-columns: 1fr; }
  .form-row-split { grid-template-columns: 1fr; }
  .topbar-nav { gap: 10px; }
  /* Logo, Navigation und Nutzer-Block bekommen auf schmalen Viewports je
     eine eigene volle Zeile (statt unvorhersehbar mal zusammen, mal getrennt
     umzubrechen, je nachdem ob "Team" gerade noch in die Nav-Zeile passt) –
     sauber gestapelt statt flackernd je nach exakter Breite. */
  .topbar-left, .topbar-nav, .topbar-right { flex-basis: 100%; }
  .topbar-right { margin-left: 0; justify-content: space-between; }
  .calendar-grid { grid-auto-rows: minmax(88px, auto); }
  .calendar-event { font-size: 0.64rem; padding: 2px 4px; }
  .calendar-month-label { min-width: 0; font-size: 1.1rem; }
  /* Freies Drag&Resize-Grid (dash-grid) ergibt auf Handy-Breite keinen Sinn
     (zu wenig Platz für Spalten/Resize-Handles) – stattdessen fix
     gestapelt in fester Lesereihenfolge, die individuelle Episoden-
     Anordnung (dashboardLayout, nur Desktop editierbar) wird hier bewusst
     ignoriert. !important nötig, weil grid-column/-row inline pro Widget
     gesetzt sind (siehe episode.ejs widgetStyle()). */
  .dash-grid { grid-template-columns: 1fr !important; grid-auto-rows: auto !important; gap: 20px; margin-top: 0; }
  .dash-widget { grid-column: 1 / -1 !important; grid-row: auto !important; height: auto; }
  .dash-widget > .progress-bar,
  .dash-widget > .card,
  .dash-widget > .episode-col-files { height: auto; overflow: visible; }
  .dash-widget[data-widget-id="progress"] { order: 1; }
  .dash-widget[data-widget-id="files"] { order: 2; }
  .dash-widget[data-widget-id="locations"] { order: 3; }
  .dash-widget[data-widget-id="guests"] { order: 4; }
  /* Die Gradient-über-Foto-Technik braucht Breite, um den Text vom Bild
     freizuhalten – bei schmalen Viewports stattdessen stapeln: Foto oben in
     fixem Seitenverhältnis (nur Optik), Text darunter auf eigenem,
     deckendem Hintergrund statt über dem Bild. */
  .episode-hero { flex-direction: column; align-items: stretch; min-height: 0; }
  .episode-hero::before { content: ""; display: block; padding-top: 46%; }
  .episode-hero-overlay { display: none; }
  .episode-hero-content { max-width: none; background: var(--bg); padding: 20px 20px 24px; }
  .episode-hero-content h1 { white-space: normal; overflow: visible; text-overflow: clip; }
  body.episode-body .page { padding-top: 48px; }
  .progress-bar { padding: 20px; }

  /* Die horizontale 5-Spalten-Variante braucht Breite, die mobil fehlt – pro
     Schritt bleiben dann nur ~60px, wodurch sich die Labels der Nachbar-
     schritte gegenseitig überlappen. Auf schmalen Viewports stattdessen eine
     normale, gestapelte Liste: Punkt links, Text rechts daneben,
     Verbindungslinie senkrecht statt waagrecht. */
  .progress-timeline-horizontal {
    flex-direction: column;
    gap: 20px;
    /* Platz oben/unten für die neuen Start-/End-Punkte, sonst überlappen sie
       mit dem ersten/letzten echten Schritt-Punkt (der auf Mobile sonst
       direkt am Rand des Containers sitzt). */
    padding: 24px 0;
  }
  /* Linie läuft mobil senkrecht statt waagrecht – dieselben --track-stops
     (vom Server als Farbliste ohne Richtung mitgegeben) einfach in die
     andere Gradient-Richtung einsetzen, statt eine zweite Variante zu
     berechnen. */
  .progress-track {
    top: 0;
    bottom: 0;
    left: 11px;
    right: auto;
    width: 2px;
    height: auto;
    background: linear-gradient(to bottom, var(--track-stops));
  }
  .progress-node-dot { top: auto; left: 11px; transform: translate(-50%, -50%); }
  .progress-node-start { top: 7px; }
  .progress-node-end { top: auto; bottom: 7px; right: auto; transform: translate(-50%, 50%); }
  .progress-timeline-horizontal .progress-step {
    flex-direction: row;
    align-items: flex-start;
    text-align: left;
    gap: 14px;
  }
  .progress-timeline-horizontal .progress-row {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
  }
  .progress-timeline-horizontal .progress-due { white-space: nowrap; }

  /* Derselbe Stapel-Trick für den Hero auf der Episodenübersicht: der
     Verlauf-übers-Foto-Effekt (.hero-overlay) braucht Breite, auf schmalen
     Viewports deckt das Foto sonst fast die ganze Breite ab und der Text
     sitzt direkt (schlecht lesbar) darüber. Stattdessen Foto oben in festem
     Seitenverhältnis, Text darunter auf eigenem, deckendem Hintergrund. */
  .hero { flex-direction: column; align-items: stretch; min-height: 0; background: var(--bg); }
  .hero::before { position: static; inset: auto; display: block; padding-top: 46%; background-size: cover; background-position: center; }
  .hero-overlay { display: none; }
  .hero-content { max-width: none; margin: 0; padding: 20px 20px 24px; }
}

/* --- Review-Player (eigene Kommentar-/Pin-Oberfläche statt Vimeo-Review,
   siehe General Controls) – eigene Seite (kein Overlay/Dialog), damit
   Browser-Zurück normal funktioniert. Portierung des lokal erprobten
   Prototyps, Farben/Radius auf die bestehenden Portal-Variablen umgestellt. --- */
.review-player-page { padding-top: 16px; }
.review-player-page-head { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; margin-bottom: 18px; }
.review-player-page-head .btn svg { width: 15px; height: 15px; margin-right: 2px; }
.review-player-page-head h1 { margin: 2px 0 0; font-size: 21px; line-height: 1.3; }
.review-player-version-pill { display: inline-flex; vertical-align: middle; margin-left: 2px; }
.review-player-page-head .page-sub { margin: 0; font-size: 13.5px; }

.review-player-loading, .review-player-error, .review-player-processing { padding: 60px 20px; text-align: center; color: var(--ink-soft); }
.review-player-error { color: var(--danger); }
.review-player-processing-sub { font-size: 0.82rem; margin-top: 6px; }
.spinner {
  display: inline-block; width: 28px; height: 28px; margin-bottom: 12px;
  border: 3px solid var(--line); border-top-color: var(--primary); border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
/* Die LINKE Spalte (Video/Timeline/Composer) soll allein die Höhe der Zeile
   bestimmen – die rechte Spalte (Kommentare) soll dem exakt folgen, aber NIE
   selbst die Zeile höher machen (z. B. bei vielen Kommentaren). Mit Grid
   "align-items:stretch" würde stattdessen die JEWEILS höhere Spalte
   gewinnen (symmetrisch) – bei vielen Kommentaren und wenig Hauptinhalt
   bliebe dann links ein riesiger Leerraum. Stattdessen: .review-player-main
   bleibt normaler Fluss (bestimmt per eigenem Inhalt die Höhe von
   .review-player-body), .review-player-sidebar wird per position:absolute
   aus dem Höhen-Berechnung herausgenommen und exakt auf top:0/bottom:0
   gezogen – folgt also exakt der von main bestimmten Höhe, kann sie aber
   selbst nie vergrößern. Die Kommentarliste bleibt intern scrollbar. */
.review-player-body {
  position: relative;
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
  background: var(--surface);
}
.review-player-main { padding: 20px; min-width: 0; margin-right: 360px; }
.review-player-sidebar {
  position: absolute; top: 0; right: 0; bottom: 0; width: 360px;
  border-left: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0;
}
@media (max-width: 880px) {
  .review-player-main { margin-right: 0; }
  .review-player-sidebar { position: static; width: auto; border-left: none; border-top: 1px solid var(--line); }
}

.review-player-main .player-wrap {
  position: relative; background: #000; max-height: 60vh; margin: 0 auto;
  aspect-ratio: 16/9; transition: aspect-ratio .2s; border-radius: var(--radius); overflow: hidden;
}
/* Vollbild (Fullscreen API): eigene Aspect-Ratio/Höhenbegrenzung aufheben –
   der Vimeo-Player selbst (responsive:true beim Erstellen) sorgt innerhalb
   der Box bereits für korrektes Letterboxing, braucht dafür nur die volle
   Fläche. */
.review-player-main .player-wrap:fullscreen,
.review-player-main .player-wrap:-webkit-full-screen {
  width: 100%; height: 100%; max-height: 100%; aspect-ratio: auto; border-radius: 0;
}
.review-player-main .player-wrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; pointer-events: none; }

/* Audio-Review-Player: Waveform statt Video-Bild (siehe audio-review-player.js)
   – zwei deckungsgleiche Canvases (graue Basis + farbige Kopie), die farbige
   steckt in einem Wrapper, dessen Breite beim Abspielen wächst und den Rest
   per overflow:hidden abschneidet, statt bei jedem timeupdate neu zu zeichnen. */
.audio-wave-wrap {
  position: relative; height: 140px; border-radius: var(--radius);
  background: var(--surface-sunken); cursor: pointer; overflow: hidden;
}
.audio-wave-wrap canvas { position: absolute; top: 0; left: 0; display: block; }
.audio-wave-progress { position: absolute; inset: 0; width: 0%; overflow: hidden; pointer-events: none; }
.review-player-main .fullscreen-btn {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  width: 34px; height: 34px; border-radius: 999px; cursor: pointer;
}
.review-player-main .fullscreen-btn svg { width: 15px; height: 15px; }
.review-player-main .fullscreen-btn:hover { border-color: var(--primary); color: var(--primary); }

/* Vollbild-Overlay-Leiste – play-btn/.timeline-area/.volume-control werden
   per JS (siehe review-player.js) nur WÄHREND Vollbild hierher verschoben,
   damit im Vollbild wirklich nur diese drei Bedienelemente + der
   Beenden-Button sichtbar sind (kein Pin/Kommentar/Qualitäts-Dropdown).
   Blendet bei Wiedergabe nach kurzer Mausinaktivität aus (siehe
   showFsControls), bleibt bei Pause immer sichtbar. */
.review-player-main .fs-controls {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 10;
  display: flex; align-items: center; gap: 12px; padding: 16px 18px;
  background: linear-gradient(0deg, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0) 100%);
  opacity: 1; transition: opacity .25s ease; pointer-events: auto;
}
.review-player-main .fs-controls[hidden] { display: none; }
.review-player-main .fs-controls.is-idle { opacity: 0; pointer-events: none; }
.review-player-main .fs-controls .timeline-area { flex: 1; padding: 0; }
.review-player-main .fs-exit-btn {
  flex-shrink: 0; margin-left: auto; border: none; background: rgba(255,255,255,.18); color: #fff;
  width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.review-player-main .fs-exit-btn svg { width: 15px; height: 15px; }
.review-player-main .fs-exit-btn:hover { background: rgba(255,255,255,.32); }
.review-player-main .click-overlay { position: absolute; inset: 0; cursor: pointer; z-index: 3; }
.review-player-main .click-overlay.is-pin-mode { cursor: crosshair; }
.review-player-main .pin-hint {
  position: absolute; left: 50%; top: 14px; transform: translateX(-50%);
  background: var(--primary); color: #fff; font-size: 12.5px; font-weight: 600;
  padding: 7px 14px; border-radius: 999px; z-index: 5; pointer-events: none;
  box-shadow: 0 4px 14px rgba(0,0,0,0.3); white-space: nowrap;
}
.review-player-main .pin-hint[hidden] { display: none; }
.review-player-main .video-pin-dot {
  position: absolute; width: 22px; height: 22px; transform: translate(-50%, -50%);
  border-radius: 50%; background: rgba(0, 163, 174, 0.28); border: 2.5px solid var(--accent);
  z-index: 4; transition: opacity .3s;
}
/* Anders als beim bloßen Blick-Indikator vorher (pointer-events:none) muss
   der Pin jetzt hoverbar sein (Kommentar-Popover, siehe .video-pin-popover
   unten) – fängt Klicks direkt auf dem Pin dadurch selbst ab (kein eigener
   Handler nötig: darunterliegende .click-overlay bekommt diese Klicks dann
   einfach nicht mehr, verhindert so auch versehentliches Doppelsetzen eines
   neuen Pins exakt auf einem bestehenden). */
.review-player-main .video-pin-dot.is-fading { opacity: 0; }
.review-player-main .video-pin-dot[hidden] { display: none; }
.review-player-main .video-pin-dot.is-draggable { cursor: grab; touch-action: none; }
.review-player-main .video-pin-dot.is-dragging { cursor: grabbing; transition: none; }
.review-player-main .video-pin-dot.is-flash { animation: video-pin-flash .6s ease; }
@keyframes video-pin-flash {
  0% { transform: translate(-50%, -50%) scale(1); }
  35% { transform: translate(-50%, -50%) scale(1.7); }
  100% { transform: translate(-50%, -50%) scale(1); }
}

/* Hover-Popover auf dem gesetzten Video-Pin – optisch identisch zu den
   Timeline-Marker-Popovern (gleiche *-card/-head/-avatar/-name/-company/
   -tc/-text-Klassen, siehe buildPopoverCard in review-player.js), aber mit
   eigener Positionierung: der Pin kann überall im Bild sitzen (nicht nur
   auf einer schmalen Leiste), daher standardmäßig über dem Pin, aber nahe
   am oberen Bildrand per .flip-down UNTER dem Pin, damit nichts am
   überflow:hidden Player-Rand abgeschnitten wird. Randklemmung links/rechts
   wie bei den Timeline-Markern über .align-start/-center/-end
   (popoverAlignFor in review-player.js). */
.review-player-main .video-pin-popover {
  position: absolute; bottom: 100%; left: 50%; margin-left: -115px; width: 230px; padding-bottom: 9px;
  opacity: 0; pointer-events: none; transition: opacity .12s ease, transform .12s ease;
  transform: translateY(4px); font-weight: 400;
}
.review-player-main .video-pin-popover.align-start { left: 0; margin-left: 0; }
.review-player-main .video-pin-popover.align-end { left: auto; right: 0; margin-left: 0; }
.review-player-main .video-pin-popover.flip-down {
  bottom: auto; top: 100%; padding-bottom: 0; padding-top: 9px; transform: translateY(-4px);
}
.review-player-main .video-pin-popover.is-visible { opacity: 1; transform: translateY(0); pointer-events: auto; }
.review-player-main .video-pin-popover-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 10px 28px rgba(0,0,0,.22); padding: 10px 12px; text-align: left;
}
.review-player-main .video-pin-popover-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.review-player-main .video-pin-popover-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; background: var(--ink-soft);
  color: #fff; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.review-player-main .video-pin-popover-name { font-size: 0.82rem; font-weight: 600; color: var(--ink); line-height: 1.2; }
.review-player-main .video-pin-popover-company { font-size: 0.72rem; color: var(--ink-soft); }
.review-player-main .video-pin-popover-tc {
  display: inline-block; font-size: 0.72rem; font-weight: 600; color: var(--primary); background: var(--event-lc-bg);
  border-radius: 999px; padding: 1px 8px; margin-bottom: 6px;
}
.review-player-main .video-pin-popover-text { font-size: 13.5px; font-weight: 400; color: var(--ink); line-height: 1.4; white-space: pre-wrap; word-break: break-word; }

.review-player-main .controls-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.review-player-main .play-btn, .review-player-main .pin-mode-btn, .review-player-main .add-comment-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  padding: 7px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.review-player-main .play-btn { padding: 8px; }
.review-player-main .play-btn svg { width: 16px; height: 16px; }
.review-player-main .pin-mode-btn svg, .review-player-main .add-comment-btn svg { width: 15px; height: 15px; }
.review-player-main .pin-mode-btn:hover, .review-player-main .add-comment-btn:hover, .review-player-main .play-btn:hover { border-color: var(--primary); color: var(--primary); }
.review-player-main .pin-mode-btn.is-active { background: var(--primary); color: #fff; border-color: var(--primary); }
.review-player-main .controls-spacer { flex: 1; }

.review-player-main .time-readout { display: flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; font-size: 13px; color: var(--ink-soft); }
.review-player-main .time-current { border: none; background: none; color: var(--ink); font-weight: 600; font-size: 13px; cursor: pointer; padding: 2px 4px; border-radius: 4px; }
.review-player-main .time-current:hover { background: var(--surface-sunken); }
.review-player-main .time-current-input { width: 70px; font-size: 13px; padding: 2px 4px; border: 1px solid var(--line); border-radius: 4px; }
.review-player-main .time-current-input[hidden], .review-player-main .time-current[hidden] { display: none; }

.review-player-main .volume-control { display: flex; align-items: center; gap: 6px; }
.review-player-main .volume-btn { border: none; background: none; color: var(--ink-soft); display: flex; cursor: pointer; }
.review-player-main .volume-btn svg { width: 17px; height: 17px; }
.review-player-main .volume-slider { width: 115px; transition: opacity .15s; }
.review-player-main .volume-slider.is-muted { opacity: 0.35; }

.review-player-main .quality-select {
  font-family: inherit; font-size: 12.5px; font-weight: 600; color: var(--ink);
  padding: 6px 28px 6px 12px; border: 1px solid var(--line); border-radius: 999px;
  background-color: var(--surface); cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235b6b7c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6,9 12,15 18,9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 13px;
}
.review-player-main .quality-select[hidden] { display: none; }
.review-player-main .quality-select:disabled { opacity: 0.5; cursor: not-allowed; }

.review-player-main .timeline-area { padding: 14px 4px 0; position: relative; }
/* Scrub-Vorschau beim Hover über die Timeline [TEST/POC] – siehe
   review-player.js und video-thumbs.js. Bewusst UNSCOPED (nicht unter
   .review-player-main) und an document.body statt an .timeline-area
   gehängt: läuft mit position:fixed + echten Viewport-Koordinaten, damit
   sie frei über den (overflow:hidden) Spielerrand hinausragen darf statt
   an den Seiten abgeschnitten zu werden. */
.scrub-preview {
  position: fixed; transform: translate(-50%, calc(-100% - 8px));
  z-index: 1000; pointer-events: none; display: flex; flex-direction: column; align-items: center; gap: 4px;
}
.scrub-preview[hidden] { display: none; }
.scrub-preview-img {
  background-repeat: no-repeat; border-radius: var(--radius); border: 2px solid var(--surface);
  box-shadow: 0 6px 18px rgba(0,0,0,.3); background-color: #000;
}
.scrub-preview-time {
  font-size: 11px; font-weight: 700; color: #fff; background: rgba(0,0,0,.75);
  padding: 2px 7px; border-radius: 999px; font-variant-numeric: tabular-nums;
}
.review-player-main .timeline { position: relative; height: 24px; cursor: pointer; }
.review-player-main .timeline-track { position: absolute; left: 10px; right: 10px; top: 50%; height: 4px; transform: translateY(-50%); background: var(--surface-sunken); border-radius: 999px; }
.review-player-main .timeline-progress { position: absolute; left: 10px; top: 50%; height: 4px; transform: translateY(-50%); background: var(--primary); border-radius: 999px; }
.review-player-main .timeline-playhead { position: absolute; top: 50%; width: 13px; height: 13px; transform: translate(-50%, -50%); background: var(--primary); border-radius: 50%; box-shadow: 0 0 0 3px var(--surface); }
.review-player-main .timeline.is-dragging .timeline-playhead { width: 16px; height: 16px; }

/* --- Kommentar-Punkte über der Timeline (nicht mehr direkt auf der Leiste) ---
   Eigene Zeile oberhalb von .timeline, gleicher Innenabstand (10px) wie
   .timeline-track, damit die Prozent-Positionen exakt übereinstimmen. */
.review-player-main .timeline-markers { position: relative; height: 22px; margin: 0 10px 8px; z-index: 6; }
/* z-index auf der Gruppe (nicht nur auf dem Popover drinnen) ist nötig, weil
   "transform" hier einen EIGENEN Stacking-Context öffnet: der interne
   z-index:30 des Popovers gilt dann nur INNERHALB dieser Gruppe und "entkommt"
   nicht nach außen. Ohne eigenes z-index hier zählt die Gruppe von außen als
   z-index:auto und landet dadurch HINTER .click-overlay (z-index:3) im Video,
   sobald das Popover nach oben über das Video aufklappt – die Maus trifft dann
   dort den Click-Overlay statt den Popover und das Hovern bricht ab. */
.review-player-main .timeline-marker-group {
  position: absolute; top: 50%; left: 0; transform: translate(-50%, -50%);
  transition: transform .25s ease; z-index: 1;
}
.review-player-main .timeline-marker-group.is-expanded { z-index: 2; }
.review-player-main .timeline-marker {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--surface);
  background: var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,.25); cursor: pointer;
  color: #fff; font-size: 9px; font-weight: 700; flex-shrink: 0; padding: 0;
}
.review-player-main .timeline-marker.is-resolved { opacity: 0.4; }
.review-player-main .timeline-marker-cluster { width: 19px; height: 19px; font-size: 10px; transition: opacity .15s, transform .15s; }

/* Aufgefächerte Einzel-Punkte eines Clusters – unsichtbar/nicht klickbar,
   bis der Cluster-Punkt gehovert/getippt wird (.is-expanded). Die X-Position
   (left) wird per JS gesetzt (renderMarkers/fanStartFor): so mittig wie
   möglich über der Cluster-Position, aber an den Timeline-Rand geklemmt statt
   starr nur in eine Richtung zu klappen – nutzt so auch den Platz, der z. B.
   links von einem Cluster ganz am Anfang der Timeline noch frei ist. */
.review-player-main .timeline-marker-fan {
  position: absolute; top: 50%; transform: translateY(-50%); display: flex; align-items: center; gap: 5px;
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
}
.review-player-main .timeline-marker-group.is-expanded .timeline-marker-fan { opacity: 1; pointer-events: auto; }
.review-player-main .timeline-marker-group.is-expanded .timeline-marker-cluster { opacity: 0; transform: scale(.5); pointer-events: none; }

/* Hover-Popover mit Kommentarinhalt statt nur dem nativen Browser-Tooltip.
   X-Position läuft über left/right (nicht über transform), weil die
   Ausrichtung je nach Timeline-Rand variiert (align-center/-start/-end,
   siehe popoverAlignFor in review-player.js) – nur die Y-Achse (Einblenden
   von unten) nutzt transform, kollidiert dadurch nicht mit der X-Variante.
   padding-bottom überbrückt den sichtbaren Abstand zum Punkt als Teil der
   eigenen Hoverfläche, damit die Maus beim Hochfahren nicht durch eine
   "tote Zone" muss und der Popover dabei nicht zuklappt (siehe :hover unten,
   greift sowohl bei :hover auf .timeline-marker als auch auf den Popover
   selbst, sobald die Maus direkt über ihm ist – z. B. zum Text kopieren).
   z-index muss über dem Player-Wrap (inkl. Vimeo-iframe) liegen, siehe
   .review-player-main .player-wrap weiter oben in dieser Datei. */
.review-player-main .timeline-marker-popover {
  position: absolute; bottom: 100%; width: 230px; padding-bottom: 9px;
  opacity: 0; pointer-events: none; transition: opacity .12s ease, transform .12s ease;
  transform: translateY(4px); z-index: 30; font-weight: 400;
}
.review-player-main .timeline-marker-popover.align-center { left: 50%; margin-left: -115px; }
.review-player-main .timeline-marker-popover.align-start { left: 0; }
.review-player-main .timeline-marker-popover.align-end { right: 0; }
.review-player-main .timeline-marker-popover.is-visible,
.review-player-main .timeline-marker:focus-visible .timeline-marker-popover {
  opacity: 1; transform: translateY(0); pointer-events: auto;
}
.review-player-main .timeline-marker-popover-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 10px 28px rgba(0,0,0,.22); padding: 10px 12px; text-align: left;
}
.review-player-main .timeline-marker-popover-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.review-player-main .timeline-marker-popover-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; background: var(--ink-soft);
  color: #fff; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.review-player-main .timeline-marker-popover-name { font-size: 0.82rem; font-weight: 600; color: var(--ink); line-height: 1.2; }
.review-player-main .timeline-marker-popover-company { font-size: 0.72rem; color: var(--ink-soft); }
.review-player-main .timeline-marker-popover-tc {
  display: inline-block; font-size: 0.72rem; font-weight: 600; color: var(--primary); background: var(--event-lc-bg);
  border-radius: 999px; padding: 1px 8px; margin-bottom: 6px;
}
.review-player-main .timeline-marker-popover-text { font-size: 13.5px; font-weight: 400; color: var(--ink); line-height: 1.4; white-space: pre-wrap; word-break: break-word; }

.review-player-main .composer { margin-top: 14px; border: 1px solid var(--line); border-radius: var(--radius); padding: 12px; background: var(--surface-sunken); }
.review-player-main .composer[hidden] { display: none; }
.review-player-main .composer-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.review-player-main .composer-badge { font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 700; color: var(--primary); background: #dce9f6; padding: 2px 8px; border-radius: 999px; }
.review-player-main .composer-pin-badge { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; color: var(--accent); }
.review-player-main .composer-pin-badge svg { width: 13px; height: 13px; }
.review-player-main .composer-pin-badge[hidden] { display: none; }
.review-player-main textarea#rp-composer-text { width: 100%; min-height: 70px; font-family: inherit; font-size: 13.5px; padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--radius); resize: vertical; }
.review-player-main .composer-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.review-player-main .btn-sm { border: 1px solid var(--line); background: var(--surface); color: var(--ink); padding: 7px 13px; border-radius: var(--radius); font-size: 13px; font-weight: 600; cursor: pointer; }
.review-player-main .btn-sm.primary { background: var(--primary); color: #fff; border-color: var(--primary); }
.review-player-main .btn-sm.primary:hover { background: var(--primary-dark); }
.review-player-main .btn-sm:not(.primary):hover { background: var(--surface-sunken); }

.review-player-sidebar .sidebar-head { padding: 16px 20px; border-bottom: 1px solid var(--line); flex-shrink: 0; }
.review-player-sidebar .sidebar-head h2 { font-size: 16px; margin: 0; }
.review-player-sidebar .stats-line { font-size: 12.5px; color: var(--ink-soft); margin-top: 4px; }
.review-player-sidebar .filter-tabs-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 12px; }
.review-player-sidebar .filter-tabs { display: flex; gap: 4px; background: var(--surface-sunken); padding: 3px; border-radius: 999px; width: fit-content; }
.review-player-sidebar .filter-tab { border: none; background: none; padding: 5px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); cursor: pointer; }
.review-player-sidebar .filter-tab.is-active { background: var(--surface); color: var(--primary); box-shadow: 0 1px 3px rgba(0,0,0,0.12); }
/* Icon-only, bewusst klein/unauffällig – nur für Green Forest sichtbar
   (siehe review-player.js: exportBtn.hidden = !data.canExport). */
.review-player-sidebar .export-icon-btn {
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink-soft);
}
.review-player-sidebar .export-icon-btn svg { width: 13px; height: 13px; }
.review-player-sidebar .export-icon-btn:hover { border-color: var(--primary); color: var(--primary); }
.review-player-sidebar .export-icon-btn[hidden] { display: none; }

.review-player-sidebar .comment-list { list-style: none; margin: 0; padding: 10px; display: flex; flex-direction: column; gap: 8px; overflow-y: auto; flex: 1; min-height: 0; }
.review-player-sidebar .comment-empty { padding: 30px 14px; text-align: center; color: var(--ink-soft); font-size: 13.5px; }
.review-player-sidebar .comment-item { border: 1px solid var(--line); border-left-width: 4px; border-radius: var(--radius); padding: 11px 12px; cursor: pointer; transition: border-color .12s, background .12s; }
.review-player-sidebar .comment-item:hover { border-color: var(--primary); }
.review-player-sidebar .comment-item.is-active { border-color: var(--primary); background: #f3f8fd; }
.review-player-sidebar .comment-item.is-resolved { opacity: 0.6; }
/* Gleicher Aufbau wie die Hover-Popover auf der Timeline (siehe
   .timeline-marker-popover-* in dieser Datei): Avatar + Name/Firma oben,
   Timecode als blaue Pille darunter, dann der Kommentartext. Die Randfarbe
   nach Autor bleibt (li.style.borderLeftColor, siehe review-player.js). */
.review-player-sidebar .comment-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.review-player-sidebar .comment-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.review-player-sidebar .comment-avatar {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0; background: var(--ink-soft);
  color: #fff; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.review-player-sidebar .comment-name { font-size: 0.82rem; font-weight: 600; color: var(--ink); line-height: 1.2; }
.review-player-sidebar .comment-company { font-size: 0.72rem; color: var(--ink-soft); }
.review-player-sidebar .comment-meta { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.review-player-sidebar .comment-time { font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 700; color: var(--primary); background: #dce9f6; padding: 2px 8px; border-radius: 999px; }
.review-player-sidebar .comment-item.is-resolved .comment-time { color: var(--success); background: var(--event-release-bg); }
.review-player-sidebar .comment-pin-tag { display: flex; align-items: center; color: var(--accent); }
.review-player-sidebar .comment-pin-tag svg { width: 13px; height: 13px; }
.review-player-sidebar .comment-datetime { font-size: 11px; color: var(--ink-soft); }
.review-player-sidebar .comment-controls { display: flex; gap: 4px; flex-shrink: 0; }
.review-player-sidebar .icon-btn { border: none; background: none; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; border-radius: 6px; color: var(--ink-soft); cursor: pointer; }
.review-player-sidebar .icon-btn:hover { background: var(--surface-sunken); color: var(--ink); }
.review-player-sidebar .icon-btn svg { width: 14px; height: 14px; }
.review-player-sidebar .comment-text { font-size: 13.5px; font-weight: 400; color: var(--ink); white-space: pre-wrap; word-break: break-word; }

/* Antworten sehen optisch wie der Kommentar selbst aus (gleicher Kopf aus
   buildCommentHead, gleiche .comment-text-Klasse) – nur leicht eingerückt
   und mit eigener (statt der Eltern-)Randfarbe nach Antwort-Schreiber, siehe
   review-player.js. */
.review-player-sidebar .comment-replies { margin-top: 8px; padding-top: 0; border-top: none; display: flex; flex-direction: column; gap: 8px; margin-left: 20px; }
.review-player-sidebar .reply-item {
  border: 1px solid var(--line); border-left-width: 4px; border-radius: var(--radius);
  padding: 9px 11px; background: var(--surface);
}
.review-player-sidebar .reply-add-btn { margin-top: 6px; border: none; background: none; color: var(--primary); font-size: 12px; font-weight: 600; padding: 2px 0; cursor: pointer; }
.review-player-sidebar .reply-add-btn:hover { text-decoration: underline; }
.review-player-sidebar .reply-form { margin-top: 6px; display: flex; gap: 6px; }
.review-player-sidebar .reply-form input { flex: 1; font-family: inherit; font-size: 12.5px; padding: 6px 9px; border: 1px solid var(--line); border-radius: 6px; }
.review-player-sidebar .reply-form button { border: none; background: var(--primary); color: #fff; font-size: 12px; font-weight: 600; padding: 6px 11px; border-radius: 6px; cursor: pointer; }

body.is-timeline-dragging { user-select: none; }
