/* ============================================
   Max Judith – Portfolio
   Grundgerüst: Variablen, Layout, Komponenten
   ============================================ */

@font-face {
  font-family: "Archivo Black";
  src: url("assets/fonts/ArchivoBlack-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Archivo Narrow";
  src: url("assets/fonts/ArchivoNarrow-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Archivo Narrow";
  src: url("assets/fonts/ArchivoNarrow-Bold.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --color-bg: #000000;
  --color-text: #f2f0ef;
  --color-highlight: #ff3300;
  --color-bg-alt: #0a0a0a;

  --font-title: "Archivo Black", Arial, sans-serif; /* große Titel/Headlines */
  --font-base: "Archivo Narrow", Arial, sans-serif; /* Fließtext, Nav, Labels */
  --line-color: rgba(255, 255, 255, 0.45); /* dünne weiße Trennlinien/Rahmen, Kontaktabzug-Look */

  --nav-height: 84px;
  --gutter: 1.5rem;
  --max-width: 1400px;
  --edge-pad: clamp(20px, 4vw, 48px); /* Rand für bildschirmfüllende Sections (Letzte Projekte, Social) */

  --transition: 0.25s ease;
}

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

html { scroll-behavior: smooth; }

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-base);
  line-height: 1.5;
  overflow-x: hidden;
}

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

a { color: inherit; text-decoration: none; }

.container {
  max-width: var(--max-width);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ============================================
   Navigation
   ============================================ */

.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--nav-height);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding-inline: var(--gutter);
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* Weicher Übergang an der Unterkante der Menüleiste statt hartem Schnitt */
.site-nav::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 28px;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.35), transparent);
  pointer-events: none;
}

.site-nav__logo {
  justify-self: start;
  display: flex;
}

.site-nav__logo img {
  height: 30px;
  width: auto;
}

.site-nav__list {
  justify-self: center;
  list-style: none;
  display: flex;
  gap: 2.5rem;
  flex-wrap: wrap;
  justify-content: center;
}

.site-nav__link {
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.85rem;
  color: var(--color-highlight);
  transition: opacity var(--transition);
}

.site-nav__link:hover,
.site-nav__link:focus-visible,
.site-nav__link[aria-current="page"] {
  opacity: 0.7;
}

/* Rechter Grid-Block: Sprachumschalter + Rolle + Mobile-Toggle in einer
   Flex-Reihe, damit die Navbar unabhängig davon ein 3-Spalten-Grid bleibt,
   welches der drei Kind-Elemente per Media Query aus-/eingeblendet wird. */
.site-nav__end {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}

.lang-switch {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}

.lang-switch__btn {
  width: 22px;
  height: 15px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: none;
  cursor: pointer;
  opacity: 0.45;
  filter: grayscale(70%);
  overflow: hidden;
  transition: opacity var(--transition), filter var(--transition);
}

.lang-switch__btn svg {
  width: 100%;
  height: 100%;
  display: block;
}

.lang-switch__btn:hover,
.lang-switch__btn:focus-visible {
  opacity: 0.8;
}

.lang-switch__btn.is-active {
  opacity: 1;
  filter: none;
  border-color: var(--color-highlight);
}

.site-nav__role {
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.75rem;
  opacity: 0.8;
  white-space: nowrap;
}

.site-nav__toggle {
  display: none;
  background: none;
  border: 2px solid var(--color-highlight);
  color: var(--color-highlight);
  padding: 0.5rem 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.75rem;
}

@media (max-width: 700px) {
  .site-nav__end { gap: 0.75rem; }
  .site-nav__role { display: none; }
  .site-nav__toggle { display: block; }

  .site-nav__list {
    position: fixed;
    inset: 0;
    z-index: 105;
    justify-self: auto; /* überschreibt justify-self:center der Desktop-Grid-Regel,
                            sonst schrumpft die Fixed-Box auf Inhaltsbreite */
    flex-direction: column;
    justify-content: center;
    gap: 1.5rem;
    width: 100%;
    height: 100vh;
    background: rgba(0, 0, 0, 0.92);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    transform: translateX(100%);
    transition: transform var(--transition);
  }

  .site-nav__list.is-open { transform: translateX(0); }
}

/* ============================================
   Social Sidebar (fixiert, rechter Rand)
   ============================================ */

.social-rail {
  position: fixed;
  right: 1.25rem;
  top: 50%;
  transform: translateY(-50%);
  z-index: 90;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.social-rail a {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text);
  transition: color var(--transition);
}

.social-rail a:hover,
.social-rail a:focus-visible {
  color: var(--color-highlight);
}

.social-rail svg { width: 20px; height: 20px; fill: currentColor; }

@media (max-width: 700px) {
  .social-rail {
    right: 0.75rem;
    gap: 1rem;
  }
  .social-rail svg { width: 18px; height: 18px; }
}

/* ============================================
   Back-to-top Button
   ============================================ */

.back-to-top {
  position: fixed;
  bottom: 2.5rem;
  left: 2rem;
  z-index: 90;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 2px solid var(--color-highlight);
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(6px);
  color: var(--color-highlight);
  font-size: 1.1rem;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--transition);
}

.back-to-top.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* ============================================
   Hero (Vollformat-Video)
   ============================================ */

.hero {
  position: relative;
  height: 100svh;
  width: 100%;
  overflow: hidden;
}

.hero video,
.hero .media-placeholder {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* YouTube-Embed randlos ausfüllend (statt Letterboxing): klassischer
   "Fullscreen-Background-Video"-Trick, Video wird größer als der Hero
   skaliert und mittig zugeschnitten. Kein Klick möglich (rein dekorativ). */
.hero .hero__video {
  position: absolute;
  top: 50%;
  left: 50%;
  right: auto;
  bottom: auto;
  width: 100vw;
  height: 56.25vw; /* 16:9 */
  min-height: 100%;
  min-width: 177.78vh; /* 16:9 */
  max-width: none;
  transform: translate(-50%, -50%);
  pointer-events: none;
  border: 0;
}

.hero__content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  text-align: center;
  padding-bottom: 6rem;
  background: linear-gradient(to top, rgba(0,0,0,0.75), transparent 40%);
  pointer-events: none; /* Klicks sollen zur Facade/zum Pause-Button durchgereicht werden */
}

/* Pause/Stopp-Kontrolle für das autoplaufende Showreel (WCAG 2.2.2) */
.hero__pause {
  position: absolute;
  right: clamp(1rem, 3vw, 2rem);
  bottom: clamp(1rem, 3vw, 2rem);
  z-index: 2;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-text);
  border-radius: 50%;
  background: rgba(0,0,0,0.4);
  color: var(--color-text);
  font-size: 0.7rem;
  cursor: pointer;
}

.hero__pause[hidden] { display: none; }

.hero__pause:hover,
.hero__pause:focus-visible {
  background: rgba(0,0,0,0.7);
}

/* ============================================
   YouTube-Facade: Vorschaubild + Play-Button statt
   automatisch ladendem Embed (DSGVO – kein Laden ohne Klick/Zustimmung)
   ============================================ */

.yt-facade {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 0.85rem;
  margin: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.yt-facade__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.yt-facade:focus-visible {
  outline: 2px solid var(--color-highlight);
  outline-offset: -2px;
}

.yt-facade.is-loaded {
  display: none;
}

/* ============================================
   Cookie-/Consent-Banner: externe Inhalte (YouTube)
   werden erst nach Klick oder Zustimmung geladen
   ============================================ */

.consent-banner {
  position: fixed;
  left: 1rem;
  right: auto;
  bottom: 1rem;
  z-index: 500;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  max-width: 420px;
  padding: 1rem 1.25rem;
  background: #fff;
  color: #000;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
}

.consent-banner[hidden] {
  display: none;
}

.consent-banner__text {
  flex: 1 1 260px;
  font-size: 0.75rem;
  line-height: 1.5;
  color: #000;
}

.consent-banner__text a {
  color: #000;
  text-decoration: underline;
}

.consent-banner__actions {
  display: flex;
  gap: 0.5rem;
  flex-shrink: 0;
}

.consent-banner__btn {
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.75rem;
  padding: 0.55rem 1rem;
  border: 1px solid #000;
  background: #000;
  color: #fff;
  cursor: pointer;
}

.consent-banner__btn--accept {
  background: #000;
  border-color: #000;
  color: #fff;
}

.hero__name {
  font-family: var(--font-title);
  font-size: clamp(1.8rem, 5vw, 3.5rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.hero__role {
  font-family: var(--font-base);
  font-weight: 700;
  margin-top: 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-highlight);
  font-size: clamp(0.8rem, 1.5vw, 1rem);
}

/* ============================================
   Platzhalter für Video/Foto (bis echte Medien da sind)
   ============================================ */

.media-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  background: repeating-linear-gradient(
    45deg,
    var(--color-bg-alt),
    var(--color-bg-alt) 10px,
    #222 10px,
    #222 20px
  );
  border: 1px dashed var(--color-highlight);
  color: var(--color-text);
  font-size: 0.85rem;
  text-align: center;
  padding: 1rem;
  min-height: 220px;
}

/* Sobald echtes Medium eingebunden ist, nie den Platzhalter-Look
   (Streifen/gestrichelter Rand) durchscheinen lassen */
video.media-placeholder,
img.media-placeholder,
iframe.media-placeholder {
  background: none;
  border: 0;
  padding: 0;
}

/* ============================================
   Sections generell
   ============================================ */

/* Einheitliche Sektionsgröße: alle Sections sind gleich groß (min. 70vh,
   Inhalt vertikal zentriert), außer explizit anders definiert (z. B. Hero/
   Showreel mit voller Bildschirmhöhe). */
section {
  min-height: 70vh;
  padding-block: clamp(3rem, 8vw, 6rem);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.section-title {
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: clamp(1.4rem, 3vw, 2.2rem);
  margin-bottom: 1.5rem;
}

/* Trennlinie neben dem Titel (nicht mehr darunter), auf gleicher Höhe wie
   der Titeltext, in der Highlightfarbe. Bricht auf schmalen Viewports in
   eine zweite Zeile um, falls kein Platz mehr daneben ist. */
.section-title--divider {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(20px, 3vw, 40px);
}

.section-title--divider::after {
  content: "";
  display: block;
  width: clamp(300px, 25vw, 500px);
  height: 1px;
  background: var(--color-highlight);
}

/* About-Teaser (Startseite): Hintergrundbild, Text links */
.about-teaser {
  position: relative;
  min-height: 70vh;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  padding-block: 0;
}

.about-teaser .media-placeholder {
  position: absolute;
  inset: 0;
  min-height: unset;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.about-teaser::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.55) 45%, rgba(0,0,0,0.1) 100%);
}

.about-teaser__content {
  position: relative;
  z-index: 1;
  padding-block: clamp(2rem, 6vw, 4rem);
  /* Gleicher Titel-Startpunkt wie bei .container-Sections: bei schmalen
     Viewports einfach --gutter, bei breiten der linke Rand, den ein
     zentrierter Container mit --max-width dort hätte. Text füllt (wie
     alle anderen Sections) den Rest der Breite bis zum rechten Rand. */
  padding-inline-start: max(var(--gutter), calc((100% - var(--max-width)) / 2 + var(--gutter)));
  padding-inline-end: var(--gutter);
}

/* Breite an der Stelle gekappt, an der vorher die Jobbezeichnungen-Zeile
   endete – Text soll nicht über das Gesicht im Hintergrundbild laufen. */
.about-teaser__content p {
  margin-top: 1rem;
  max-width: 460px;
}
.about-teaser__content .section-title { margin-bottom: 0; }

.about-teaser__companies {
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--color-highlight);
}

.about-teaser__content a {
  display: inline-block;
  margin-top: 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--color-highlight);
}

/* Grid für Work/Photography/Best-of */
.media-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

@media (min-width: 600px) {
  .media-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1000px) {
  .media-grid { grid-template-columns: repeat(3, 1fr); }
}

.media-grid__item .media-placeholder { min-height: 260px; }

/* Arbeiten (Startseite): bildschirmfüllend mit etwas Luft zum Rand,
   Kacheln im 16:9, dünne Trennlinien wie ein Kontaktabzug/Sucher-Overlay,
   Label pro Frame. */
.work-preview {
  padding-inline: var(--edge-pad);
}

/* Nur der Titel wird auf die gemeinsame Section-Titel-Position gerückt
   (gleiche Formel wie .about-teaser__content), der Rest der Section
   (Video-Grid) bleibt bildschirmfüllend/responsiv wie gehabt. */
.work-preview .section-title {
  margin-inline-start: calc(max(var(--gutter), calc((100vw - var(--max-width)) / 2 + var(--gutter))) - var(--edge-pad));
}

.work-preview .media-grid {
  gap: 28px;
}

/* "Letzte Projekte": alle Reihen stehen normal im Seitenfluss (kein
   eigener Scroll-Container mehr). Der untere Verlauf blendet sich beim
   normalen Seiten-Scrollen aus, sobald das untere Ende der Sektion in den
   Viewport kommt – siehe initWorkPreviewFade in script.js. */
.work-preview__scroll-wrap {
  position: relative;
  margin-top: 28px;
}

.work-preview__row2 {
  margin-top: 28px;
}

.work-preview__fade-bottom {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: clamp(60px, 8vw, 120px);
  pointer-events: none;
  z-index: 2;
  background: linear-gradient(to top, var(--color-bg), transparent);
}

/* "More Work"-Link, zentriert auf dem unteren Verlauf */
.work-preview__more {
  position: absolute;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 3;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--color-highlight);
}

.work-preview .media-grid__item {
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  position: relative;
}

/* Generisches Label (Nummer + Titel) – für Frame-Boxen überall im Stil
   wiederverwendbar, nicht nur im Arbeiten-Grid */
/* Frame Header = der Bereich zwischen der oberen Linie des Frame-Containers
   (.frame::after, oben) und der unteren Trennlinie des Frame-Headers
   (.frame-label::after). .frame selbst bringt schon 10px Padding mit (Regel:
   Inhalt hält überall mind. 10px Abstand zu den Linien), das oben also schon
   vor dem Label sitzt. Damit Titel/Play-Button unabhängig vom Inhalt exakt
   mittig zwischen BEIDEN Linien stehen (nicht nur innerhalb der Label-Box),
   wird das durch .frame vorgegebene obere Padding hier unten wieder
   abgezogen – padding-top + padding-bottom bleiben in Summe gleich, nur die
   Verteilung gleicht die 10px von oben aus. */
.frame-label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: calc(1.2rem - 10px) 1rem 1.2rem;
  position: relative;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.8rem;
}

.frame-label::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 0;
  height: 1px;
  background: var(--line-color);
}

.frame-label__index { opacity: 0.5; }

/* Play-Icon im Frame-Header: als ganz normales Flex-Kind von .frame-label
   (align-items:center greift automatisch, kein Offset-Hack nötig) rechts
   ausgerichtet über margin-inline-start:auto. Rein dekorativ (aria-hidden)
   – die eigentliche Klickfläche bleibt das ganze Thumbnail (.yt-facade). */
.frame-label__play {
  margin-inline-start: auto;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--color-text);
  background: var(--color-bg);
  color: var(--color-text);
  cursor: pointer;
  transition: color var(--transition), border-color var(--transition);
}

/* Play-Dreieck (Standardzustand: Video läuft nicht) */
.frame-label__play::before {
  content: "";
  border-style: solid;
  border-width: 5px 0 5px 8px;
  border-color: transparent transparent transparent currentColor;
  margin-left: 2px;
}

/* Läuft das Video (per Klick auf Thumbnail oder diesen Button gestartet),
   zeigt der Button statt des Dreiecks ein Stopp-Quadrat und bleibt in der
   Highlightfarbe – ein weiterer Klick stoppt das Video wieder. */
.frame-label__play.is-active {
  color: var(--color-highlight);
  border-color: var(--color-highlight);
}

.frame-label__play.is-active::before {
  width: 10px;
  height: 10px;
  margin-left: 0;
  border: none;
  background: currentColor;
}

/* Button färbt sich in der Highlightfarbe, sobald die Maus über dem Video
   (dem ganzen Thumbnail-Klickbereich) steht, er selbst gehovert/fokussiert
   wird – nicht nur beim direkten Hover auf das Icon selbst. */
.frame-label__play:hover,
.frame-label__play:focus-visible,
.frame:has(.yt-facade:hover) .frame-label__play,
.frame:has(.yt-facade:focus-visible) .frame-label__play {
  color: var(--color-highlight);
  border-color: var(--color-highlight);
}

.frame-label__play:focus-visible {
  outline: 2px solid var(--color-highlight);
  outline-offset: 2px;
}

.work-preview .media-grid__item .media-placeholder {
  min-height: unset;
}

/* Innerer Video-Bereich einer Frame-Box – 16:9, direkt unter dem Label,
   durch dessen Trennlinie (.frame-label::after) vom Titel abgesetzt */
.frame-media {
  position: relative;
  aspect-ratio: 16 / 9;
}

/* Vollständiger Rahmen um eine Box (Video, Kontaktformular, …) – die vier
   Linien berühren sich an den Ecken nie, ~7px Abstand. Der Inhalt hält
   selbst mind. 10px Abstand zu den Linien (Padding auf .frame). */
.frame {
  position: relative;
  padding: 10px;
}

.frame::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-repeat: no-repeat;
  background-image:
    linear-gradient(var(--line-color), var(--line-color)),
    linear-gradient(var(--line-color), var(--line-color)),
    linear-gradient(var(--line-color), var(--line-color)),
    linear-gradient(var(--line-color), var(--line-color));
  background-size:
    calc(100% - 14px) 1px,
    calc(100% - 14px) 1px,
    1px calc(100% - 14px),
    1px calc(100% - 14px);
  background-position:
    7px 0,
    7px 100%,
    0 7px,
    100% 7px;
}

.work-preview .media-grid__item video,
.work-preview .media-grid__item img,
.work-preview .media-grid__item iframe {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border: 0;
  background: none;
}

/* ============================================
   Social (Startseite): YouTube- und Instagram-Profilkarte,
   jede Spalte eigenständig gestaltet, eigenes Frame-Label.
   Bildschirmfüllend wie "Letzte Projekte" (nicht mehr .container),
   nur der Titel wird auf die gemeinsame Section-Titel-Position gerückt. */
.social-section {
  padding-inline: var(--edge-pad);
}

.social-section .section-title {
  margin-inline-start: calc(max(var(--gutter), calc((100vw - var(--max-width)) / 2 + var(--gutter))) - var(--edge-pad));
}

.social-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  padding-top: 1.25rem;
  /* Jede Karte behält ihre eigene, vom Inhalt bestimmte Höhe – die
     Inhaltsgröße (Shorts-Bereich / Screenshot) wird stattdessen direkt
     über ein gemeinsames Seitenverhältnis angeglichen, siehe
     .shorts-slider-wrap weiter unten. */
  align-items: start;
}

/* Grid-Kinder schrumpfen ohne min-width:0 nicht unter die Inhaltsbreite
   ihrer Kinder – der horizontal scrollende Shorts-Slider würde sonst
   seine Spalte aufblähen und Instagram an den Rand drängen. */
.social-columns > .frame {
  min-width: 0;
}

@media (max-width: 700px) {
  .social-columns {
    grid-template-columns: 1fr;
  }
}

.social-card__body {
  display: flex;
  flex-direction: column;
  gap: 1.3rem;
  padding: 0.85rem 1.75rem 2rem;
}

.frame.social-card {
  display: flex;
  flex-direction: column;
}

.social-card__profile {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: fit-content;
  transition: opacity var(--transition);
}

.social-card__profile:hover,
.social-card__profile:focus-visible {
  opacity: 0.75;
}

.social-card__profile:hover .social-card__handle,
.social-card__profile:focus-visible .social-card__handle {
  color: var(--color-highlight);
}

.social-card__icon {
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  color: var(--color-text);
}

.social-card__icon svg { width: 100%; height: 100%; fill: currentColor; }

.social-card__handle {
  font-family: var(--font-base);
  font-weight: 700;
  letter-spacing: 0.03em;
  font-size: 1.05rem;
}

/* CTA-Button – gleiche Optik wie der Instagram-Button (Rahmen + Fläche
   statt reiner Unterstreichung) */
.social-card__cta {
  align-self: center;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.8rem;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--color-text);
  background: rgba(0, 0, 0, 0.4);
  transition: border-color var(--transition), background var(--transition);
}

.social-card__cta:hover,
.social-card__cta:focus-visible {
  border-color: var(--color-highlight);
}

/* YouTube: horizontaler Shorts-Slider (9:16-Kacheln). Seitenverhältnis
   entspricht exakt dem des Instagram-Screenshots (1200×778), damit die
   Inhaltsgröße beider Felder bei gleicher Spaltenbreite immer gleich groß
   ist – unabhängig davon, wie viele Kacheln dabei ohne Scrollen sichtbar
   sind (auch wenn das nur 3 sind). */
.shorts-slider-wrap {
  position: relative;
  aspect-ratio: 1200 / 778;
  /* Hart gedeckelt: egal was der Inhalt (z. B. lange Video-Titel) an
     eigener Höhe verlangt, sichtbar bleibt exakt die Höhe, die sich aus
     dem Seitenverhältnis ergibt – identisch zur Höhe des IG-Screenshots. */
  overflow: hidden;
}

/* Verlauf an beiden Seiten, deutet weitere (bereits gescrollte/kommende)
   Shorts an – links in Schwarz, rechts in CI-Orange */
.shorts-slider-wrap::before,
.shorts-slider-wrap::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0.35rem;
  width: clamp(36px, 10vw, 90px);
  pointer-events: none;
  z-index: 1;
}

.shorts-slider-wrap::before {
  left: 0;
  background: linear-gradient(to right, var(--color-bg), transparent);
}

.shorts-slider-wrap::after {
  right: 0;
  background: linear-gradient(to left, var(--color-highlight), transparent);
}

.shorts-slider {
  display: flex;
  height: 100%;
  gap: 0.75rem;
  overflow-x: auto;
  padding-bottom: 0.35rem;
  scrollbar-width: thin;
  scrollbar-color: var(--color-highlight) transparent;
}

.shorts-slider::-webkit-scrollbar {
  height: 4px;
}

.shorts-slider::-webkit-scrollbar-track {
  background: transparent;
}

.shorts-slider::-webkit-scrollbar-thumb {
  background: var(--color-highlight);
  border-radius: 4px;
}

.shorts-slider::-webkit-scrollbar-thumb:hover {
  background: var(--color-text);
}

.shorts-slider__status {
  font-size: 0.85rem;
  opacity: 0.6;
}

.shorts-slider__item {
  flex: 0 0 auto;
  width: auto;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.shorts-slider__thumb-wrap {
  display: block;
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: auto;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--color-bg-alt);
}

.shorts-slider__thumb-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.shorts-slider__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 0.4rem;
  font-size: 0.72rem;
  line-height: 1.3;
  opacity: 0.75;
}

/* Instagram: statischer Screenshot des Profils statt Live-Feed, verlinkt
   aufs echte Profil. Button sitzt jetzt darunter (.social-card__cta,
   gleiche Struktur wie beim YouTube-Feld), nicht mehr als Overlay auf dem
   Bild – so sind beide Spalten exakt gleich groß. */
.instagram-preview {
  display: block;
  overflow: hidden;
}

.instagram-preview__img {
  width: 100%;
  height: auto;
  display: block;
  filter: saturate(0.9);
  transition: transform var(--transition), filter var(--transition);
}

.instagram-preview:hover .instagram-preview__img,
.instagram-preview:focus-visible .instagram-preview__img {
  transform: scale(1.03);
  filter: saturate(1);
}

/* ============================================
   Katalog-Liste (Work/Photography): nummeriert,
   durch dünne helle Linien getrennt – Kontaktabzug-Look
   ============================================ */

.catalog {
  border-top: 1px solid var(--line-color);
}

.catalog__row {
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
  padding-block: 1.1rem;
  border-bottom: 1px solid var(--line-color);
  transition: opacity var(--transition);
}

.catalog__row:hover { opacity: 0.7; }

.catalog__index {
  font-family: var(--font-base);
  font-weight: 700;
  font-size: 0.85rem;
  opacity: 0.5;
  width: 2rem;
  flex-shrink: 0;
}

.catalog__title {
  flex: 1;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: clamp(0.95rem, 2vw, 1.15rem);
}

.catalog__meta {
  font-family: var(--font-base);
  font-weight: 700;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.6;
  white-space: nowrap;
}

/* Utility: soft-focus/entsättigter "analoger" Look für echte Fotos,
   sobald sie eingebunden werden (auf <img> anwenden) */
.media-photo {
  filter: saturate(0.85) contrast(0.95);
}

/* ============================================
   About-Seite
   ============================================ */

/* Intro: gleiches Muster wie der Showreel-Hero auf der Startseite
   (.hero) – Vollformat 100svh, Bild/Video randlos, Verlauf + Titel unten
   zentriert. Aktuell ein Foto als Platzhalter (.about-hero__media);
   .media-photo sorgt schon für den entsättigten "analogen" Look. Sobald
   das Bilder-Video fertig geschnitten ist, wird hier aus dem <img> ein
   <iframe>/<video> nach dem gleichen Muster wie #video-showreel. */
.about-hero {
  position: relative;
  height: 100svh;
  width: 100%;
  overflow: hidden;
}

.about-hero__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about-hero__content {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  text-align: center;
  padding-bottom: 6rem;
  background: linear-gradient(to top, rgba(0,0,0,0.75), transparent 40%);
}

.about-hero__title {
  font-family: var(--font-title);
  font-size: clamp(1.8rem, 5vw, 3.5rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Skill Tree: Hintergrund in diagonal geschnittene Spalten gesplittet,
   je eine Spalte = ein Skill. Jede Spalte ist ein absolut positioniertes
   Panel über die volle Fläche von .skilltree__panels, per clip-path auf
   ein Trapez zugeschnitten (--st/--et = Start/Ende oben, --sb/--eb =
   Start/Ende unten, in % der Breite) – so entstehen durchgängige, parallel
   verlaufende Diagonalen statt gerader Spaltengrenzen. Foto liegt in Ruhe
   oben, Video blendet sich beim Hover/Fokus ein und spielt nur so lange. */
.skilltree {
  padding-inline: var(--edge-pad);
}

.skilltree .section-title {
  margin-inline-start: calc(max(var(--gutter), calc((100vw - var(--max-width)) / 2 + var(--gutter))) - var(--edge-pad));
}

.skilltree__panels {
  position: relative;
  margin-top: 28px;
  /* Nochmal um ca. 1/4 größer (480/61.3vw/827px * 1.25), dann um ca. 1/8 reduziert
     (600/76.6vw/1034px * 0.875) – darf ruhig groß sein */
  height: clamp(525px, 67vw, 905px);
  isolation: isolate; /* eigener Stacking-Context, damit z-index beim Hover nicht mit anderen Sections kollidiert */
}

.skilltree__panel {
  position: absolute;
  inset: 0;
  clip-path: polygon(var(--st) 0%, var(--et) 0%, var(--eb) 100%, var(--sb) 100%);
  overflow: hidden;
  cursor: pointer;
  transform-origin: var(--tx, 50%) 50%;
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), clip-path 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.skilltree__panel:hover,
.skilltree__panel:focus-within {
  transform: scale(1.06);
  z-index: 2;
}

/* Wichtig: Bild/Video wird NICHT über die volle Panels-Breite gelegt,
   sondern nur über die eigene Spalten-Box (--bx/--bw, in % der
   .skilltree__panels-Breite, siehe Inline-Style je Panel). Würde das Bild
   die volle Breite füllen, läge (bei object-fit:cover) jedes Foto 1:1 über
   allen 3 Spalten – der schräge clip-path der jeweiligen Spalte würde dann
   nur einen schmalen, meist willkürlichen Ausschnitt davon zeigen, und die
   Person darauf könnte in einer ganz anderen Spalte "landen" als gedacht.
   Über die eigene, schmalere Box greift object-fit:cover dagegen wie ein
   normaler Bildausschnitt dieser einen Spalte, und object-position (--ox/
   --oy) lässt sich sinnvoll nutzen, um die Person mittig ins Bild zu holen. */
.skilltree__img,
.skilltree__video {
  position: absolute;
  top: 0;
  left: var(--bx, 0%);
  width: var(--bw, 100%);
  height: 100%;
  object-fit: cover;
  object-position: var(--ox, 50%) var(--oy, 50%);
  filter: saturate(0.85) contrast(0.95);
}

.skilltree__video {
  opacity: 0;
  transition: opacity 0.3s ease;
}

.skilltree__panel:hover .skilltree__video,
.skilltree__panel:focus-within .skilltree__video,
.skilltree__panel.is-playing .skilltree__video {
  opacity: 1;
}

/* Ein fixes "left" würde bei den schräg geschnittenen Spalten oft außerhalb
   des sichtbaren (clip-path) Bereichs landen und verschwinden. Stattdessen
   an --tx ausgerichtet: das ist bereits die horizontale Mitte der Spalte auf
   halber Panel-Höhe (siehe Inline-Style je Panel, gleiche Variable wie beim
   transform-origin fürs Hover-Scaling) – zusammen mit top:50% steht der Titel
   so mittig in seiner Spalte statt wie bisher unten. Alle drei Titel nutzen
   dieselbe Größe (einheitlich, unabhängig von der Textlänge); --label-size
   bleibt als optionales Pro-Panel-Override verfügbar, falls ein künftiger
   Titel zu lang für seine Spalte wird und einzeln verkleinert werden muss. */
.skilltree__label {
  position: absolute;
  top: 50%;
  left: var(--tx, 50%);
  transform: translate(-50%, -50%);
  z-index: 1;
  white-space: nowrap;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: var(--label-size, clamp(0.85rem, 1.75vw, 1.6rem));
  color: var(--color-text);
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.85);
}

@media (max-width: 700px) {
  /* Diagonale Trapez-Schnitte brauchen Breite, um zu wirken – auf schmalen
     Viewports werden die Panels stattdessen einfach gestapelt. */
  .skilltree__panels {
    height: auto;
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }

  .skilltree__panel {
    position: relative;
    clip-path: none;
    height: 260px;
    transform-origin: center;
  }

  /* Ohne Clip-Path ist die Spalte wieder ein normales Rechteck über die
     volle Breite – Titel bleibt trotzdem mittig, jetzt einfach mittig im
     Rechteck statt an --tx (das ist ein Desktop-Diagonalwert). */
  .skilltree__label {
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

  /* Jedes Panel ist jetzt ein eigenes, volles Rechteck (siehe oben) – Bild/
     Video soll hier wieder die ganze Breite füllen statt der schmalen
     Desktop-Spalten-Box. */
  .skilltree__img,
  .skilltree__video {
    left: 0;
    width: 100%;
  }
}

/* "Behind the Szenes"-Sektion: drei durchlaufende Filmstreifen-Reihen
   ("Marquee") aus BTS-Fotos, jede Kachel im echten Mittelformat-Dia-Rähmchen
   (Grafik: Mittelformt-Frame-Analog.png). Technik pro Kachel: Foto liegt
   unten (object-fit:cover, per inset auf das gemessene Grünfläche-Fenster
   der Rahmengrafik positioniert), die freigestellte Rahmengrafik (Grün per
   Chroma-Key zu transparent gemacht, siehe frame-analog-window.png) liegt
   als zweites <img> exakt darüber – so "verdeckt" das Foto nur die
   ehemalige Grünfläche, der Rest bleibt vom Rahmen maskiert.
   Jede Reihe verdoppelt ihre Kachel-Liste im Markup und animiert per
   transform: translateX(0 → -50% bzw. -50% → 0) – dadurch entsteht ein
   nahtloser Endlos-Loop ohne sichtbaren Sprung. Reihe 1+3 laufen links→
   rechts, Reihe 2 rechts→links (siehe Keyframes unten). */
.about-gallery {
  padding-inline: var(--edge-pad);
  min-height: unset;
  justify-content: flex-start;
}

.about-gallery .section-title {
  margin-inline-start: calc(max(var(--gutter), calc((100vw - var(--max-width)) / 2 + var(--gutter))) - var(--edge-pad));
}

.about-gallery__marquee {
  --row-h: clamp(120px, 12.5vw, 210px);
  margin-top: 28px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.about-gallery__row-track {
  overflow: hidden;
  width: 100%;
}

.about-gallery__row {
  display: flex;
  width: max-content;
  /* Drei Reihen bewusst unterschiedlich schnell (60s/95s/75s), damit die
     Bewegung nicht synchron wirkt, sondern organischer/zufälliger. */
  animation: bts-scroll-ltr 60s linear infinite;
}

.about-gallery__row--rtl {
  animation-name: bts-scroll-rtl;
  animation-duration: 95s;
}

.about-gallery__row--slow {
  animation-duration: 75s;
}

@keyframes bts-scroll-ltr {
  from { transform: translateX(-50%); }
  to { transform: translateX(0); }
}

@keyframes bts-scroll-rtl {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .about-gallery__row {
    animation: none;
  }
}

.about-gallery__tile {
  position: relative;
  flex: none;
  height: var(--row-h);
  aspect-ratio: 540 / 360; /* Seitenverhältnis der Rahmengrafik */
}

.about-gallery__tile-photo {
  position: absolute;
  display: block;
  /* Inset = das per Chroma-Key vermessene Grünflächen-Fenster der
     Rahmengrafik (in % von Breite/Höhe der Grafik: 540×360px). */
  inset: 5.3% 7% 6.4% 9.1%;
  width: calc(100% - 9.1% - 7%);
  height: calc(100% - 5.3% - 6.4%);
  object-fit: cover;
  filter: saturate(0.85) contrast(0.95);
}

.about-gallery__tile-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  pointer-events: none;
}

/* Wiederverwendeter Text-Baustein für den Link – aktuell in
   .company-showcase__info verwendet (COU2IN/FrameFactory), Klassenname
   bewusst allgemein gehalten für weitere mögliche Wiederverwendung.
   (Die frühere .about-company__heading-Regel für die Firmennamen-Überschrift
   ist entfallen, seit die Überschriften entfernt wurden – das Logo
   übernimmt diese Funktion jetzt allein.) */
.about-company__link {
  display: inline-block;
  margin-top: 1.5rem;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--color-highlight);
}

/* Company Showcase (COU2IN / FrameFactory): eigene Vollformat-Sektion in
   Skill-Tree-Größe. Linkes/rechtes Drittel = schwarze Fläche mit Logo +
   Text, restliche 2/3 = Kachel-Mosaik aus Fotos. .company-showcase--reverse
   spiegelt die Seiten einfach über die Reihenfolge der beiden Panels im
   Markup (kein flex-direction:row-reverse nötig) – nur die Verlaufsrichtung
   des Übergangs muss dafür extra gespiegelt werden (siehe unten). */
.company-showcase {
  padding-inline: var(--edge-pad);
  min-height: unset;
  justify-content: flex-start;
}

.company-showcase__panels {
  display: flex;
  flex-wrap: wrap;
  /* gleiche Höhe wie .skilltree__panels, siehe dort (um 1/8 reduziert) */
  height: clamp(525px, 67vw, 905px);
  background: #000;
  isolation: isolate; /* eigener Stacking-Context, wie beim Skill Tree */
}

.company-showcase__info {
  flex: 1 1 33.333%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.25rem;
  padding: clamp(1.5rem, 4vw, 3rem);
  position: relative;
  z-index: 2;
}

.company-showcase__info p { margin-top: 1.25rem; max-width: 340px; }

/* Rollen-Zeile direkt unterm Logo (z. B. "Co-Founder & Videograf") – wie
   ein kleines Etikett, enger ans Logo gerückt als der Fließtext darunter.
   Selektor mit zwei Klassen bewusst, um die generische margin-top-Regel
   direkt darüber (.company-showcase__info p) gezielt zu überschreiben. */
.company-showcase__info .company-showcase__role {
  margin-top: 0.5rem;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.75rem;
  color: var(--color-highlight);
  opacity: 0.9;
}

/* Kachel-Mosaik: 5 fest platzierte Kacheln über grid-template-areas (ein
   großes Feld links/rechts + 4 kleinere, siehe ASCII-Layout unten), sodass
   sie IMMER exakt die 5×6-Fläche füllen – keine Lücken, aber auch kein
   Überstand/Clipping über die Sektion hinaus (anders als die vorherige
   Auto-Flow-Variante). .company-showcase--reverse spiegelt die Areas
   horizontal, die Tile-Elemente selbst (grid-area: t1/t1b/t2/t3/t4) bleiben
   dabei unverändert im Markup. */
.company-showcase__tiles {
  flex: 1 1 66.666%;
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  grid-template-rows: repeat(6, 1fr);
  grid-template-areas:
    "t1  t1  t1  t2  t2"
    "t1  t1  t1  t2  t2"
    "t1  t1  t1  t3  t3"
    "t1  t1  t1  t3  t3"
    "t1b t1b t1b t4  t4"
    "t1b t1b t1b t4  t4";
  gap: 28px; /* wie .work-preview .media-grid – gleicher "Luft"-Wert wie bei
                den anderen Kachel-/Karten-Rastern der Seite */
}

/* FrameFactory: t1 (die Video-Kachel, siehe .company-showcase__tile--video
   weiter unten) soll exakt dieselbe Größe/Form wie COU2IN's t1 haben (3
   Spalten × 4 Zeilen), aber unten rechts statt oben links stehen – daher
   ist dieses Areas-Layout eine 180°-Drehung des COU2IN-Layouts (jede Zeile
   UND jede Spalte gespiegelt): t1b wandert von unten-links nach oben-rechts,
   t2/t3/t4 entsprechend mit. Ergebnis bleibt weiterhin lückenlos ohne
   Überstand, wirkt aber nicht wie eine reine Spiegelung der COU2IN-Sektion
   (die kleinen Kacheln liegen alle links statt alle rechts). */
.company-showcase--reverse .company-showcase__tiles {
  grid-template-areas:
    "t4  t4  t1b t1b t1b"
    "t4  t4  t1b t1b t1b"
    "t3  t3  t1  t1  t1"
    "t3  t3  t1  t1  t1"
    "t2  t2  t1  t1  t1"
    "t2  t2  t1  t1  t1";
}

/* Weicher Übergang von der schwarzen Logo-Fläche in die Kacheln, statt
   eines harten Schnitts – liegt über den Kacheln, nicht klickbar. */
.company-showcase__tiles::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(to right, #000 0%, transparent 45%);
}

/* Gespiegelt: Info-Panel liegt jetzt hinter (rechts von) den Kacheln im
   Markup, der Verlauf muss also von rechts statt von links kommen. */
.company-showcase--reverse .company-showcase__tiles::before {
  background: linear-gradient(to left, #000 0%, transparent 45%);
}

/* Jede Kachel ist jetzt zusätzlich eine .frame-Box (siehe frame-lines-
   design-pattern.md) mit eigenem Frame-Label (Index + Titel) – dafür intern
   auf Flex umgestellt: Label oben (feste Höhe), Medienbereich darunter
   füllt den Rest der Kachel. Die vier Rahmenlinien von .frame wachsen beim
   Hover mit, weil transform auf der ganzen Kachel inkl. .frame::after
   liegt. */
.company-showcase__tile {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transform-origin: center;
  transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.company-showcase__tile:hover {
  transform: scale(1.05);
  z-index: 4;
}

/* .frame bringt sitzweit 10px Padding mit (Design-Pattern-Regel), das war
   der eigentliche Grund, warum der Titel trotz symmetrischem Label-Padding
   nicht mittig wirkte: der Abstand von der oberen Rahmenlinie bis zum Text
   war 10px(Frame) + Label-padding-top, der Abstand vom Text zur unteren
   Trennlinie aber nur Label-padding-bottom – deutlich weniger. Für diese
   sehr kompakten Kachel-Header wird das Frame-Padding hier gezielt auf 6px
   reduziert (nur für Company-Showcase-Kacheln, das globale .frame bleibt
   für Work-Preview/Kontaktformular bei 10px) und das Label-Padding hat
   dadurch oben 0, unten 6px – macht Frame-Padding + Label-Padding auf
   beiden Seiten gleich (6px/6px), Text sitzt jetzt wirklich mittig
   zwischen oberer Rahmenlinie und unterer Trennlinie. */
.company-showcase__tile.frame {
  padding: 6px;
}

.company-showcase__tile .frame-label {
  flex: none;
  z-index: 4; /* über dem ::before-Verlauf (z-index:3), sonst bei den
                 kachelnahen zum Logo hin kaum lesbar */
  align-items: center;
  padding: 0 0.85rem 6px;
  font-size: 0.6rem;
  line-height: 1;
}

/* Titel sauber mit Ellipsis abschneiden statt hart mitten im Wort (durch
   das overflow:hidden der Kachel), falls er auf schmalen Kacheln (v. a.
   Mobile) nicht mehr ganz reinpasst. */
.company-showcase__tile .frame-label__title {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  min-width: 0;
}

.company-showcase__tile-media {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  margin-top: 0.6rem; /* Luft zwischen Label-Trennlinie und Foto, sonst
                          klebt das Bild direkt an der Linie */
  overflow: hidden;
}

.company-showcase__tile-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--ox, 50%) var(--oy, 50%);
  filter: saturate(0.85) contrast(0.95);
}

/* Einzelne, ausgewählte Kacheln können zusätzlich ein Hover-Video bekommen
   (aktuell nur die große COU2IN-Kachel t1, Modifier-Klasse
   .company-showcase__tile--video) – gleiches Prinzip wie beim Skill Tree:
   Foto liegt in Ruhe, Video blendet per Hover/Fokus ein und spielt nur so
   lange (siehe initHoverVideoPanels() in script.js, dieselbe Funktion
   bedient jetzt Skill-Tree-Panels UND diese Kacheln – Selektor dort um
   ".company-showcase__tile--video" erweitert). */
.company-showcase__tile-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.85) contrast(0.95);
  opacity: 0;
  transition: opacity 0.3s ease;
}

.company-showcase__tile--video:hover .company-showcase__tile-video,
.company-showcase__tile--video:focus-within .company-showcase__tile-video,
.company-showcase__tile--video.is-playing .company-showcase__tile-video {
  opacity: 1;
}

/* Frame-Rahmenfarbe ist pro Kachel überschreibbar, ohne .frame::after
   anzufassen: --line-color ist eine CSS-Variable, die per Inline-Style auf
   einer einzelnen .frame-Box gesetzt werden kann (siehe die COU2IN-Video-
   Kachel in about.html: --line-color: var(--color-highlight)). Default
   bleibt für alle anderen Frames das sitzweite Weiß aus --line-color. */

.company-showcase__logo {
  height: clamp(80px, 12vw, 180px);
  width: auto;
  margin-bottom: 1.5rem;
}

/* Die FrameFactory-Datei ist ein fast quadratisches Signet mit viel
   Weißraum/Rahmen um die eigentliche Bildmarke (F-Symbol + Schriftzug),
   während die COU2IN-Datei eng auf den Schriftzug zugeschnitten ist –
   bei gleicher CSS-Höhe wirkt FrameFactory dadurch deutlich kleiner.
   Kompensiert über eine größere Zielhöhe, bis beide optisch etwa gleich
   schwer wirken. */
#framefactory .company-showcase__logo {
  height: clamp(120px, 17vw, 260px);
}

@media (max-width: 700px) {
  /* Wie beim Skill Tree: das Nebeneinander von schmaler Logo-Fläche und
     Kachel-Mosaik braucht Breite. Auf Mobile stattdessen gestapelt – Logo/
     Text immer zuerst, unabhängig von --reverse, danach die Kacheln in
     derselben 5×6-Aufteilung, nur mit fester, kleinerer Höhe. */
  .company-showcase__panels {
    flex-direction: column;
    height: auto;
  }

  .company-showcase--reverse .company-showcase__panels {
    flex-direction: column;
  }

  .company-showcase--reverse .company-showcase__info { order: 1; }
  .company-showcase--reverse .company-showcase__tiles { order: 2; }

  .company-showcase__info {
    flex: none;
    padding: 2rem clamp(1.25rem, 4vw, 2rem);
  }

  .company-showcase__logo {
    height: clamp(64px, 22vw, 110px);
  }

  .company-showcase__tiles {
    flex: none;
    height: clamp(360px, 90vw, 480px);
    gap: 10px; /* der große Desktop-Abstand (28px) frisst auf schmalen
                  Viewports zu viel von der ohnehin knappen Breite */
  }

  /* Verlauf ist nur beim Nebeneinander sinnvoll, im gestapelten Layout
     einfach ausblenden statt unpassend über die Kacheln zu legen. */
  .company-showcase__tiles::before,
  .company-showcase--reverse .company-showcase__tiles::before {
    background: none;
  }
}

/* ============================================
   Kontaktformular
   ============================================ */

.contact {
  background: var(--color-bg-alt);
  padding-inline: 20px;
}

.contact-frame {
  width: 100%;
  max-width: 1160px;
  margin-inline: auto;
  padding: 0.5rem clamp(1.25rem, 4vw, 2.25rem) clamp(1.5rem, 4vw, 2.25rem);
}

/* Name/E-Mail/Nachricht und der Connect-Textblock beginnen/enden exakt dort,
   wo die Trennlinie unter dem Frame-Label beginnt/endet (.frame-label::after
   ist 14px von der Frame-Label-Box eingerückt – gleiche 14px hier). */
.contact-columns {
  display: grid;
  grid-template-columns: 1.2fr 1fr;
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
  padding-top: 1.25rem;
  padding-inline: 14px;
}

@media (max-width: 700px) {
  .contact-columns {
    grid-template-columns: 1fr;
  }
}

.contact-form {
  display: grid;
  gap: 0.85rem;
}

.contact-info {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  align-self: center;
  gap: 0.75rem;
  padding-top: 0.4rem;
  text-align: right;
}

.contact-info__heading {
  font-family: var(--font-title);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: clamp(1.3rem, 2.6vw, 1.8rem);
  margin-bottom: 0.5rem;
  color: var(--color-highlight);
}

.contact-info__link {
  font-family: var(--font-base);
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  color: var(--color-text);
  border-bottom: 1px solid transparent;
  width: fit-content;
  transition: border-color var(--transition);
}

.contact-info__link:hover,
.contact-info__link:focus-visible {
  border-color: var(--color-highlight);
}

.contact-form label {
  display: block;
  margin-bottom: 0.3rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  background: transparent;
  border: 1px solid var(--color-text);
  color: var(--color-text);
  padding: 0.55rem 0.65rem;
  font-family: inherit;
  font-size: 0.9rem;
}

.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-color: var(--color-highlight);
}

.contact-form button {
  justify-self: start;
  background: var(--color-highlight);
  color: var(--color-bg);
  border: none;
  padding: 0.65rem 1.5rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: opacity var(--transition);
}

.contact-form button:hover { opacity: 0.85; }

.contact-form__status { font-size: 0.9rem; }
.contact-form__status[data-state="success"] { color: #7fd97f; }
.contact-form__status[data-state="error"] { color: #ff6b6b; }

/* Honeypot-Feld: für Menschen unsichtbar, Bots tappen rein */
.contact-form__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ============================================
   Footer
   ============================================ */

.site-footer {
  padding-block: 2.5rem;
  border-top: 1px solid #2a2a2a;
  font-size: 0.85rem;
}

.site-footer__columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2rem;
  margin-bottom: 2rem;
}

/* Ab Tablet-Breite: drei gleich breite Spuren über die volle Breite –
   Info ganz links, Social mittig (auch die Links zentriert), Gehört zu
   mir ganz rechts (rechtsbündig). Auf Mobile bleibt alles gestapelt und
   linksbündig (siehe .site-footer__col). */
@media (min-width: 600px) {
  .site-footer__columns {
    grid-template-columns: 1fr 1fr 1fr;
    gap: clamp(2rem, 6vw, 5rem);
  }

  .site-footer__col:nth-child(1) {
    align-items: flex-start;
    text-align: left;
  }

  .site-footer__col:nth-child(2) {
    align-items: center;
    text-align: center;
  }

  .site-footer__col:nth-child(3) {
    align-items: flex-end;
    text-align: right;
  }
}

.site-footer__col {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
}

.site-footer__heading {
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 0.75rem;
  color: var(--color-highlight);
  margin-bottom: 0.4rem;
}

.site-footer__col a { opacity: 0.8; }
.site-footer__col a:hover { opacity: 1; color: var(--color-highlight); }

.site-footer__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-color);
}

.site-footer__copyright {
  opacity: 0.6;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.site-footer__logo {
  height: 20px;
  width: auto;
  opacity: 0.85;
}

/* Platzhalter-Hinweistext generell */
.placeholder-note {
  color: var(--color-highlight);
  font-size: 0.85rem;
}

/* ============================================
   Rechtstexte (Impressum/Datenschutz): reiner Fließtext-Aufbau, keine
   Frame-Boxen – Unterüberschriften in der technischen Schrift + dünner
   Trennlinie, angelehnt an den Linien-Look der Seite (siehe
   frame-lines-design-pattern), aber bewusst leichter für reinen Prosatext.
   ============================================ */
.legal-content {
  padding-bottom: 6rem;
}

.legal-content__meta p {
  margin-bottom: 0.75rem;
  line-height: 1.6;
}

.legal-content__meta a {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legal-content h2 {
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.9rem;
  margin-top: 2.75rem;
  margin-bottom: 0.85rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.25);
}

.legal-content p {
  font-size: 0.92rem;
  line-height: 1.65;
  opacity: 0.85;
  margin-bottom: 1rem;
}

.legal-content ul {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
}

.legal-content li {
  position: relative;
  padding-left: 1.1em;
  font-size: 0.92rem;
  line-height: 1.6;
  opacity: 0.85;
  margin-bottom: 0.35rem;
}

.legal-content li::before {
  content: "–";
  position: absolute;
  left: 0;
  opacity: 0.6;
}

/* Kompaktere Variante für sehr lange Rechtstexte (Datenschutzerklärung):
   kleinere Schrift, engere Abstände, zusätzlich Unterüberschriften-Ebene
   (h3, z. B. "a) Kontaktformular") unterhalb der nummerierten h2-Abschnitte. */
.legal-content--compact h2 {
  font-size: 0.8rem;
  margin-top: 2rem;
  margin-bottom: 0.6rem;
  padding-bottom: 0.45rem;
}

.legal-content--compact h3 {
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
  opacity: 0.85;
  margin-top: 1.5rem;
  margin-bottom: 0.5rem;
}

.legal-content--compact p,
.legal-content--compact li {
  font-size: 0.8rem;
  line-height: 1.6;
}

/* ============================================
   Work-Seite: Katalog-Liste mit Vollbild-Hover-Video
   ============================================
   Aufbau: volle 100svh-Section, Hintergrundvideo per YouTube-Embed
   (gleicher Fullscreen-Cover-Trick wie .hero__video), das per Hover/Fokus
   auf eine Zeile eingeblendet wird und dabei die passende data-yt-id lädt
   (siehe initWorkCatalogVideoBg() in script.js). Die Zeilen selbst sitzen
   unten im Viewport in einer Box mit fester Höhe (--work-row-h * 3.8 =
   3 volle Zeilen + je eine teilweise sichtbare oben/unten), die per
   Scroll erreichbar sind. Die teilweise sichtbaren Zeilen "verschwinden"
   nicht hart, sondern blenden über zwei Blur-Veils aus (gleiche
   backdrop-filter-Technik wie die Navbar beim Scrollen, siehe oben in
   dieser Datei) – dadurch der gewünschte "läuft ins Unendliche im Blur"-
   Effekt. */
.work-hero {
  position: relative;
  height: 100svh;
  width: 100%;
  overflow: hidden;
  background: #000;
}

.work-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

/* Klick auf das sichtbare Hintergrundvideo (oberer Bereich des Hero, wo
   keine Zeile drüberliegt) geht ins Vollbild – siehe
   initWorkCatalogVideoBg() in script.js. Cursor-Hinweis nur, solange
   wirklich ein Video läuft. */
.work-hero__bg:has(.work-hero__iframe.is-active) {
  cursor: pointer;
}

/* Gleicher Trick wie .hero .hero__video: Embed wird größer als die Box
   skaliert und mittig zugeschnitten, damit es randlos den ganzen
   Viewport füllt statt Letterboxing zu zeigen. */
.work-hero__iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100vw;
  height: 56.25vw; /* 16:9 */
  min-height: 100%;
  min-width: 177.78vh; /* 16:9 */
  max-width: none;
  transform: translate(-50%, -50%);
  pointer-events: none;
  border: 0;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.work-hero__iframe.is-active {
  opacity: 1;
}

.work-hero__gradient {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to top, rgba(0, 0, 0, 0.92) 0%, rgba(0, 0, 0, 0.55) 30%, rgba(0, 0, 0, 0.15) 55%, transparent 75%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.7) 0%, transparent 30%);
  pointer-events: none;
}

.work-hero__intro {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  padding-top: calc(var(--nav-height) + clamp(1.5rem, 4vw, 3rem));
  padding-inline: var(--edge-pad);
}

.work-catalog-wrap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding-inline: var(--edge-pad);
  padding-bottom: clamp(1.25rem, 3vw, 2.5rem);
}

.work-catalog-viewport {
  --work-row-h: clamp(38px, 4vw, 56px);
  position: relative;
  height: calc(var(--work-row-h) * 3.8);
  overflow: hidden;
}

.work-catalog {
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  border-top: 1px solid var(--line-color);
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* Padding oben/unten = (Viewport-Höhe - eine Zeilenhöhe) / 2, also
     (3.8 - 1) / 2 = 1.4 Zeilenhöhen. Dadurch startet Zeile 01 beim Laden
     schon mittig im Viewport (statt an der Oberkante vom Blur-Veil
     angeschnitten zu sein), und die letzte Zeile lässt sich genauso bis in
     die Mitte scrollen, statt am unteren Rand hängen zu bleiben. */
  padding-block: calc(var(--work-row-h) * 1.4);
}

.work-catalog::-webkit-scrollbar {
  display: none;
}

/* .work-row ist bewusst ein <div>, kein <a>: der Sound-Button braucht ein
   eigenständig klickbares <button>, und ein <button> darf laut HTML-Spec
   nicht in einem <a> verschachtelt sein. Stattdessen übernimmt
   .work-row__link als unsichtbarer, über die ganze Zeile gestreckter Link
   die Klick-/Tab-Navigation ("Stretched-Link"-Muster) und liegt im
   Stacking hinter dem Sound-Button, der per position:relative + z-index
   darüber liegt und so unabhängig klickbar bleibt. */
.work-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.25vw, 1rem);
  height: var(--work-row-h);
  border-bottom: 1px solid var(--line-color);
  color: var(--color-text);
}

.work-row__link {
  position: absolute;
  inset: 0;
  z-index: 0;
  text-decoration: none;
}

/* Hover-Highlight: der Titel der gehoverten/fokussierten Zeile wechselt in
   die Akzentfarbe (--color-highlight) statt die ganze Zeile zu dimmen –
   liest sich zusammen mit dem einblendenden Hintergrundvideo klarer als
   ein pauschales opacity-Dimming der ganzen Zeile. */
.work-row:hover .work-row__title,
.work-row:focus-within .work-row__title {
  color: var(--color-highlight);
}

.work-row__index {
  flex: 0 0 auto;
  width: 1.5rem;
  font-family: var(--font-base);
  font-weight: 700;
  font-size: 0.7rem;
  opacity: 0.5;
}

/* Sound-Button: standardmäßig läuft der Ton des Hintergrundvideos mit
   (siehe initWorkCatalogVideoBg() in script.js) – dieser Button pro Zeile
   ist die vom Nutzer jederzeit erreichbare Stumm/Ton-an-Kontrolle dazu
   (WCAG 1.4.2/2.2.2-Gedanke, gleiches Prinzip wie .hero__pause). Sitzt
   bewusst direkt hinter der Zahl. position:relative + z-index:1 hebt ihn
   über den gestreckten .work-row__link, damit er unabhängig klickbar
   bleibt statt die Zeilen-Navigation auszulösen. */
.work-row__sound {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text);
  opacity: 0.5;
  cursor: pointer;
  transition: opacity var(--transition), color var(--transition);
}

.work-row__sound:hover,
.work-row__sound:focus-visible {
  opacity: 1;
  color: var(--color-highlight);
}

.work-row__sound.is-muted {
  opacity: 0.35;
}

.work-row__sound-icon {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.work-row__sound-icon .work-row__sound-body {
  fill: currentColor;
  stroke: none;
}

.work-row__sound.is-muted .work-row__sound-wave {
  display: none;
}

.work-row__sound:not(.is-muted) .work-row__sound-mute {
  display: none;
}

/* Titel + Kategorie/Kunde stehen jetzt einzeilig zusammen ganz links
   (".work-row__heading"): "TITEL / Kategorie" (z. B. "On the Court /
   Personal Work"), durch einen schmalen Schrägstrich getrennt (siehe
   .work-row__category::before). Der gestapelte Zweizeiler aus der Vorversion
   sah laut Max nicht gut aus. Die Crew-Liste (".work-row__crew") füllt
   danach die mittlere, flexible Zone bis zur Rolle. */
.work-row__heading {
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 0.5em;
}

.work-row__title {
  max-width: 26vw;
  min-width: 0;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: clamp(0.7rem, 1.7vw, 1.3rem);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color var(--transition);
}

/* Kategorie/Kunde ist NIE abgeschnitten (Max' Vorgabe, dass dieser Teil
   nicht fehlen darf) – deshalb kein max-width/ellipsis wie beim Titel. Der
   Schrägstrich davor kommt per ::before, damit er nicht Teil des reinen
   Textinhalts ist (z. B. fürs title-Tooltip an anderer Stelle unnötig). */
.work-row__category {
  font-family: var(--font-base);
  font-weight: 700;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.75;
  white-space: nowrap;
}

.work-row__category::before {
  content: "/";
  margin-right: 0.5em;
  opacity: 0.5;
}

.work-row__crew {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-base);
  font-size: 0.64rem;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.work-row__role {
  flex: 0 0 auto;
  min-width: 8rem;
  margin-left: auto;
  text-align: right;
  font-family: var(--font-base);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.85;
  white-space: nowrap;
}

/* Blur-Veils oben/unten: gleiche backdrop-filter-Technik wie die Navbar
   (siehe .site-header beim Scrollen), zusätzlich per mask-image so
   ausgeblendet, dass die Unschärfe direkt an der Kante am stärksten ist
   und zur Zeilen-Mitte hin ausläuft ("ins Unendliche im Blur"). */
.work-catalog__veil {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  height: calc(var(--work-row-h) * 0.85);
  pointer-events: none;
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

.work-catalog__veil--top {
  top: 0;
  mask-image: linear-gradient(to bottom, black, transparent);
  -webkit-mask-image: linear-gradient(to bottom, black, transparent);
}

.work-catalog__veil--bottom {
  bottom: 0;
  mask-image: linear-gradient(to top, black, transparent);
  -webkit-mask-image: linear-gradient(to top, black, transparent);
}

@media (max-width: 700px) {
  .work-catalog-viewport {
    --work-row-h: 42px;
  }

  .work-row {
    gap: 0.4rem;
  }

  .work-row__title {
    font-size: 0.85rem;
    max-width: 60vw;
  }

  /* Zu wenig Platz für vier/fünf Spalten auf schmalen Viewports – Kategorie
     und Crew weichen zuerst, Rolle bleibt (wichtigste Zusatzinfo neben dem
     Titel). */
  .work-row__category,
  .work-row__crew {
    display: none;
  }

  .work-row__role {
    min-width: auto;
    font-size: 0.65rem;
  }
}

/* ============================================
   Clients-Sektion (Work-Seite): reine Textliste, keine Logos
   ============================================ */
.clients {
  padding-block: clamp(3rem, 8vw, 6rem);
  border-top: 1px solid var(--line-color);
}

.clients__list {
  margin-top: clamp(1.5rem, 4vw, 2.5rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  row-gap: 0.9em;
  text-align: center;
  font-family: var(--font-base);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: clamp(0.8rem, 1.5vw, 1.05rem);
  color: var(--color-text);
  opacity: 0.6;
}

.clients__item {
  white-space: nowrap;
}

.clients__item::after {
  content: "·";
  display: inline-block;
  margin-inline: 0.8em;
  opacity: 0.5;
}

.clients__item:last-child::after {
  content: none;
}
