/* ==========================================================
   FONT — Futura PT ist kostenpflichtig und daher hier nicht
   eingebunden. Sobald du deine lizenzierten Dateien hast,
   trag sie hier ein, z. B.:

   @font-face {
     font-family: 'Futura PT';
     src: url('fonts/FuturaPT-Book.woff2') format('woff2');
     font-weight: 400;
   }
   @font-face {
     font-family: 'Futura PT';
     src: url('fonts/FuturaPT-Medium.woff2') format('woff2');
     font-weight: 500;
   }

   Bis dahin greift ein geometrischer Sans-Fallback, der der
   Optik von Futura sehr nahekommt.
   ========================================================== */

:root {
  --bg: #1a1817;
  --bg-header: #1a1817;
  --bg-modal: #211d1b;
  --text: #f2efec;
  --text-muted: #b6afa9;
  --line: rgba(255, 255, 255, 0.12);
  --line-width: 1px;
  --curtain-filter: none;
  --placeholder-bg: #2a2624;
  /* Text auf fest dunklen, halbtransparenten Pillen/Overlays (schweben
     immer über Fotos, nicht über der Seite selbst — z.B. Jahres-Badge,
     "Mehr erfahren", Kino-Lichtschalter, "Film ansehen"). Bewusst NICHT
     in :root[data-theme="light"] überschrieben: der Hintergrund dieser
     Pillen bleibt in beiden Themes dunkel, darum muss ihr Text immer hell
     bleiben, unabhängig vom Seiten-Theme (siehe var(--text) unten, das
     im hellen Modus sonst fälschlich dunkel würde). */
  --overlay-text: #f2efec;
  --overlay-text-muted: #b6afa9;
  --font-display: 'Futura PT', 'Century Gothic', 'Avenir Next', 'Segoe UI', sans-serif;
  --font-body: 'Futura PT', 'Century Gothic', 'Avenir Next', 'Segoe UI', sans-serif;
  --gutter: clamp(1.5rem, 4vw, 4rem);
  --curtain: #7a1e1a;
  --curtain-dark: #3d0f0c;
}

/* Temporärer, nur für dich sichtbarer Vorschau-Umschalter (Footer-Button,
   siehe script.js) — kein offizielles zweites Theme der Seite, nur zum
   Ausprobieren, ob eine helle Variante überhaupt gefallen würde. Linien
   werden bewusst sehr dunkel UND deutlich dicker (nicht nur invertiert),
   damit die Struktur der Seite auf Weiß genauso klar erkennbar bleibt wie
   die feinen hellen Linien auf Dunkel es sind. */
:root[data-theme="light"] {
  --bg: #ffffff;
  --bg-header: #ffffff;
  --bg-modal: #ffffff;
  --text: #111111;
  --text-muted: #4a4540;
  --line: #111111;
  --line-width: 2px;
  --placeholder-bg: #e3e0db;
  --curtain: #1e3a7a;
  --curtain-dark: #0c1c3d;
  --curtain-filter: hue-rotate(210deg) saturate(1.15);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.01em;
  margin: 0 0 0.6em;
}

h1 { font-size: clamp(1.6rem, 3vw, 2.1rem); }
h2 { font-size: clamp(1.4rem, 2.4vw, 1.8rem); }

p { margin: 0 0 1em; color: var(--text-muted); font-size: 0.95rem; overflow-wrap: break-word; }

/* Letzter Absatz in einer Grid-Spalte (Intro-/Synopse-Spalten) braucht
   keinen eigenen Abstand nach unten — der kommt schon vom Grid-`gap`
   selbst (zwischen Spalten nebeneinander UND, im gestapelten Ein-Spalten-
   Zustand unter 900px, auch zwischen den Spalten untereinander). Ohne
   das addieren sich beide und der Abstand wirkt doppelt so groß wie bei
   Absätzen innerhalb derselben Spalte. */
.intro__columns > div > p:last-child,
.modal__text-columns > div > p:last-child {
  margin-bottom: 0;
}

/* Klickbarer Filmname mitten im Fließtext einer Eventbeschreibung (siehe
   linkifyFilmName in script.js) — liest sich wie ein normaler Link im
   Text, keine Button-Optik. */
.inline-film-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.inline-film-link:hover,
.inline-film-link:focus-visible {
  color: var(--accent, var(--text));
}

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

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg-header);
  padding: 1.4rem var(--gutter) 1rem;
}

.logo {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.3rem;
  margin-bottom: 1.1rem;
}

.main-nav {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}

.main-nav a {
  color: var(--text);
  font-size: 0.95rem;
  padding-bottom: 0.15rem;
  border-bottom: 1px solid transparent;
  transition: border-color 0.15s ease;
}

.main-nav a:hover,
.main-nav a:focus-visible {
  border-color: var(--text);
}

/* Kompakte Nav unter 560px (Haus-Symbol, aufklappbares "Projekte", Über
   mich) — Aufbau + Sichtbarkeits-Umschaltung siehe Media Query weiter
   unten. Standardmäßig (ab 560px) unsichtbar. */
.main-nav--mobile {
  display: none;
  align-items: center;
  gap: 1.4rem;
}

.main-nav__icon {
  display: flex;
  color: var(--text);
}

.main-nav__projects-toggle {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text);
  cursor: pointer;
}

.main-nav__projects-toggle::after {
  content: "▾";
  font-size: 0.7em;
  color: var(--text-muted);
  transition: transform 0.2s ease;
}

.main-nav__projects-toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}

.main-nav__projects {
  display: none;
  flex-direction: column;
  gap: 0.9rem;
  margin-top: 1rem;
}

/* ---------- Sections ---------- */

.section {
  padding: 3rem var(--gutter);
  border-top: var(--line-width) solid var(--line);
  /* Der Header ist sticky (position:sticky) — ohne das hier würde er
     die Überschrift beim Anker-Sprung von der Navigation überdecken. */
  scroll-margin-top: 6.5rem;
}

.section--flush { padding-top: 0; border-top: none; }

.section__heading-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.section__heading-row h2 { margin-bottom: 0; }

/* Kurzer erklärender Satz direkt unter der Kapitelüberschrift (Filme/
   Mitwirkungen/Events) — was diesen Bereich von den anderen beiden
   unterscheidet, zusätzlich zur allgemeineren Home-Intro oben. */
.section__lead {
  color: var(--text-muted);
  font-size: 0.95rem;
  margin: 0.4rem 0 1.6rem;
}

.view-toggle {
  display: flex;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0.3rem;
  border-radius: 4px;
  transition: color 0.15s ease, background 0.15s ease;
}

.view-toggle:hover,
.view-toggle:focus-visible {
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
}

/* ---------- Hero images ---------- */

.hero {
  width: 100%;
  height: clamp(220px, 32vw, 420px);
  overflow: hidden;
  background: #000;
  transition: height 0.4s ease;
}

.modal__hero {
  width: 100%;
  height: clamp(200px, 30vw, 380px);
  overflow: hidden;
  background: #000;
  transition: height 0.4s ease;
}

/* Die tatsächliche Höhe im aufgeklappten Zustand setzt JS inline (16:9
   relativ zur aktuellen Bannerbreite, siehe Carousel.prototype.setExpanded
   in script.js) — so bleibt object-fit durchgehend "cover" (Foto bleibt
   zentriert, kein Umschalten auf "contain"/kein Umskalieren), nur die
   Höhe wächst, wie ein Aufscrollen. */

/* ---------- Carousel (Banner mit mehreren Bildern) ---------- */

.carousel {
  position: relative;
  outline: none;
  cursor: ns-resize;
}

.carousel__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s ease;
  pointer-events: none;
}

.carousel__slide.is-active {
  opacity: 1;
  pointer-events: auto;
}

.carousel__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 2.4rem;
  height: 2.4rem;
  border: none;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.15s ease, background 0.15s ease;
}

.carousel__arrow:hover,
.carousel__arrow:focus-visible {
  opacity: 1;
  background: rgba(0, 0, 0, 0.55);
}

.carousel__arrow--prev { left: 1rem; }
.carousel__arrow--next { right: 1rem; }

.carousel__empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 0.85rem;
  border: var(--line-width) dashed var(--line);
  text-align: center;
  padding: 1rem;
}

.carousel__caption {
  /* Gleicher Abstand nach unten (zur Trennlinie von .modal__section
     darunter) wie nach oben (zum Bildbanner) — vorher stand die Caption
     ohne Luft direkt auf dieser Linie. */
  margin: 0.6rem 0;
  color: var(--text-muted);
  font-size: 0.85rem;
  font-style: italic;
  min-height: 1.3em;
}

.carousel__caption--modal {
  padding: 0 var(--gutter);
}

/* ---------- About: Profilfoto + Bio nebeneinander ---------- */

.about-layout {
  display: grid;
  grid-template-columns: minmax(160px, 240px) 1fr;
  gap: 2rem;
  align-items: start;
}

.profile-photo {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: contain;
  background: transparent;
}

/* Ohne Deckel würde der Bio-Text auf breiten Screens über die ganze
   1fr-Spalte laufen und damit unlesbar lange Zeilen bekommen — 60ch ist
   auf schmalen Screens ohnehin nie das Limit, greift also nur dort, wo
   es nötig ist. */
.about-text {
  max-width: 60ch;
}

/* ---------- About: Kontakt + Downloads ---------- */

.about-meta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
  margin-top: 2.5rem;
}

.about-cv {
  margin-top: 2.5rem;
}

.site-footer {
  padding: 2rem var(--gutter) 3rem;
  border-top: var(--line-width) solid var(--line);
  text-align: center;
}

.site-footer a,
.site-footer button {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: pointer;
}

.site-footer a:hover,
.site-footer a:focus-visible,
.site-footer button:hover,
.site-footer button:focus-visible {
  color: var(--text);
}

.site-footer__sep {
  color: var(--text-muted);
  font-size: 0.85rem;
  margin: 0 0.6rem;
}

.download-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  margin-top: 1.2rem;
}

.download-link {
  display: inline-flex;
  align-items: center;
  padding: 0.6rem 1.1rem;
  border: var(--line-width) solid var(--line);
  border-radius: 999px;
  color: var(--text);
  font-size: 0.9rem;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.download-link:hover,
.download-link:focus-visible {
  border-color: var(--text);
  background: rgba(255, 255, 255, 0.04);
}

.download-link--pending {
  color: var(--text-muted);
  border-style: dashed;
}

/* ---------- Intro / Traumgestaltung / About ---------- */

.intro {
  padding: 2.5rem var(--gutter) 1rem;
}

.intro__lead {
  color: var(--text);
  margin-bottom: 1.6rem;
}

.intro__columns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
}

/* ---------- Filme grid ---------- */

/* auto-fit statt einer festen Spaltenzahl + Breakpoints: Kacheln
   schrumpfen/wachsen ab 150px, springen darunter automatisch in eine neue
   Spalte/Zeile — dadurch kann das Grid bei Zwischenbreiten nie über den
   Fensterrand hinausragen (siehe auch min-width:0 bei .film-card unten,
   ohne das ein Poster mit großer Originalbreite die Spalte am Schrumpfen
   hindern würde). Obergrenze bewusst 1fr statt einer festen Pixelbreite:
   so wachsen die Kacheln in der letzten Reihe immer bis zum rechten Rand
   mit, statt bei bestimmten Fensterbreiten eine leere Fläche rechts offen
   zu lassen. */
.film-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1.2rem;
  margin-top: 1.6rem;
}

.film-grid[hidden] { display: none; }

.film-card {
  position: relative;
  min-width: 0;
  aspect-ratio: 2 / 3;
  padding: 0;
  border: none;
  background: var(--placeholder-bg);
  cursor: pointer;
  overflow: visible;
  border-radius: 2px;
  z-index: 1;
}

.film-card:hover,
.film-card:focus-within {
  z-index: 5;
}

.film-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 2px;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.film-card:hover img,
.film-card:focus-visible img {
  transform: scale(1.15);
  box-shadow: 0 14px 34px rgba(0, 0, 0, 0.55);
}

.film-card__year {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 2;
  background: rgba(0, 0, 0, 0.55);
  color: var(--overlay-text);
  font-size: 0.75rem;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  pointer-events: none;
}

/* Signalisiert, dass ein Klick aufs Plakat mehr Infos öffnet — blendet
   wie der carousel__watch-toggle als dunkle Pille ein, bei Hover/Fokus,
   damit die Klickbarkeit über den reinen Zoom-Effekt hinaus klar wird. */
.film-card__hint {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 3;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.7);
  color: var(--overlay-text);
  font-size: 0.8rem;
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
  white-space: nowrap;
}

.film-card:hover .film-card__hint,
.film-card:focus-visible .film-card__hint {
  opacity: 1;
}

.film-card--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 0.85rem;
  cursor: default;
}

.film-card--empty:hover img { transform: none; }

/* ---------- Events: Kachel-Grid (Alternative zur Standard-Liste) ---------- */
/* Standardansicht ist die reine Liste (.table--events, wie Mitwirkungen/
   Filme) — dieses Kachel-Grid mit großem Erstfoto je Event ist die per
   Button umschaltbare Alternative, analog zu Filme-Grid/-Tabelle. */

.event-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.8rem 1.2rem;
  margin-top: 1.6rem;
}

.event-grid[hidden] { display: none; }

.event-card {
  display: block;
  min-width: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.event-card__thumb {
  aspect-ratio: 16 / 10;
  border-radius: 2px;
  overflow: hidden;
  background: var(--placeholder-bg);
}

.event-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.25s ease;
}

.event-card:hover .event-card__thumb img,
.event-card:focus-visible .event-card__thumb img {
  transform: scale(1.08);
}

.event-card__thumb--tba {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 0.8rem;
}

.event-card__title {
  display: block;
  margin-top: 0.7rem;
  color: var(--text);
  font-size: 0.95rem;
}

.event-card__meta {
  display: block;
  margin-top: 0.2rem;
  color: var(--text-muted);
  font-size: 0.8rem;
}

/* ---------- Tables (Mitwirkungen / Events) ---------- */

.table {
  margin-top: 1.6rem;
  display: flex;
  flex-direction: column;
}

/* Ohne das hier gewinnt "display: flex" oben gegen das native [hidden]
   (Autoren-CSS schlägt UA-Stylesheet immer, unabhängig von Spezifität) —
   gleiches Muster wie bei .light-toggle[hidden] / .modal__chevron[hidden]. */
.table[hidden] { display: none; }

.table__row {
  display: grid;
  gap: 0.6rem;
  padding: 0.9rem 0;
  border-bottom: var(--line-width) solid var(--line);
  align-items: baseline;
}

/* Grid-Zellen schrumpfen ohne min-width:0 nicht unter ihre Inhaltsbreite
   (Standard-Automatikminimum ist die längste Zeile, nicht das längste
   Wort) — ohne das hier würde z.B. "Camera-Assistence / Lichtgestaltung"
   die Rolle-Spalte in einer Zeile erzwingen und die ganze Tabelle über
   die Fensterbreite hinaus schieben, statt in der Spalte umzubrechen. */
.table__row > span {
  min-width: 0;
}

.table--mitwirkungen .table__row {
  grid-template-columns: 3rem 8rem 6rem 8rem 1fr;
}

.table--filme .table__row {
  grid-template-columns: 3rem 14rem 1fr;
}

.table--events .table__row {
  grid-template-columns: 3rem 10rem 1fr 8rem;
}

/* Letzte Spalte pro Tabelle rechtsbündig, damit die Zeile links (Jahr)
   und rechts (letzte Spalte) sauber an den Rändern anliegt — betrifft
   auch die Kopfzeile, da sie dieselben Klassen/Spalten teilt. Bewusst
   auf die jeweilige Tabelle gescoped: .table__type ist in Mitwirkungen
   die dritte Spalte (Format), in Events und Filme aber die letzte
   (Typ/Genre). */
.table--mitwirkungen .table__role {
  text-align: right;
}

.table--events .table__type,
.table--filme .table__type {
  text-align: right;
}

.table__row--clickable {
  cursor: pointer;
}

.table__row--clickable:hover,
.table__row--clickable:focus-visible {
  background: rgba(255, 255, 255, 0.04);
}

.event-modal__meta {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin: 0 0 1.4rem;
}

/* Event-Modals haben bewusst kein Foto-Hero-Banner wie die Filme (siehe
   #modal-event in index.html) — stattdessen eine einfache Bildergalerie
   unter dem Text, sofern Fotos vorhanden sind (siehe openEventDetail in
   script.js). Klick auf ein Bild öffnet es in der vorhandenen
   Poster-Lightbox groß. */
.event-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.8rem;
  margin-top: 1.8rem;
}

.event-gallery[hidden] { display: none; }

.event-gallery img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 2px;
  cursor: pointer;
  transition: opacity 0.15s ease;
}

.event-gallery img:hover,
.event-gallery img:focus-visible {
  opacity: 0.85;
}

.table__title { color: var(--text); font-weight: 500; }
.table__year, .table__type, .table__name, .table__role, .table__location {
  color: var(--text-muted);
  font-size: 0.92rem;
}

/* Kopfzeile: statisches Markup in index.html (nicht Teil von renderTable,
   sonst würde sie beim Rendern der Datenzeilen mit gelöscht) — macht
   klar, dass "Regie" immer die andere Person ist und "Meine Rolle"
   (Niko) am Ende der Zeile steht. */
.table__row--header {
  padding-top: 0;
  padding-bottom: 0.6rem;
}

.table__row--header span {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-muted);
  font-weight: 400;
}

/* ---------- Modal / Film-Detail-Overlay ---------- */

.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--bg-modal);
  display: none;
  flex-direction: column;
  overflow: hidden;
}

.modal.is-open { display: flex; }

/* Kino-Modus: alles außer dem Banner selbst (Plakat, Beschreibung,
   Credits …) dunkelt ab, solange das Video läuft. Der "Fotos ansehen"-
   Knopf bleibt ausgenommen — er schwebt zwar als Overlay knapp unter dem
   Banner (siehe .carousel__watch-toggles, Position per JS), muss aber
   immer klickbar bleiben, um aus dem Video-Modus wieder herauszukommen. */
.modal.is-cinema-mode .modal__scroll > *:not(.modal__hero):not(.carousel__watch-toggles) {
  opacity: 0.1;
  transition: opacity 2s ease;
  pointer-events: none;
}

/* Lichtschalter: schwebt unten rechts über dem ganzen Modal (Kind von
   .modal, nicht von .modal__scroll — bleibt also von der Abdunkelung
   oben unberührt und unabhängig von der Scroll-Position sichtbar).
   Nur während ein Video läuft eingeblendet (siehe script.js). */
.light-toggle {
  position: absolute;
  bottom: 1.4rem;
  right: var(--gutter);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: rgba(0, 0, 0, 0.55);
  color: var(--overlay-text-muted);
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  font-size: 0.8rem;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.light-toggle[hidden] { display: none; }

.light-toggle:hover,
.light-toggle:focus-visible {
  background: rgba(0, 0, 0, 0.8);
}

.light-toggle__icon {
  width: 1.1rem;
  height: 1.1rem;
  flex: 0 0 auto;
  transition: filter 0.15s ease, opacity 0.15s ease;
}

.light-toggle[data-light-mode="on"] {
  color: var(--overlay-text);
}

.light-toggle[data-light-mode="on"] .light-toggle__icon {
  filter: drop-shadow(0 0 4px var(--overlay-text));
}

.modal__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.4rem var(--gutter);
  border-bottom: var(--line-width) solid var(--line);
  flex: 0 0 auto;
}

.modal__bar h2 { margin: 0; font-weight: 700; }

.modal__close {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
}

.modal__close:hover,
.modal__close:focus-visible { color: var(--text); }

/* Vorheriger/Nächster Film: fest am unteren Rand jedes Film-Modals (dritte
   Flex-Zeile neben .modal__bar oben und .modal__scroll dazwischen), nicht
   Teil des scrollbaren Inhalts. Wechselt zyklisch durch FILM_SLUGS, siehe
   slideToFilm in script.js. */
.modal__footer-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem var(--gutter);
  border-top: var(--line-width) solid var(--line);
  flex: 0 0 auto;
}

.modal__nav-btn {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  max-width: 45%;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0.3rem 0.4rem;
  transition: color 0.15s ease;
}

.modal__nav-btn--next { margin-left: auto; flex-direction: row-reverse; }

.modal__nav-btn:hover,
.modal__nav-btn:focus-visible { color: var(--text); }

.modal__nav-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.modal__scroll {
  position: relative; /* Bezugsrahmen für den frei schwebenden .carousel__watch-toggle */
  overflow-y: auto;
  flex: 1 1 auto;
}

.modal__section {
  padding: 2.2rem var(--gutter);
  position: relative;
  border-top: var(--line-width) solid var(--line);
}

.eyebrow {
  font-size: 1.05rem;
  margin-bottom: 1.2rem;
}

.film-meta {
  color: var(--text-muted);
  font-size: 0.85rem;
  margin: -0.6rem 0 1.2rem;
}

.modal__description {
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 2rem;
  /* Ohne das würden Plakat und Text sich per Grid-Default gegenseitig auf
     die Höhe des jeweils längeren strecken — bei aufgeklapptem, kürzerem
     Text bliebe dann unten Leerraum, bevor der "Weniger anzeigen"-Pfeil
     kommt. So behält jede Spalte ihre eigene, natürliche Höhe. */
  align-items: start;
  transition: opacity 0.6s ease, transform 0.6s ease;
}

/* Läuft ein Video (siehe .modal.is-cinema-mode), fährt Plakat + Synopse
   zusätzlich zum allgemeinen Abdunkeln (siehe weiter unten) sichtbar nach
   oben unter den Banner und blendet dabei aus — schneller als das
   generische Abdunkeln der restlichen Sektion, damit es wie ein
   eigenständiges Verschwinden wirkt, nicht nur ein Mitdimmen. */
.modal.is-cinema-mode .modal__description {
  opacity: 0;
  transform: translateY(-2rem);
}

.modal__poster img {
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: 2px;
  cursor: zoom-in;
}

.poster-credit {
  margin: 0.5rem 0 0;
  color: var(--text-muted);
  font-size: 0.75rem;
}

/* ---------- Poster-Vollbild (Lightbox) ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(0, 0, 0, 0.9);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 2rem;
}

.lightbox.is-open { display: flex; }

.lightbox__image {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: 2px;
  cursor: pointer;
  touch-action: none; /* eigene Wisch-Geste zum Schließen statt Browser-Scroll/Zoom */
}

.lightbox__close {
  position: absolute;
  top: 1.4rem;
  right: var(--gutter);
  background: none;
  border: none;
  color: var(--text);
  font-size: 1.8rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
}

.lightbox__close:hover,
.lightbox__close:focus-visible { color: var(--text-muted); }

.modal__text-columns {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem;
  position: relative;
}

/* Ohne min-width:0 kann ein einzelnes langes, unteilbares Wort (z.B. ein
   zusammengesetzter Fachbegriff ohne Trennstelle) die Spalte über ihre
   1fr-Breite hinaus aufblähen, statt in der Spalte umzubrechen — gleiches
   Prinzip wie bei den Tabellen weiter oben. */
.modal__text-columns > div {
  min-width: 0;
  /* JS setzt --collapsed-height auf die tatsächliche Plakat-Höhe, sobald
     das Modal offen ist (siehe refreshSynopsisOverflow in script.js) */
  max-height: var(--collapsed-height, 9rem);
  overflow: hidden;
  transition: max-height 0.4s ease;
}

/* Kürzerer Text mit weniger Absätzen als Spalten (renderColumns lässt
   leere Spalten weg, siehe script.js) — die einzige verbliebene Spalte
   nutzt dann die volle Breite, statt nur die halbe Grid-Spur. */
.modal__text-columns > div:only-child {
  grid-column: 1 / -1;
}

.modal__text-columns.is-expanded {
  max-height: 2000px;
}

.modal__text-columns:not(.is-expanded)::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.5rem;
  background: linear-gradient(to bottom, transparent, var(--bg-modal));
  pointer-events: none;
}

/* ---------- Video-Vorhang im Foto-Banner ---------- */
/* Ein "Film ansehen"-Klick lässt einen roten Vorhang vor den Banner
   fahren, tauscht dahinter Fotos gegen das YouTube-Video und öffnet
   den Vorhang wieder. */

.curtain {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 50%;
  /* Fällt auf den Gradient zurück, falls images/curtain.jpeg mal fehlt.
     Bei erneutem Dateiformat-Wechsel hier den Dateinamen anpassen. */
  background: url('images/curtain.jpeg') center/cover no-repeat,
    linear-gradient(180deg, var(--curtain), var(--curtain-dark));
  /* Im hellen Vorschau-Modus (siehe :root[data-theme="light"]) wird das
     Vorhang-Foto blau statt rot eingefärbt — sonst "none" (unverändert). */
  filter: var(--curtain-filter);
  z-index: 5;
  pointer-events: none;
  transition: transform 0.7s cubic-bezier(0.65, 0, 0.35, 1);
}

.curtain--left { left: 0; transform: translateX(-100%); }
.curtain--right { right: 0; transform: translateX(100%); }

.carousel.is-curtain-closing .curtain--left,
.carousel.is-curtain-closing .curtain--right {
  transform: translateX(0);
}

.carousel__video {
  position: absolute;
  inset: 0;
  /* Liegt standardmäßig HINTER den Stills (die haben kein eigenes
     z-index, also effektiv 0) — so kann das iframe im Hintergrund schon
     laden, ohne das gerade gezeigte Still-Bild zu verdecken. Erst wenn
     der Vorhang schon ganz zu ist (is-video), rückt es nach vorne. */
  z-index: -1;
  display: block;
  background: #000;
}

.carousel.is-video .carousel__video { z-index: 1; }
.carousel.is-video .carousel__arrow { display: none; }

.carousel__video iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

.carousel__video-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  margin: 0;
  padding: 0 2rem;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* Kind von .modal__scroll (nicht vom Banner), schwebt frei als Overlay
   darüber — Layout darunter bleibt dadurch immer unverändert. `top` wird
   per JS gesetzt (siehe positionToggles in script.js): innen unten
   rechts im Banner im Foto-Modus, knapp darunter sobald ein Video läuft
   (sonst würde die Gruppe den YouTube-eigenen Link zum Streaming-
   Anbieter unten rechts im Video überdecken). Die Transition auf `top`
   animiert diesen Sprung simpel, ohne zusätzliche Bewegtbild-Logik.
   Enthält ein oder zwei Knöpfe ("Film ansehen" / "Trailer ansehen"),
   je nachdem was in video.txt hinterlegt ist. */
.carousel__watch-toggles {
  position: absolute;
  right: 1rem;
  z-index: 10;
  display: flex;
  gap: 0.6rem;
  transition: top 0.4s ease;
}

.carousel__watch-toggle {
  background: rgba(0, 0, 0, 0.55);
  color: var(--overlay-text);
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  font-size: 0.85rem;
  cursor: pointer;
  /* opacity/transform werden per JS direkt gesetzt (siehe mergeToggles
     in script.js) — läuft eines der beiden Videos (Film/Trailer), blendet
     der jeweils andere Knopf so unsichtbar aus, ohne dem Layout entzogen
     zu werden (sonst würde die verbleibende Kapsel beim Reflow hart statt
     weich an ihren Platz springen). */
  transition: background 0.15s ease, opacity 0.3s ease, transform 0.3s ease;
}

.carousel__watch-toggle:hover,
.carousel__watch-toggle:focus-visible {
  background: rgba(0, 0, 0, 0.8);
}

/* Ankündigungstext hinter dem Vorhang, solange VIDEOS_ENABLED in
   script.js auf false steht (siehe setupComingSoon) — liegt wie
   .carousel__video standardmäßig hinter den Stills und rückt erst nach
   vorne, wenn der Vorhang ganz zu ist (is-announcement). */
.carousel__announcement {
  position: absolute;
  inset: 0;
  z-index: -1;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 3rem;
  background: #000;
  color: var(--overlay-text-muted);
  font-size: 1.1rem;
  font-style: italic;
}

.carousel.is-announcement .carousel__announcement { z-index: 1; }
.carousel.is-announcement .carousel__arrow { display: none; }

/* Bleibt (anders als .carousel__watch-toggle) immer innen unten rechts
   im Banner — es gibt hier kein echtes Video, das den Knopf beim
   YouTube-eigenen Link stören könnte, daher keine Positions-Logik per
   JS nötig. */
.carousel__coming-soon-toggle {
  position: absolute;
  bottom: 1rem;
  right: 1rem;
  z-index: 10;
  background: rgba(0, 0, 0, 0.55);
  color: var(--overlay-text);
  border: none;
  border-radius: 999px;
  padding: 0.5rem 1.1rem;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 0.15s ease;
}

.carousel__coming-soon-toggle:hover,
.carousel__coming-soon-toggle:focus-visible {
  background: rgba(0, 0, 0, 0.8);
}

.modal__chevron {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 1.5rem;
  color: var(--text-muted);
  font-size: 1.3rem;
  background: none;
  border: none;
  cursor: pointer;
  transition: transform 0.3s ease, color 0.15s ease;
}

.modal__chevron[hidden] { display: none; }

.modal__chevron:hover,
.modal__chevron:focus-visible {
  color: var(--text);
}

.modal__chevron.is-expanded {
  transform: rotate(180deg);
}

.modal__section--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
}

.modal__section--split.modal__section--single {
  grid-template-columns: 1fr;
}

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

.awards-list li {
  padding: 0.35rem 0;
  border-bottom: var(--line-width) solid var(--line);
  color: var(--text);
  font-size: 0.92rem;
}

.credits-list { margin: 0; }
.credits-list div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.35rem 0;
  border-bottom: var(--line-width) solid var(--line);
}
.credits-list dt { color: var(--text-muted); }
.credits-list dd { margin: 0; color: var(--text); }

/* Ausbildung/Berufserfahrung: Zeitraum als eigene, rechtsbündige Spalte
   statt im Fließtext der Beschreibung — dafür Grid statt des sonst
   üblichen 2-spaltigen Flex-Layouts von .credits-list. */
.credits-list--dated div {
  display: grid;
  grid-template-columns: 7rem 1fr auto;
}

.credits-list--dated dd.credits-date {
  color: var(--text-muted);
  text-align: right;
  white-space: nowrap;
}

/* Für externe Links im Lebenslauf (Filmschule Wien, Staatstheater
   Kassel) — gleiches Verhalten wie .table__row--clickable bei den
   Events: Hover-Hinweis, Klick öffnet den Link in einem neuen Tab. */
.credits-list div[data-external-link] {
  cursor: pointer;
}

.credits-list div[data-external-link]:hover,
.credits-list div[data-external-link]:focus-visible {
  background: rgba(255, 255, 255, 0.04);
}

.credits-footnote {
  margin-top: 1.2rem;
  font-size: 0.85rem;
}

.award-item {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.award-item img { width: 3.6rem; border-radius: 2px; }
.award-item p { margin: 0; color: var(--text); }

/* Vorführungen (Screening-Historie) pro Film, aus data-screenings.js.
   Einträge mit passendem EventTitel sind klickbar (öffnen das Event-
   Overlay), reine Info-Einträge (kein EventTitel) bleiben Fließtext. */
.screenings-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.screening-item {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding: 0.5rem 0;
  border-bottom: var(--line-width) solid var(--line);
  font-size: 0.92rem;
}

.screening-title {
  color: var(--text);
}

/* Kein durchgehender Unterstrich — stattdessen dieselbe Hover-Animation
   wie die Hauptnavigation: eine zunächst unsichtbare Unterlinie blendet
   sich beim Hovern per Transition ein, statt permanent dazustehen. */
.screening-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--text);
  border-bottom: 1px solid transparent;
  padding-bottom: 0.15rem;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.screening-link:hover,
.screening-link:focus-visible {
  border-color: var(--text);
}

.screening-meta {
  color: var(--text-muted);
  white-space: nowrap;
}

/* ---------- Responsive ---------- */

/* Muss NACH .about-layout/.about-meta/.about-cv/.credits-list--dated
   stehen — bei gleicher Spezifität gewinnt sonst die Basis-Regel und die
   Seite bleibt auf Mobilgeräten fälschlich zweispaltig bzw. die
   Zeitraum-Spalte läuft über den Rand hinaus. */
@media (max-width: 700px) {
  .about-layout {
    grid-template-columns: 1fr;
  }
  .profile-photo {
    width: 55%;
    margin: 0 auto;
  }
  .about-meta {
    grid-template-columns: 1fr;
  }
  .credits-list--dated div {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }
  .credits-list--dated dd.credits-date {
    text-align: left;
  }

  /* Stapelt bewusst an derselben Breite wie der Lebenslauf oben, nicht
     erst bei 900px — beides sind Tabellen mit fester Spaltenbreite, die
     ab hier eng werden. */
  .table--mitwirkungen .table__row,
  .table--events .table__row,
  .table--filme .table__row {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }

  /* In der gestapelten Ansicht steht jedes Feld in eigener Zeile —
     rechtsbündig ergibt hier keinen Sinn, alles wieder linksbündig. */
  .table--events .table__type,
  .table--mitwirkungen .table__role,
  .table--filme .table__type {
    text-align: left;
  }
}

@media (max-width: 900px) {
  .intro__columns,
  .modal__text-columns { grid-template-columns: 1fr; }
  .modal__description { grid-template-columns: 8rem 1fr; }
  .modal__section--split { grid-template-columns: 1fr; gap: 2rem; }
}

@media (max-width: 560px) {
  /* Fünf Textlinks passen hier nicht mehr sauber in eine Zeile (siehe
     .main-nav--desktop) — stattdessen die kompakte Nav zeigen: Haus-
     Symbol, aufklappbares "Projekte", Über mich. */
  .main-nav--desktop { display: none; }
  .main-nav--mobile { display: flex; }
  .main-nav__projects:not([hidden]) { display: flex; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .film-card img { transition: none; }
  .carousel__slide { transition: none; }
}
