/* PIXEL.SYNTAX — Prototyp-Layout.
   Tokens kommen unverändert aus tokens.css (Briefing §4) und werden hier
   NUR verwendet, nicht überschrieben.

   Abstände: nach dem Goldenen Schnitt (φ = 1.618) aus --sp-1 abgeleitet.
   --axis-gap ist der FIXE Abstand Nummer ↔ Headline; er definiert auch
   den Abstand der Kicker-Linie zu ihrem Text. */

:root {
  --sp-1: 14px;
  --sp-2: calc(var(--sp-1) * 1.618); /* ≈ 23px */
  --sp-3: calc(var(--sp-1) * 2.618); /* ≈ 37px */
  --sp-4: calc(var(--sp-1) * 4.236); /* ≈ 59px */
  --sp-5: calc(var(--sp-1) * 6.854); /* ≈ 96px */
  --axis-gap: 28px;

  /* Typo insgesamt +10 % (Override der tokens.css-Werte, die selbst
     unverändert bleiben) */
  --fs-hero: clamp(44px, 9.9vw, 114px);
  --fs-h1: clamp(40px, 6.6vw, 79px);
  --fs-h2: clamp(31px, 4.4vw, 53px);
  --fs-h3: clamp(22px, 2.64vw, 31px);
  --fs-body: clamp(18px, 1.32vw, 20px);
  --fs-small: 15.4px;
  --fs-label: 13.2px;

  /* Signatur-Rahmen der Seite: abgesetzte L-Ecken statt durchgehender
     Umrandung (wie um das o2-Layout im Case). Als Hintergrund-Layer
     einsetzbar: background: var(--corner), <fill>;  Ecke färben über --fc. */
  --fc: var(--accent); /* R12: alle Ecken blau */
  --corner-len: 15px;
  --corner:
    linear-gradient(var(--fc), var(--fc)) left top / var(--corner-len) 2px no-repeat,
    linear-gradient(var(--fc), var(--fc)) left top / 2px var(--corner-len) no-repeat,
    linear-gradient(var(--fc), var(--fc)) right top / var(--corner-len) 2px no-repeat,
    linear-gradient(var(--fc), var(--fc)) right top / 2px var(--corner-len) no-repeat,
    linear-gradient(var(--fc), var(--fc)) left bottom / var(--corner-len) 2px no-repeat,
    linear-gradient(var(--fc), var(--fc)) left bottom / 2px var(--corner-len) no-repeat,
    linear-gradient(var(--fc), var(--fc)) right bottom / var(--corner-len) 2px no-repeat,
    linear-gradient(var(--fc), var(--fc)) right bottom / 2px var(--corner-len) no-repeat;
}

html {
  /* Einheitlich reines Schwarz (Runde 10) */
  background: #000;
  /* Scrollbar-Platz immer reservieren → kein Sprung beim Galerie-Sperren */
  scrollbar-gutter: stable;
}
/* Galerie offen: Seite gegen Scrollen sperren UND die aktive Galerie als
   Vollbild-Overlay (position:fixed) über die Seite legen. Dadurch ist sie
   unabhängig von der Scroll-Position immer voll im Bild — der „↑ zurück
   zum Case"-Button ist stets erreichbar und Ziehen über den Fensterrand
   kann die Seite nicht wegscrollen (robuster als scrollTo + Scroll-Lock). */
html.gallery-open,
html.gallery-open body {
  overflow: hidden;
}
html.gallery-open .gallery:not([hidden]),
html.gallery-open .mosaik:not([hidden]) {
  position: fixed;
  inset: 0;
  z-index: 60;
  width: 100vw;
  height: 100vh;
  height: 100svh;
  margin-left: 0;
  background: var(--bg);
}
/* Durchgehender Maus-Parallax (js/parallax.js setzt --px/--py) */
.px {
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
  will-change: transform;
}

/* Scroll-Reveal (analog Lebenslauf): .rv = fade + Slide, .rv-fade = nur
   Opazität (für Parallax-Elemente, damit die Transforms nicht kollidieren) */
.rv {
  opacity: 0;
  transform: translateY(38px);
  transition: opacity 0.8s ease, transform 0.9s cubic-bezier(0.34, 1.45, 0.64, 1); /* R25: elastisch */
}
.rv.is-in { opacity: 1; transform: none; }
.rv-fade {
  opacity: 0;
  transition: opacity 0.85s ease;
}
.rv-fade.is-in { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .rv, .rv-fade { opacity: 1; transform: none; transition: none; }
}
body {
  overflow-x: clip;
}
::selection {
  background: var(--accent);
  color: var(--on-accent);
}

/* ---- A11y-Basics (Polish-Pass) ------------------------------------------ */

/* Tastatur-Fokus: sichtbarer Akzent-Ring auf ALLEN interaktiven Elementen.
   :focus-visible = nur bei Tastatur-Navigation, Maus-Klicks bleiben ruhig. */
:focus-visible {
  outline: 2px solid var(--accent, #4D7CFF);
  outline-offset: 2px;
  border-radius: 1px;
}
:focus:not(:focus-visible) {
  outline: none;
}

/* Formular-/Button-Elemente erben die Schrift NICHT automatisch — ohne
   diese Regel rendert der Browser dort Arial/Systemschrift. */
button,
input,
select,
textarea {
  font: inherit;
}

/* ---- Ladesequenz (Ball-Video) ------------------------------------------- */
.loader {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: #000;
  display: grid;
  place-items: center;
  cursor: pointer;
  opacity: 1;
  transition: opacity 0.6s ease;
}
.loader.is-done {
  opacity: 0;
  pointer-events: none;
}
.loader__video {
  width: 100%;
  height: 100%;
  object-fit: contain; /* Video ist 16:9 auf Schwarz — kein Beschnitt nötig */
}
@media (prefers-reduced-motion: reduce) {
  .loader {
    display: none;
  }
}

/* ---- Globale Ebenen ----------------------------------------------------- */

/* Dezente Scanline-Textur (Anmutung der Referenzseite). */
.scanlines {
  position: fixed;
  inset: 0;
  z-index: 90;
  pointer-events: none;
  background: repeating-linear-gradient(
    0deg,
    rgba(255, 255, 255, 0.02) 0 1px,
    transparent 1px 3px
  );
}

/* Matrix-Zeichenregen (R33): blaues Canvas-Overlay über dem Hintergrund.
   Textfelder/Videos werden in js/matrix.js aus dem Canvas gestanzt.
   Unter den Scanlines (90) und unter Menü/Lightbox (94+). */
.matrix-rain {
  position: fixed;
  inset: 0;
  z-index: 88;
  pointer-events: none;
  opacity: 0.5;
}

/* Scroll-Fortschritt oben. */
.progress {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  width: 0;
  background: var(--accent);
  z-index: 100;
}

/* .tag kommt aus tokens.css (bleibt unangetastet) — hier nur die
   Lesbarkeits-Untergrenze anheben (11 → 12px). */
.tag {
  font-size: 12px;
}

/* ---- Topbar + Navigation -------------------------------------------------- */

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 80;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--sp-3);
  padding: 16px var(--gutter);
  background: rgba(10, 11, 14, 0.72);
  background: rgba(0, 0, 0, 0.72); /* Fallback ohne color-mix */
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.topbar .label {
  color: var(--text);
}
.topbar__nav {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.nav-link {
  position: relative;
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--text);
  background: none;
  border: 0;
  padding: 6px 0;
  cursor: pointer;
  /* „Arbeit ▾" darf nie intern umbrechen (Caret rutschte auf Mobil
     in die zweite Zeile → Eintrag setzte sich optisch ab) */
  white-space: nowrap;
}
.topbar .label {
  white-space: nowrap;
}
/* unsichtbare Trefferfläche: hebt die Nav-Items auf ≥44px (Touch),
   ohne das Desktop-Layout zu verändern */
.nav-link::after {
  content: "";
  position: absolute;
  inset: -8px;
}
.nav-link:hover {
  color: var(--accent);
}
.nav-caret {
  color: var(--accent);
}
/* Mobil-Links (Home/Arbeitsproben/…) nur im Burger-Panel sichtbar */
.nav-mobile {
  display: none;
}
.nav-item--drop {
  position: relative;
}
.nav-drop {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 220px;
  display: none;
  flex-direction: column;
  background: var(--corner), var(--surface);
  padding: 8px 0;
}
.nav-item--drop:hover .nav-drop,
.nav-item--drop:focus-within .nav-drop {
  display: flex;
}
.nav-drop a {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  /* ≥44px Trefferfläche (Touch) */
  padding: 13px 16px;
}
.nav-drop a:hover {
  color: var(--accent);
  background: var(--surface-2);
}

/* ---- Scrollgeschwindigkeit (immer rechts unten) --------------------------- */

.speed-ctl {
  position: fixed;
  /* 10 % vom Rand eingezogen, Look wie „Weiter scrollen" */
  right: 10%;
  bottom: 10%;
  z-index: 85;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--text);
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(0, 0, 0, 0.85) 18%,
    rgba(0, 0, 0, 0.85) 82%,
    transparent 100%
  );
  border: 0;
  padding: 12px 22px 10px;
  cursor: pointer;
}
.speed-ctl:hover {
  color: var(--accent);
}
.speed-ctl:hover .speed-ctl__icon {
  stroke: var(--accent);
}
/* gleiche Icon-Größe wie das Scroll-Icon, beide am unteren Rand */
.speed-ctl__icon {
  width: 22px;
  height: 22px;
  display: block;
}

/* ---- Platzhalter-Markierungen (Briefing §0: sichtbar kennzeichnen) ------- */

.ph-badge {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px dashed var(--accent);
  padding: 7px 12px;
  background: rgba(0, 0, 0, 0.72); /* Fallback ohne color-mix */
  background: color-mix(in srgb, var(--bg) 72%, transparent);
}

.ph-slot {
  border: 1px dashed var(--line);
  padding: var(--sp-3) var(--gutter);
  display: grid;
  gap: var(--sp-1);
  justify-items: start;
}
.ph-slot p {
  color: var(--muted);
  font-size: var(--fs-small);
}

/* ---- Hero ----------------------------------------------------------------
   Vollbild: Hintergrund-Video, Figur links, Text rechts, „Intro"-CTA.
   3-stufiger Maus-Parallax (Haptik wie About me). */

.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.hero__stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* gemeinsame Vollflächen-Ebenen (Video + Figur) */
.hero__video,
.hero__me {
  position: absolute;
  /* etwas größer als der Viewport, damit Parallax keine Kanten zeigt */
  inset: -5%;
  width: 110%;
  height: 110%;
  object-fit: cover;
  will-change: transform;
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
}
.hero__video {
  z-index: 0;
  object-position: center;
}
.hero__me {
  z-index: 1;
  /* Figur sitzt im linken Drittel — Oberkante bleibt UNTER der fixen
     Topbar (Kopf darf nie von der Navigation überdeckt werden) */
  top: clamp(60px, 8vh, 110px);
  height: calc(105% - clamp(60px, 8vh, 110px));
  object-fit: contain;
  object-position: left bottom;
}
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  /* nach rechts und unten leicht abdunkeln, damit der Text trägt */
  background:
    linear-gradient(90deg, rgba(10, 10, 10, 0) 38%, rgba(10, 10, 10, 0.55) 100%),
    linear-gradient(180deg, rgba(10, 10, 10, 0) 60%, rgba(10, 10, 10, 0.7) 100%);
  pointer-events: none;
}

.hero__content {
  position: absolute;
  z-index: 3;
  /* rechts neben der Figur, vertikal mittig — Block sitzt bewusst weiter
     Richtung Bildmitte (Nutzerwunsch R12) */
  /* rechtsbündiger Textblock */
  right: clamp(calc(var(--gutter) + 60px), 16vw, 320px);
  left: 42%;
  top: 50%;
  transform: translate3d(var(--px, 0px), calc(-50% + var(--py, 0px)), 0);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  will-change: transform;
}
.hero__name {
  font-size: var(--fs-hero);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}
.hero__name .glitch::before,
.hero__name .glitch::after {
  background: transparent; /* über Video: kein Box-Hintergrund hinterm Glitch */
}
/* „Pixel meets Syntax" — eigene Hierarchie-Stufe zwischen Name und Tagline:
   blau, Mittelgröße (fs-h2). */
.hero__slogan {
  margin-top: var(--sp-2);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-h2);
  line-height: 1.05;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--accent);
}
/* R41: zweite Zeile — eine Hierarchiestufe kleiner, weiß, deutlich abgesetzt */
.hero__slogan2 {
  margin-top: clamp(30px, 4vh, 56px);
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-h3);
  line-height: 1.2;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text);
}
/* „Design, Motion & AI" — dünner Mono-Schnitt (300), weiß, kleinste Stufe */
@media (max-width: 720px) {
  /* Mobil-Hero = EIN Viewport, als Flex-Spalte OHNE Positions-Magie:
     kompakter Textblock oben, die Figur füllt LÜCKENLOS den ganzen
     Rest bis zum unteren Rand (kein toter Bildraum, kein Scrollen). */
  .hero {
    height: 100vh;
    height: 100svh;
  }
  .hero__stage {
    display: flex;
    flex-direction: column;
  }
  .hero__content {
    position: static;
    order: 1;
    transform: none;
    align-items: flex-end;
    text-align: right;
    /* rechts +6px: bündig mit dem Burger-ICON (Button hat 6px Innenabstand) */
    padding: clamp(76px, 11vh, 120px) calc(var(--gutter) + 6px) 0 var(--gutter);
  }
  /* Typo neu umbrochen/skaliert, damit der Block kompakt harmoniert */
  .hero__name {
    font-size: clamp(38px, 11vw, 52px);
  }
  .hero__slogan {
    margin-top: 10px;
    font-size: clamp(17px, 4.6vw, 21px);
  }
  .hero__slogan2 {
    font-size: clamp(13px, 3.6vw, 16px);
  }
  .hero__me {
    position: static;
    order: 2;
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    height: auto;
    margin-top: var(--sp-2);
    /* Quellbild = freigestelltes Brustporträt (Figur ~4–55 % der Breite,
       Kopf oben). Kopf oben VERANKERN (y 0) + Fenster auf die Figur
       zentrieren → Manuel ist immer komplett im Bild, nie überzoomt
       abgeschnitten. Höhe deckeln, damit der Kopf nicht formatfüllend wird. */
    object-fit: cover;
    /* mehr von der linken Bildseite abschneiden (Nutzerwunsch R21) */
    object-position: 34% 0%;
    /* R24: näher an den Text (kleinerer Mindestabstand) und KEIN
       Höhen-Deckel mehr — die Figur füllt bis zur Unterkante der Sektion
       (vorher endete die Bildbox über dem Rand = „unten abgeschnitten"). */
    margin-top: clamp(10px, 1.8vh, 28px);
  }
  .hero__scrim {
    background: linear-gradient(180deg, rgba(10, 10, 10, 0.5) 0%, rgba(10, 10, 10, 0) 30%, rgba(10, 10, 10, 0) 70%, rgba(10, 10, 10, 0.55) 100%);
  }
}

/* ---- Hero-Aktionen (drei Buttons) — R48 -------------------------------- */
.hero__actions {
  margin-top: clamp(20px, 3vh, 40px);
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end; /* rechtsbündig wie der Textblock */
  gap: clamp(10px, 1vw, 16px);
}
.hero__btn {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(14px, 1.15vw, 17px);
  letter-spacing: var(--ls-display);
  text-transform: uppercase;
  padding: clamp(12px, 1.5vh, 16px) clamp(20px, 1.8vw, 30px);
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
}
.hero__btn--primary {
  background: var(--accent);
  color: var(--on-accent);
  border: 1px solid var(--accent);
}
.hero__btn--primary:hover {
  background: transparent;
  color: var(--accent);
}
.hero__btn--ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--line);
}
.hero__btn--ghost:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* ---- Intro-Video-Bühne = Hintergrund von Sektion 02 (R49) -------------- */
.intro { position: relative; overflow: hidden; }
.intro__text { position: relative; z-index: 1; }
/* Bühne deckt 02 ab, sobald das Intro läuft. Höhe = EXAKT 1 Viewport
   (nicht die volle Sektionshöhe inkl. Padding) — so bleibt die Video-
   Skalierung beim Crossfade-Wechsel fixed→absolute identisch (kein Sprung). */
.intro__stage {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  height: 100svh;
  z-index: 2; /* über dem echten 02-Text */
  display: none;
  align-items: center;
  background: #000;
}
.intro--on .intro__stage { display: flex; }
.intro__stage-video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover; /* Video ist selbst schwarz gerahmt → randlos */
}
/* Lesbarkeits-Scrim für den Willkommenstext (nur wenn Text sichtbar) */
.intro__stage-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.55) 100%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 42%);
  opacity: 0;
  transition: opacity 2s ease;
}
/* Willkommenstext legt sich in ~2 s über das Video */
.intro__welcome {
  position: relative;
  z-index: 2;
  width: 100%;
  opacity: 0;
  transition: opacity 2s ease;
}
.intro--welcome .intro__stage-scrim,
.intro--welcome .intro__welcome { opacity: 1; }
.intro__stage-skip {
  position: absolute;
  z-index: 3;
  /* Safe-Area einrechnen, damit die Browser-Leiste/Notch den Button nicht
     verdeckt (greift nur im Inline-Fallback; Mobil nutzt nativen Vollbild) */
  top: calc(env(safe-area-inset-top, 0px) + clamp(16px, 3vh, 28px));
  right: calc(env(safe-area-inset-right, 0px) + clamp(16px, 3vw, 32px));
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.25);
  padding: 8px 16px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.intro__stage-skip:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, 0.6);
}
.intro--welcome .intro__stage-skip { display: none; }
/* Topbar während des aktiven Playbacks ausblenden (kommt mit dem Text zurück) */
.topbar { transition: opacity 0.4s ease; }
.intro-playing .topbar { opacity: 0; pointer-events: none; }
/* R50: MOBIL/Hochformat — Bühne FIXED über dem Viewport (echtes Vollbild,
   unabhängig von der dynamischen Adressleiste; deckt auch die Topbar).
   Am Ende blendet die Bühne aus → normales 02 (kein Freeze auf Mobil). */
@media (orientation: portrait) {
  .intro__stage {
    position: fixed;
    z-index: 200;
  }
}
@media (prefers-reduced-motion: reduce) {
  .intro__stage-scrim, .intro__welcome { transition: none; }
}

.scroll-cta {
  position: absolute;
  left: 50%;
  bottom: 22px;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  transition: opacity 0.4s ease;
}
.scroll-cta.is-off {
  opacity: 0;
}
.scroll-cta__label {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: #8A8A8A;
}
.scroll-cta__line {
  width: 1px;
  height: 34px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.scroll-cta__line::after {
  content: "";
  position: absolute;
  left: 0;
  top: -50%;
  width: 100%;
  height: 50%;
  background: var(--accent);
  animation: cta-drop 1.8s ease-in-out infinite;
}
@keyframes cta-drop {
  0% { top: -50%; }
  100% { top: 110%; }
}

/* ---- Fullscreen-Panels (alle Textsektionen) -------------------------------
   Jeder Abschnitt füllt den Viewport; der Textblock sitzt im LINKEN
   UNTEREN Drittel. Nummer = gleiche Höhe wie Headline; --axis-gap (fix)
   trennt Nummer und Headline, alle Absätze starten auf der Headline-Achse. */

/* Kicker: senkrechte Linie — Abstand zur Schrift = --axis-gap (wie 03 ↔
   Headline), Linie bündig mit der linken Kante des Absatzes davor. */
.kicker {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  line-height: 1.3;
  color: var(--accent);
  max-width: 44ch;
  border-left: 2px solid var(--accent);
  padding-left: var(--axis-gap);
  margin-left: -2px;
}

/* PLATZHALTER-Sequenz je Panel: schiebt sich beim Scrollen leicht mit. */
/* Text-Einflug: von unten links, feste Dauer (gleiches Pacing überall,
   unabhängig von der Scrollgeschwindigkeit, < 2 s). */
/* Kontakt: kompakt — kein Vollbild-Panel mehr (zwischen Techstack und
   „Auf den Punkt" klaffte sonst ein fast leerer Viewport) */
.kontakt-sub {
  color: var(--muted);
  max-width: 52ch;
}

/* 07 Kontakt: beide Buttons GLEICH GROSS (gleiche Breite, zentrierter Text) */
.kontakt-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-1);
  max-width: 640px;
  margin-top: var(--sp-2);
}
.kontakt-actions .btn {
  width: 100%;
  justify-content: center;
  text-align: center;
}
@media (max-width: 560px) {
  .kontakt-actions {
    grid-template-columns: 1fr;
  }
}

/* Footer: Kontaktzeile mit Mail (nur hier ganz unten) + Impressum */
.footer {
  border-top: var(--border) solid var(--line);
  padding: 26px 0;
}
.footer .wrap {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 24px;
  justify-content: space-between;
  align-items: center;
}
.footer .label a {
  color: var(--text);
  border-bottom: 2px solid var(--accent);
  padding-bottom: 1px;
}
.footer__legal {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--muted);
}
.footer__legal:hover {
  color: var(--accent);
}

/* ---- 04 · Lebenslauf: Stationen + Ausbildung ---------------------------- */
.cv__head {
  display: grid;
  gap: var(--sp-2);
  padding-bottom: var(--sp-4);
}
.cv__head .section-num {
  font-size: var(--fs-h2);
  line-height: 0.95;
}
.cv__head h2 {
  word-spacing: -0.5ch;
}
.cv__sub {
  color: var(--muted);
  max-width: 52ch;
}
/* Lebenslauf-Sektion auf reines Schwarz → das Hintergrund-Video hebt sich
   nicht ab (wie beim o2-Maschinenraum). overflow-hidden: der über die rechte
   Kante ragende Teil des Videos wird sauber abgeschnitten (kein H-Scroll). */
#lebenslauf { background: #000; overflow: hidden; }
.cv__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--sp-4) var(--sp-5);
  /* stretch: die kürzere Ausbildungs-Spalte wird auf die volle Höhe der
     Stationen-Spalte gezogen → „unten bündig mit dem untersten Eintrag". */
  align-items: stretch;
}
.cv__col { position: relative; }
/* Stationen-Text liegt UEBER dem Lebenslauf-Video (sonst graute das
   0.5-opacity-Video spaeter im DOM z.B. "...WORKFLOW" aus) */
.cv__col--jobs { z-index: 2; }
/* Ausbildungs-Spalte: Ausbildung oben, Fortbildungen ans untere Ende,
   dazwischen läuft der Lebenslauf-Loop im Hintergrund. */
.cv__col--edu {
  display: flex;
  flex-direction: column;
}
.cv__col--edu > * { position: relative; z-index: 1; }
.cv__col--edu .cv__colhead--2 { margin-top: auto; } /* Fortbildungen nach unten */
/* Hintergrund-Video: unten bündig mit dem untersten Eintrag, hinter dem Text,
   nach oben weich auslaufend (Text bleibt lesbar). */
.cv__bg {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 0;
  /* js/main.js (fitCvVideo) setzt top/height/width/left: quadratische Box
     (Höhe = Lothar-von-Faber → Distart), Mitte auf der rechten Kante der
     Ausbildungsspalte. contain = volles Video, NICHT beschnitten. */
  object-fit: contain;
  opacity: 0.5;
  pointer-events: none;
}
.cv__colhead {
  display: block;
  color: var(--text);
  padding-bottom: var(--sp-2);
  border-bottom: var(--border) solid var(--line);
  margin-bottom: var(--sp-3);
}
/* zweiter Block (Fortbildungen) in der Ausbildungs-Spalte: Luft nach oben */
.cv__colhead--2 {
  margin-top: var(--sp-4);
}
.cv__list {
  list-style: none;
  display: grid;
  gap: var(--sp-3);
}
/* Eintrag: Zeitachse links (Akzentlinie + Punkt), Inhalt rechts.
   Fadet beim Scrollen gestaffelt ein (.reveal + Staffel-Delay). */
.cv-item {
  position: relative;
  padding-left: var(--axis-gap);
  border-left: 2px solid var(--line);
  display: grid;
  gap: 6px;
}
.cv-item.reveal {
  transition-duration: 0.7s;
}
.cv-item:nth-child(2) { transition-delay: 0.08s; }
.cv-item:nth-child(3) { transition-delay: 0.16s; }
.cv-item:nth-child(4) { transition-delay: 0.24s; }
.cv-item:nth-child(5) { transition-delay: 0.32s; }
.cv-item:nth-child(6) { transition-delay: 0.40s; }
.cv-item::before {
  content: "";
  position: absolute;
  left: -5px;
  top: 2px; /* R25: bündig mit der Oberkante der größeren Jahreszahl */
  width: 8px;
  height: 8px;
  background: var(--accent);
}
.cv-item__time {
  font-family: var(--font-display);
  /* R25: eine Hierarchie größer, aber THIN (300); oben bündig mit dem
     blauen Block (line-height 1 + Marker-Top angepasst) */
  font-size: var(--fs-h3);
  font-weight: 300;
  line-height: 1;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--accent);
}
.cv-item__role {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: var(--ls-display);
  color: var(--text);
}
.cv-item__org {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  color: var(--muted);
}
.cv-item p {
  font-size: var(--fs-small);
  color: var(--text);
  max-width: 52ch;
}

@media (max-width: 900px) {
  .cv__grid {
    grid-template-columns: 1fr;
    align-items: start;
  }
  /* einspaltig: kein Bündig-Trick, Fortbildungen normal, Video als
     schmaler Block statt Vollhöhen-Hintergrund. */
  .cv__col--edu { display: block; }
  .cv__col--edu .cv__colhead--2 { margin-top: var(--sp-4); }
  .cv__bg {
    position: static;
    width: min(100%, 320px);
    margin-top: var(--sp-3);
    opacity: 0.45;
    -webkit-mask-image: none;
            mask-image: none;
  }
}

/* ---- 05 · „Schon gebaut für" + Werkzeuge: zwei Laufbänder --------------- */
/* R43: Kopf-Blöcke mittig — Sektionsnummer + Headline zentriert */
.stack__head,
.proben__head,
.cv__head {
  justify-items: center;
  text-align: center;
}
.intro__text > .section-num,
.intro__text > h2 {
  justify-self: center;
}
.stack__head {
  display: grid;
  gap: var(--sp-2);
  padding-bottom: var(--sp-4);
}
.stack__head .section-num {
  font-size: var(--fs-h2);
  line-height: 0.95;
}
.stack__head h2 {
  word-spacing: -0.5ch;
}
/* 3D-Marquee (R34, Referenz 21st.dev „3d-marquee"): perspektivisch
   gekippte Fläche, 4 Spalten laufen gegenläufig vertikal durch.
   Nahtloser Loop: Karten-Satz doppelt, Abstände als margin-bottom
   (NICHT gap — sonst stimmt translateY(−50 %) um eine halbe Lücke nicht). */
.m3d {
  --m3d-gap: clamp(28px, 3.2vh, 52px);
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  height: clamp(520px, 74vh, 900px);
  overflow: hidden;
  /* R45: offscreen KOMPLETT vom Rendering ausnehmen (GPU-Schutz) */
  content-visibility: auto;
  contain-intrinsic-size: auto 700px;
  /* weiche Kanten oben/unten */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 10%, #000 90%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 10%, #000 90%, transparent 100%);
}
/* ISOMETRISCH (wie die Referenz): KEIN perspective — dadurch bleiben
   ALLE Kacheln gleich groß, nichts läuft nach hinten winzig zusammen. */
.m3d__scene {
  position: absolute;
  inset: 0;
}
/* Unschärfe zu den Rändern (gleicher Look wie .gallery__blur der
   Rakete-Galerie): Mitte scharf, außen weich verlaufend verschwommen */
.m3d::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  /* R45: 12→8px — Backdrop-Blur über bewegtem Inhalt ist GPU-teuer */
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-mask-image: radial-gradient(
    ellipse 72% 64% at 50% 50%,
    transparent 46%,
    rgba(0, 0, 0, 0.55) 74%,
    #000 96%
  );
  mask-image: radial-gradient(
    ellipse 72% 64% at 50% 50%,
    transparent 46%,
    rgba(0, 0, 0, 0.55) 74%,
    #000 96%
  );
}
/* Platte ist VIEL größer als die Bühne → explizit um die eigene Mitte
   zentrieren (translate −50 %/−50 % VOR den Rotationen; Grid-Zentrierung
   versagt bei übergroßen, gedrehten Elementen). */
.m3d__plane {
  position: absolute;
  left: 50%;
  top: 50%;
  display: flex;
  gap: var(--m3d-gap);
  transform: translate(-50%, -50%) rotateX(55deg) rotateZ(-45deg);
  /* 3D-Raum bis zu den Karten durchreichen — nur so wird der elastische
     Hover-Lift (translateZ in m3d.js) als Anheben sichtbar */
  transform-style: preserve-3d;
}
.m3d__col {
  display: flex;
  flex-direction: column;
  transform-style: preserve-3d;
  animation: m3d-up var(--dur, 44s) linear infinite;
  /* R45: KEIN will-change mehr — zwang die ~6.000px-Spalten dauerhaft in
     eigene GPU-Texturen (Grafikspeicher lief voll → Mac-Absturz) */
}
/* R45: Bühne außerhalb des Bilds → Animationen stehen (m3d.js setzt is-off) */
.m3d.is-off .m3d__col {
  animation-play-state: paused;
}
.m3d__col--down {
  animation-name: m3d-down;
}
.m3d:hover .m3d__col {
  animation-play-state: paused;
}
/* ein Satz = 1/3 der Spalte → nahtlos */
@keyframes m3d-up {
  from { transform: translateY(0); }
  to { transform: translateY(-33.333%); }
}
@keyframes m3d-down {
  from { transform: translateY(-33.333%); }
  to { transform: translateY(0); }
}
/* Karten = große Querformat-„Screens" (Referenz-Look): 16:10, leicht
   gerundet, mit dezentem Blau-Schimmer; gestrichelte Rasterlinien in den
   Lücken entstehen über die outline (halber Kachelabstand nach außen). */
.m3d__card {
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(340px, 27vw, 560px);
  aspect-ratio: 16 / 10;
  padding: clamp(20px, 2.4vh, 36px);
  margin-bottom: var(--m3d-gap);
  /* softer, MATTER Blauton (Akzent in die Fläche gemischt, kein Glanz),
     zu 75 % transparent (2× halbiert) — Schrift bleibt voll deckend */
  background: rgba(31, 39, 61, 0.25); /* Fallback ohne color-mix */
  background: linear-gradient(
    160deg,
    color-mix(in srgb, color-mix(in srgb, var(--accent) 22%, var(--surface)) 25%, transparent) 0%,
    color-mix(in srgb, color-mix(in srgb, var(--accent) 12%, var(--surface)) 25%, transparent) 100%
  );
  border: 1px solid rgba(110, 140, 255, 0.4); /* Fallback ohne color-mix */
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--line));
  border-radius: 12px;
  outline: 1px dashed rgba(255, 255, 255, 0.09);
  outline-offset: calc(var(--m3d-gap) / 2 - 2px);
  /* R45: box-shadow entfernt — auf 150 Karten teuer zu rastern (GPU) */
  text-align: center;
  /* transform gehört dem elastischen Lift (m3d.js) — NICHT transitionieren,
     sonst kämpft die CSS-Transition gegen die Feder-Animation */
  transition: border-color 0.25s ease;
}
.m3d__card:hover {
  border-color: var(--accent);
}
/* Kunden: verlinkte Wortmarken, groß wie auf einem Screen */
.m3d__card--client {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(26px, 2.3vw, 44px);
  line-height: 1.15;
  text-transform: uppercase;
  letter-spacing: var(--ls-display);
  color: var(--text);
}
a.m3d__card--client:hover {
  color: var(--accent);
}
/* Techstack: bestehende .tool-Optik, auf Screen-Größe skaliert */
.m3d__card--tool .tool {
  font-size: clamp(20px, 1.7vw, 32px);
  white-space: normal;
}
.m3d__card--tool { cursor: pointer; } /* R46: Sektion 06 in 05 fusioniert */

/* R42: Techstack-Liste — Overlay über der Fläche, alle Programme */
.m3d__list {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.82); /* Fallback ohne color-mix */
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.m3d__list.is-open { opacity: 1; }
.m3d__list[hidden] { display: none; }
.m3d__list-inner {
  position: relative;
  width: min(88vw, 640px);
  padding: clamp(28px, 4vw, 52px);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: 0 0 40px rgba(77, 124, 255, 0.14);
}
.m3d__list-kicker {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.m3d__list-inner h3 {
  margin: 6px 0 clamp(18px, 2.4vh, 30px);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(24px, 3vw, 40px);
  text-transform: uppercase;
  letter-spacing: var(--ls-display);
  color: var(--text);
}
.m3d__list-inner ul {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px clamp(20px, 3vw, 44px);
}
.m3d__list-inner li {
  font-family: var(--font-display);
  font-size: clamp(15px, 1.3vw, 19px);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text);
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.m3d__list-x {
  position: absolute;
  top: 14px;
  right: 16px;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.m3d__list-x:hover { color: var(--text); }
@media (max-width: 720px) {
  .m3d__list-inner ul { grid-template-columns: 1fr; }
}

/* Techstack-Band: Programm-Marken (Zwei-Buchstaben-Logos in
   Originalfarben, radius 0) + Name */
.tool {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(18px, 2.4vw, 32px);
  line-height: 1.1;
  text-transform: uppercase;
  letter-spacing: var(--ls-display);
  color: var(--text);
  white-space: nowrap;
}
.tool__mark {
  font-style: normal;
  display: grid;
  place-items: center;
  width: 1.9em;
  height: 1.9em;
  font-weight: 700;
  font-size: 0.62em;
  letter-spacing: 0;
  text-transform: none;
  border: 1px solid rgba(255, 255, 255, 0.14);
}
.tool__mark--id { background: #49021f; color: #ff3366; }
.tool__mark--ps { background: #001e36; color: #31a8ff; }
.tool__mark--ai { background: #330000; color: #ff9a00; }
.tool__mark--ae { background: #00005b; color: #9999ff; }
.tool__mark--pr { background: #00005b; color: #ea77ff; }
.tool__mark--jira { background: #1868DB; color: #ffffff; }
.tool__mark--ac { background: #2e0500; color: #ff5b4d; }
.tool__mark--ic { background: #40072a; color: #ff5fb0; }
.tool__mark--claude { background: #2a1a12; color: #d97757; }
/* KI-Video-Tools (Seedance/Kling/Veo) — einheitliche Akzent-Marke */
.tool__mark--ai2 { background: #0e1626; color: #6ea8ff; }
/* KI-Workflows: der mh-ball als Marke (looped Video, quadratisch beschnitten) */
.tool__mark--ball {
  overflow: hidden;
  border-color: var(--accent);
}
.tool__mark--ball video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}
/* Echte Logo-Dateien (C4D, one2edit, n8n) */
.tool__mark--img {
  overflow: hidden;
}
.tool__mark--img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (prefers-reduced-motion: reduce) {
  .m3d__col {
    animation: none;
  }
}

/* ---- 07 · „Into the Void"-Vortex (R35, Referenz 21st.dev) -------------- */
/* Vollflächige Wirbel-Sektion: Canvas hinter dem Inhalt, KONTAKT MITTIG
   im blauen Halo; Buttons bleiben klickbar. */
#kontakt {
  position: relative;
  overflow: hidden;
  min-height: 100vh; /* Fallback für Browser ohne svh */
  min-height: 100svh;
  display: grid;
  align-content: center;
  justify-items: center;
}
#kontakt > .wrap {
  position: relative;
  z-index: 1;
  text-align: center;
}
/* dezenter blauer Halo hinter dem Kontakt (statisch, wie die Referenz) */
#kontakt::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(44vw, 540px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    circle,
    rgba(77, 124, 255, 0.22) 0%,
    rgba(77, 124, 255, 0.09) 40%,
    transparent 70%
  );
  filter: blur(8px);
  z-index: 0;
  pointer-events: none;
}
#kontakt .stack__head {
  justify-items: center;
  padding-bottom: var(--sp-2);
}
/* R39: ZWEI Buttons mit „oder" dazwischen — größer + fetter */
#kontakt .kontakt-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 2vw, 30px);
  max-width: none;
  margin-inline: auto;
}
/* R40: Buttons transparent, WEISSER Text, BLAUE Eckwinkel (Site-Look) */
#kontakt .btn {
  position: relative;
  font-size: clamp(19px, 1.7vw, 28px);
  font-weight: 700;
  padding: clamp(18px, 2.2vh, 26px) clamp(30px, 3vw, 54px);
  background: transparent;
  border: 0;
  color: var(--text);
}
#kontakt .btn::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  --bl: 20px; /* Ecklänge */
  background:
    linear-gradient(var(--accent), var(--accent)) left top / var(--bl) 3px no-repeat,
    linear-gradient(var(--accent), var(--accent)) left top / 3px var(--bl) no-repeat,
    linear-gradient(var(--accent), var(--accent)) right top / var(--bl) 3px no-repeat,
    linear-gradient(var(--accent), var(--accent)) right top / 3px var(--bl) no-repeat,
    linear-gradient(var(--accent), var(--accent)) left bottom / var(--bl) 3px no-repeat,
    linear-gradient(var(--accent), var(--accent)) left bottom / 3px var(--bl) no-repeat,
    linear-gradient(var(--accent), var(--accent)) right bottom / var(--bl) 3px no-repeat,
    linear-gradient(var(--accent), var(--accent)) right bottom / 3px var(--bl) no-repeat;
}
#kontakt .btn:hover {
  color: var(--accent);
  background: transparent;
}
.kontakt-oder {
  font-family: var(--font-display);
  font-size: clamp(15px, 1.2vw, 20px);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text); /* R40: weiß */
}
@media (max-width: 720px) {
  #kontakt .kontakt-actions {
    flex-direction: column;
  }
}
.vortex {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

/* ---- Galerie (phantom.land-Prinzip): unendliche, ziehbare Fläche ----------
   Kacheln werden per JS absolut positioniert und beim Ziehen/Scrollen
   endlos „herumgewickelt" (Wrap). Drag = erkunden, Mouseover = abspielen,
   Klick = in die Mitte holen + auf 60 % der Fensterbreite vergrößern. */

.section--gallery {
  padding-block: 0;
}

.gallery[hidden] {
  display: none;
}

/* Galerie-Wechsel: Ansicht zoomt nach außen weg bzw. kommt von außen
   herein (Klasse .viewswap = Außen-Zustand; Übergang beim Entfernen). */
.gallery,
.mosaik,
.proben {
  transition: transform 0.45s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.45s ease;
}
.gallery.viewswap,
.mosaik.viewswap,
.proben.viewswap {
  transform: scale(1.16);
  opacity: 0;
  pointer-events: none;
}

/* ---- 02 · Hallo / Intro (Willkommen im Maschinenraum) ------------------- */
.intro {
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: var(--space-section);
}
/* Kopf-Raster vereinheitlicht (wie 06 Techstack): Nummer ÜBER der Headline */
.intro__text {
  display: grid;
  gap: var(--sp-2);
  max-width: clamp(340px, 62vw, 780px);
}
.intro__text > .section-num {
  font-size: var(--fs-h2);
  line-height: 0.95;
}
.intro__text > h2 {
  word-spacing: -0.5ch;
}
.intro__body {
  margin-top: var(--sp-2);
  display: grid;
  gap: var(--sp-2);
  color: var(--muted);
  font-size: var(--fs-body);
  line-height: 1.65;
}
.intro__body p {
  max-width: 64ch;
}

/* ---- Arbeitsproben-Übersicht (Zwischenschritt vor den Galerien) --------- */
.proben {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  /* Kopf hängt oben im Video, Kacheln ganz unten */
  justify-content: space-between;
  gap: var(--sp-4);
  padding-block: clamp(92px, 13vh, 150px) var(--sp-5);
}
.proben[hidden] {
  display: none;
}
/* Ball-Video als VOLLBILD-Hintergrund der Sektion (cover). Kopf hängt oben
   im Video, Kacheln sitzen unten und dürfen den Ball überlappen. */
.proben__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  opacity: 0.6;
  mix-blend-mode: screen;
  pointer-events: none;
  will-change: transform;
  transform: translate3d(var(--px, 0px), var(--py, 0px), 0);
}
.proben__head,
.proben__grid {
  position: relative;
  z-index: 1;
}
/* Kopf-Raster vereinheitlicht (wie 06 Techstack): Nummer ÜBER der Headline.
   width:100%: als Flex-Kind von .proben schrumpfte die .wrap-Box sonst auf
   Inhaltsbreite und die auto-Margins ZENTRIERTEN sie (fiel aus dem Raster). */
.proben__head {
  display: grid;
  gap: var(--sp-2);
  width: 100%;
}
.proben__head .section-num {
  font-size: var(--fs-h2);
  line-height: 0.95;
}
.proben__head h2 {
  word-spacing: -0.5ch;
}
.proben__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  /* Gap > 24px: Platz fuer die abgesetzten 12px-Ecken beider Nachbarn */
  gap: clamp(56px, 4.5vw, 80px);
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.probe {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  min-height: clamp(120px, 18vh, 200px);
  padding: clamp(18px, 2vw, 28px);
  /* Kachelfläche 50 % transparent; Ecken abgesetzt via ::before (R16) */
  background: rgba(18, 20, 26, 0.5);
  background: rgba(21, 21, 21, 0.5); /* Fallback ohne color-mix */
  background: color-mix(in srgb, var(--surface) 50%, transparent);
  color: var(--text);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.2s ease;
  /* Kachel = Container: die Titel-Typo skaliert mit der Kachelbreite */
  container-type: inline-size;
}
/* Abgesetzte Ecken (12px außerhalb, 2px Akzent) — wie alle Medienrahmen */
.probe::before {
  content: "";
  position: absolute;
  inset: -24px;
  pointer-events: none;
  --fc: var(--accent);
  background: linear-gradient(var(--fc), var(--fc)) left top / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) left top / 4px 32px,
    linear-gradient(var(--fc), var(--fc)) right top / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) right top / 4px 32px,
    linear-gradient(var(--fc), var(--fc)) left bottom / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) left bottom / 4px 32px,
    linear-gradient(var(--fc), var(--fc)) right bottom / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) right bottom / 4px 32px;
  background-repeat: no-repeat;
}

/* Logo-Kachel: weißes Marken-Logo unten links, „Case ansehen →" darunter */
.probe--logo .probe__logos {
  margin-top: auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(16px, 2.6vw, 34px);
}
.probe--logo .probe__logos img {
  width: auto;
  max-width: 100%;
  object-fit: contain;
}
/* Rakete-Logo (Standalone) groß; o2/Brodos als Paar etwas kompakter,
   damit beide nebeneinander in die Kachel passen */
.probe--logo .probe__logos > img {
  height: clamp(52px, 8vw, 96px);
}
.probe__logo--o2 { height: clamp(46px, 6.4vw, 80px) !important; }
.probe__logo--brodos { height: clamp(30px, 4.2vw, 52px) !important; }
.probe:hover:not(:disabled) {
  --fc: var(--accent);
  transform: translateY(-2px);
}
.probe__title {
  margin-top: auto;
  font-family: var(--font-display);
  font-weight: 700;
  /* passt sich der Kachel an: skaliert mit der Kachelbreite (cqw), sodass
     auch das längste Wort („Verschiedenes") NIE die Kante erreicht */
  font-size: clamp(16px, 2vw, 30px); /* Fallback ohne cqw */
  font-size: clamp(16px, 8.6cqw, 30px);
  line-height: 1.2;
  max-width: 100%;
  text-transform: uppercase;
  letter-spacing: var(--ls-display);
}
.probe__cta {
  font-family: var(--font-display);
  /* „Case ansehen" 20 % größer */
  font-size: calc(var(--fs-label) * 1.2);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.probe--soon {
  cursor: default;
}
.probe--soon .probe__cta {
  color: var(--muted);
}

/* Mobil: Übersicht kompakt — kein Vollbild-Zentrieren (zu viel Luft
   über/unter den Kacheln), flachere Kacheln */
@media (max-width: 720px) {
  .proben {
    min-height: 0;
    justify-content: flex-start;
    gap: var(--sp-3);
    padding-block: clamp(84px, 12vh, 140px) var(--sp-4);
  }
  .probe {
    min-height: clamp(110px, 16vh, 160px);
    gap: var(--sp-1);
  }
}

/* ---- Mosaik-Galerien (o2, Verschiedenes): ziehbare Fläche aus
   gemischten Formaten + Videos — Look & Feel wie die Rakete-Galerie ------ */
.mosaik {
  position: relative;
  height: 100vh;
  height: 100svh;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  background: var(--bg);
  border-top: var(--border) solid var(--line);
  border-bottom: var(--border) solid var(--line);
}
.mosaik[hidden] {
  display: none;
}
.mosaik.is-dragging {
  cursor: grabbing;
}
@media (pointer: fine) {
  .mosaik,
  .mosaik.is-dragging {
    cursor: none;
  }
}
.mosaik__stage {
  position: absolute;
  inset: 0;
  z-index: 1; /* über dem Topo-Hintergrund (.gallery__bg) */
  will-change: transform;
}
.mtile {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  visibility: hidden;
  will-change: transform;
}
.mtile img,
.mtile video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--surface);
  pointer-events: none; /* Drag geht durch */
  /* Grundzustand wie Rakete: Schwarzweiß, Mouseover = Farbe */
  filter: grayscale(1);
  transition: filter 0.5s ease;
}
.mtile.is-hover img,
.mtile.is-hover video {
  filter: none;
}
.mtile.is-hover {
  z-index: 2;
}
/* Eck-Rahmen (gleiche Optik wie Rakete-Kacheln), aktiv = Akzent.
   Überhang klein halten (12px) — muss zusammen mit dem Nachbar-Rahmen
   in den Kachel-Abstand passen, sonst überlappt es optisch. */
/* R45: o2-Galerie — Ecken proportional verkleinert (Offset 24→13,
   Länge 32→20, Strichstärke 4→2.5) — passt besser zu den kleinen Kacheln */
.mtile .gtile__frame {
  top: -13px;
  left: -13px;
  width: calc(100% + 26px);
  height: calc(100% + 26px);
  background:
    linear-gradient(var(--fc), var(--fc)) left top / 20px 2.5px,
    linear-gradient(var(--fc), var(--fc)) left top / 2.5px 20px,
    linear-gradient(var(--fc), var(--fc)) right top / 20px 2.5px,
    linear-gradient(var(--fc), var(--fc)) right top / 2.5px 20px,
    linear-gradient(var(--fc), var(--fc)) left bottom / 20px 2.5px,
    linear-gradient(var(--fc), var(--fc)) left bottom / 2.5px 20px,
    linear-gradient(var(--fc), var(--fc)) right bottom / 20px 2.5px,
    linear-gradient(var(--fc), var(--fc)) right bottom / 2.5px 20px;
  background-repeat: no-repeat;
}
.mtile.is-hover .gtile__frame {
  --fc: var(--accent);
}
/* R45: geklickte o2-Kachel liegt über den Nachbarn (Desktop + Mobil) */
.mtile.is-zoom {
  z-index: 6;
}

/* ---- „Greifbares Design": Void = Passe-partout --------------------------
   Exhibits in ECHTFARBE (nie umfärben) — der Blau-Rim lebt auf der KANTE
   und im Schwarz drumherum, nicht auf dem Inhalt. Schwere Vignette am
   Sektionsrand (Museum-Wand). */
.mosaik--echt .mtile img,
.mosaik--echt .mtile video {
  filter: none; /* Echtfarbe — kein S/W-Grundzustand */
  /* Exponate werden NIE angeschnitten */
  object-fit: contain;
  background: #000; /* R38: Tiefschwarz, einheitlich */
}

/* „← Zurück" aus der Unter-Galerie (Band-Optik wie „Weiter scrollen") */
.mosaik__back {
  position: absolute;
  top: 10%;
  left: 10%;
  z-index: 6;
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(0, 0, 0, 0.85) 14%,
    rgba(0, 0, 0, 0.85) 86%,
    transparent 100%
  );
  border: 0;
  border-top: 2.5px solid var(--accent);
  border-bottom: 2.5px solid var(--accent);
  padding: 12px 34px;
  min-height: 44px;
  cursor: pointer;
  white-space: nowrap;
}
.mosaik__back[hidden] {
  display: none;
}
.mosaik__back:hover {
  color: var(--accent);
}
.mosaik--echt .mtile {
  /* harter Blau-Rim auf der Exhibit-Kante + volumetrischer Glow */
  box-shadow: 0 0 0 1px rgba(77, 124, 255, 0.45),
    0 0 26px -8px rgba(77, 124, 255, 0.4);
  transition: box-shadow 0.35s ease;
}
.mosaik--echt .mtile.is-hover {
  box-shadow: 0 0 0 1px var(--accent),
    0 0 44px -6px rgba(77, 124, 255, 0.65);
}
.mosaik--echt::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(
    ellipse 80% 74% at 50% 46%,
    transparent 52%,
    rgba(0, 0, 0, 0.45) 84%,
    rgba(0, 0, 0, 0.72) 100%
  );
}

/* Beschriftung (echte Textebene, Mono) unter dem Exhibit */
.mtile__label {
  position: absolute;
  left: 0;
  top: calc(100% + 10px);
  max-width: 100%;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  pointer-events: none;
}

/* Hover kippt Totale → Detail (Messestand) */
.mtile__detail {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.45s ease;
  pointer-events: none;
}
.mtile.is-hover .mtile__detail {
  opacity: 1;
}

/* Hover kippt Print-Stücke auf die Working-View: Anschnitt (rot),
   Satzspiegel-Hilfslinien (magenta), Mono-Tag — Handwerk sichtbar,
   ohne den Inhalt vollständig auszuliefern */
.mtile__wv {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}
.mtile.is-hover .mtile__wv {
  opacity: 1;
}
.mtile__wv .wv-bleed {
  position: absolute;
  inset: -7px;
  border: 1px solid rgba(255, 70, 70, 0.85);
}
.mtile__wv .wv-margin {
  position: absolute;
  inset: 9%;
  border: 1px solid rgba(255, 0, 255, 0.7);
}
.mtile__wv .wv-tag {
  position: absolute;
  left: 0;
  bottom: 0;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(0, 0, 0, 0.82);
  padding: 5px 8px;
}

/* Text-Kachel der Mosaik-Galerien (erste Kachel, Intro endet auf ihr).
   Die GESAMTE Typo skaliert in em mit der Kachel: mosaik.js setzt die
   Basis-font-size passend zur Kachelhöhe — auf kleinen Monitoren reißt
   der Text sonst aus der Kachel. */
.mtile--text {
  display: flex;
  /* R25: Inhalt beginnt OBEN mit der Headline (war vertikal zentriert) */
  align-items: flex-start;
  /* R32: Kachel ist jetzt klein (Viertel) — Text angeschnitten mit Fade,
     Klick öffnet das Lese-Overlay (auch am Desktop) */
  overflow: hidden;
  cursor: pointer;
  -webkit-mask-image: linear-gradient(to bottom, #000 68%, transparent 96%);
          mask-image: linear-gradient(to bottom, #000 68%, transparent 96%);
  /* großzügige Innenränder: Typo darf nie die Kachelkante erreichen */
  padding: 2em;
  overflow: hidden;
}
.mtile--text .gtile__texthead {
  gap: 1.4em;
}
.mtile--text .section-num {
  font-size: 1.85em;
  line-height: 0.95;
}
.mtile--text h2 {
  font-size: 1.85em;
  line-height: 0.95;
}
.mtile--text p {
  font-size: 0.95em;
  line-height: 1.5;
  color: var(--text);
}

/* markierte Platzhalter-Kachel (Galerie ohne Material) */
.gallery {
  position: relative;
  /* immer volle Fensterhöhe */
  height: 100vh;
  height: 100svh;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  overflow: hidden;
  cursor: grab;
  /* vertikales Wischen scrollt weiter die Seite (kein Scroll-Käfig auf Touch) */
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
  border-top: var(--border) solid var(--line);
  border-bottom: var(--border) solid var(--line);
  /* 3D-Tiefe für die Schalen-Verkrümmung (translateZ der Kacheln) */
  perspective: 1300px;
  perspective-origin: 50% 50%;
}
.gallery.is-dragging {
  cursor: grabbing;
}
@media (pointer: fine) {
  /* nativer Cursor aus — die große Hand (.gallery__hand) übernimmt */
  .gallery,
  .gallery.is-dragging {
    cursor: none;
  }
}
.gallery__stage {
  position: absolute;
  inset: 0;
  z-index: 1;
  will-change: transform;
  transform-style: preserve-3d;
}

/* Spotlight: Schwarz mit 70 % Deckkraft hinter der aktiven Kachel —
   liegt ÜBER den inaktiven Kacheln (z 2), die aktive (z 3) bleibt frei. */
.gallery__dim {
  position: absolute;
  inset: -140px;
  z-index: 2;
  background: #000;
  opacity: 0; /* Deckkraft setzt der Loop: 0.8 Vollbild · 0.7 Lock/Hover */
  transition: opacity 0.35s ease;
  pointer-events: none;
}

/* Mitlaufender Hintergrund: feines Punktraster + vereinzelte Akzentpunkte,
   wird im Loop mit ~1/5 der Kamerageschwindigkeit verschoben (Parallaxe). */
.gallery__bg {
  position: absolute;
  inset: -420px;
  z-index: 0;
  pointer-events: none;
  will-change: transform;
  /* dezente weiße Höhenlinien (Topo-Karte). Kachel 390×390 = Periode der
     Parallaxe-Verschiebung im Loop → nahtloses Wrappen. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='390' height='390'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='0.055' stroke-width='1'%3E%3Cpath d='M0 33 Q97 10 195 33 T390 33'/%3E%3Cpath d='M0 78 Q97 100 195 78 T390 78'/%3E%3Cpath d='M0 123 Q97 103 195 123 T390 123'/%3E%3Cpath d='M0 168 Q97 192 195 168 T390 168'/%3E%3Cpath d='M0 213 Q97 191 195 213 T390 213'/%3E%3Cpath d='M0 258 Q97 280 195 258 T390 258'/%3E%3Cpath d='M0 303 Q97 282 195 303 T390 303'/%3E%3Cpath d='M0 348 Q97 370 195 348 T390 348'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 390px 390px;
}

/* Unschärfe zum Rand hin: Overlay mit backdrop-filter, dessen Maske die
   Mitte ausspart. */
.gallery__blur {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  -webkit-mask-image: radial-gradient(
    ellipse 72% 64% at 50% 50%,
    transparent 46%,
    rgba(0, 0, 0, 0.55) 74%,
    #000 96%
  );
  mask-image: radial-gradient(
    ellipse 72% 64% at 50% 50%,
    transparent 46%,
    rgba(0, 0, 0, 0.55) 74%,
    #000 96%
  );
}

/* Logo „Die Rakete" oben links — solide Fläche, Kacheln laufen dahinter
   durch und sind dort damit visuell ausgespart. */
.gallery__logo {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 5;
  padding: calc(var(--sp-3) + 48px) var(--sp-3) var(--sp-3) var(--gutter);
  background: linear-gradient(
    135deg,
    var(--bg) 0%,
    var(--bg) 72%,
    transparent 100%
  );
  pointer-events: none;
}
.gallery__logo img {
  display: block;
  width: clamp(140px, 16vw, 220px);
  height: auto;
}
/* o2-Galerie: zwei Marken (Brodos zuerst, dann o2), weiß, untereinander.
   align-items:flex-start → Bilder werden NICHT auf Container-Breite gestreckt
   (sonst gestaucht). width:auto + feste Höhe pro Marke = korrektes Seitenverhältnis. */
.gallery__logo--o2 {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}
.gallery__logo--o2 img { width: auto; }
.gallery__logo--o2 .gl--brodos { height: clamp(22px, 2.8vw, 34px); } /* Wortmarke, breit */
.gallery__logo--o2 .gl--o2 { height: clamp(44px, 5.5vw, 72px); }     /* Bildmarke, kompakt */

/* Kategorie-Filter: oben rechts, 10 % vom Rand eingezogen. Optik wie
   „Weiter scrollen" (schwarz hinterlegt, Akzentlinie, seitlich auslaufend). */
/* Galerie-Navigation (Übersicht / Die Rakete / …) — GLEICHE Optik wie
   „Weiter scrollen": ein schwarzes Band, blaue Linien oben/unten,
   seitlich transparent auslaufend. */
.gallery__filters {
  position: absolute;
  top: 10%;
  right: 10%;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 44px 4px;
  max-width: 72vw;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(0, 0, 0, 0.85) 14%,
    rgba(0, 0, 0, 0.85) 86%,
    transparent 100%
  );
}
.gallery__filters::before,
.gallery__filters::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 2.5px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--accent) 14%,
    var(--accent) 86%,
    transparent 100%
  );
}
.gallery__filters::before { top: 0; }
.gallery__filters::after { bottom: 0; }
.gallery__filter {
  font-family: var(--font-display);
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  background: none;
  border: 0;
  padding: 12px 14px;
  min-height: 44px;
  cursor: pointer;
  white-space: nowrap;
}
.gallery__filter:hover,
.gallery__filter.is-on {
  color: var(--accent);
}

/* CTA „Galerie-Funktionalität": mittig, deutlich, verschwindet nach dem
   ersten Ziehen. */
.gallery__cta {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 6;
  pointer-events: none;
  display: flex;
  align-items: center;
  gap: 16px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(0, 0, 0, 0.82); /* Fallback ohne color-mix */
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border: var(--border) solid var(--accent);
  padding: 20px 28px;
  transition: opacity 0.5s ease;
}
.gallery__cta.is-off {
  opacity: 0;
}
.gallery__cta-arrow {
  color: var(--accent);
  font-weight: 700;
}
.gallery__cta-arrow--l {
  animation: cta-nudge-l 1.6s ease-in-out infinite;
}
.gallery__cta-arrow--r {
  animation: cta-nudge-r 1.6s ease-in-out infinite;
}
@keyframes cta-nudge-l {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(-6px); }
}
@keyframes cta-nudge-r {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(6px); }
}

/* CTA „Weiter scrollen": schwarz hinterlegt, Linien oben/unten in der
   Stärke des Hochformat-Streifens (2.5px) — beides läuft zu den Seiten
   transparent aus. Immer am unteren Rand. */
.gallery__scroll {
  position: absolute;
  left: 50%;
  bottom: clamp(40px, 7vh, 84px);
  transform: translateX(-50%);
  z-index: 6;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 84px 10px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(0, 0, 0, 0.85) 22%,
    rgba(0, 0, 0, 0.85) 78%,
    transparent 100%
  );
}
.gallery__scroll::before,
.gallery__scroll::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 2.5px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--accent) 22%,
    var(--accent) 78%,
    transparent 100%
  );
}
.gallery__scroll::before {
  top: 0;
}
.gallery__scroll::after {
  bottom: 0;
}
.gallery__scroll-label {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--fs-body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  white-space: nowrap;
}
/* „↑ zurück zum Case" — KLICK bringt an den Anfang des Case (Band-Optik) */
.gallery__scrollhint {
  position: absolute;
  left: 50%;
  bottom: clamp(40px, 7vh, 84px);
  transform: translateX(-50%);
  z-index: 6;
  cursor: pointer;
  border: 0;
  /* pointer-events wird sonst von der Galerie (none) geerbt → nicht klickbar */
  pointer-events: auto;
  padding: 12px 84px 10px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(0, 0, 0, 0.85) 22%,
    rgba(0, 0, 0, 0.85) 78%,
    transparent 100%
  );
}
.gallery__scrollhint:hover .gallery__scroll-label {
  color: var(--accent);
}
/* Scroll- und Speed-Icon: identische Größe */
.scroll-mouse {
  width: 22px;
  height: 22px;
  display: block;
}
.scroll-mouse__wheel {
  animation: wheel-drop 1.4s ease-in-out infinite;
}
@keyframes wheel-drop {
  0% { transform: translateY(0); opacity: 1; }
  70% { transform: translateY(7px); opacity: 0.15; }
  100% { transform: translateY(0); opacity: 0; }
}

/* Große Hand als Cursor (nur feine Zeiger; Position setzt der Loop).
   Flat/Pixel-Stil, weiß. */
.gallery__hand {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 7;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  filter: drop-shadow(0 3px 8px rgba(0, 0, 0, 0.65));
}
.gallery__hand svg {
  width: 58px;
  height: 58px;
  display: block;
}
.gallery__hand .hand-grab {
  display: none;
}
.gallery.is-dragging .gallery__hand .hand-open {
  display: none;
}
.gallery.is-dragging .gallery__hand .hand-grab {
  display: inline;
}

/* ---- Kacheln ---------------------------------------------------------------- */

.gtile {
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
  z-index: 1;
}

.gtile video {
  display: block;
  width: 100%;
  object-fit: cover;
  /* R42: Kachelfläche nur noch 20 % deckend (Hintergrund scheint durch) */
  background: rgba(21, 21, 21, 0.2); /* Fallback ohne color-mix */
  background: color-mix(in srgb, var(--surface) 20%, transparent);
  border: 0; /* kein grauer Rahmen um die Videos */
  pointer-events: none; /* Drag geht durch */
  /* Grundzustand: pausiert + Schwarzweiß auf Frame 1 — spielende Kacheln
     (Mouseover, eingerastet oder geklickt) laufen farbig, siehe .is-active */
  filter: grayscale(1);
  transition: filter 0.5s ease;
}
.gtile.is-active video {
  filter: none;
}
.gtile__quer video,
.gtile__quer .tile__ph {
  aspect-ratio: 16 / 9;
}
.gtile__insta {
  position: absolute;
  width: 36%;
  right: -30%;
  bottom: -38%;
  z-index: 2;
}
.gtile__insta video,
.gtile__insta .tile__ph {
  aspect-ratio: 9 / 16;
}
/* Akzentstreifen am Hochformat: 50 % dünner als zuvor und vom Video
   abgesetzt (L-Form links/unten, 10px Abstand). */
/* Akzentstreifen am Querformat — L-Form UNTEN + LINKS (wie Hochformat).
   Endet vor dem Hochformat-Inset (right 34 %), damit sich die beiden
   Akzent-L nie überschneiden. */
.gtile__quer {
  position: relative;
}
/* Text-Kachel: EINSPALTIG — Zahl + Headline in EINER Zeile, Absatz darunter.
   (gilt gleich für Rakete-Galerie und Mosaik-Galerien) */
.gtile--text .gtile__textinner,
.mtile--text .gtile__textinner {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  align-items: flex-start;
}
/* Textkachel: Innenabstand zum Rand + flexible Hoehe (waechst mit Inhalt
   nach unten — bis zum naechsten Content ist Platz) */
.gtile--text {
  padding: clamp(20px, 1.8vw, 32px);
  height: auto;
  box-sizing: border-box;
}
.gtile--text .gtile__texthead,
.mtile--text .gtile__texthead {
  display: flex;
  align-items: baseline;
  gap: var(--axis-gap);
}
.gtile--text .section-num {
  font-size: var(--fs-h2);
  line-height: 0.95;
}
.gtile--text h2,
.mtile--text h2 {
  word-spacing: -0.5ch;
}
.gtile--text p {
  font-size: var(--fs-small);
  color: var(--text);
}

/* Eck-Rahmen um das ganze Projekt — EINHEITLICH (Runde 12): 2px Strich,
   Akzent-Blau, 12px Abstand zur Medienkante (wie .case-frame/.mtile). */
.gtile__frame {
  position: absolute;
  top: -24px;
  left: -24px;
  width: calc(130% + 48px);
  height: calc(138% + 48px);
  pointer-events: none;
  --fc: var(--accent);
  background: linear-gradient(var(--fc), var(--fc)) left top / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) left top / 4px 32px,
    linear-gradient(var(--fc), var(--fc)) right top / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) right top / 4px 32px,
    linear-gradient(var(--fc), var(--fc)) left bottom / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) left bottom / 4px 32px,
    linear-gradient(var(--fc), var(--fc)) right bottom / 32px 4px,
    linear-gradient(var(--fc), var(--fc)) right bottom / 4px 32px;
  background-repeat: no-repeat;
}
.gtile--text .gtile__frame {
  width: calc(100% + 48px);
  height: calc(100% + 48px);
}
.gtile.is-active .gtile__frame {
  --fc: var(--accent);
}

/* Platzhalter-Kachel für fehlendes Format */
.tile__ph {
  display: grid;
  place-items: center;
  width: 100%;
  background: var(--surface);
  border: var(--border) dashed var(--accent);
  pointer-events: none;
}
.tile__ph span {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  text-align: center;
  padding: 12px;
}

/* Beschreibung: sichtbar, solange die Kachel NICHT spielt.
   Gleichmäßiger Abstand (--sp-1) zur Videokante. */
.gtile__cap {
  position: absolute;
  left: 0;
  top: calc(100% + var(--sp-1));
  max-width: 62%;
  display: grid;
  gap: 6px;
  opacity: 1;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.gtile.is-active .gtile__cap {
  opacity: 0;
}
/* Geklickte (fokussierte) Kachel: Beschreibung wieder einblenden */
.gtile.is-focus .gtile__cap {
  opacity: 1;
}
.gtile__cap-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
}
.tile__title {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.tile__meta {
  color: var(--muted);
}
/* Werkzeug-/KI-Tags */
.tile__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.tag-mini {
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #8A8A8A;
  border: var(--border) solid var(--line);
  padding: 3px 7px;
}
.tag-mini--ai {
  color: var(--accent);
  border-color: var(--accent);
}

/* Sound-Knopf: minimalistischer Linien-Lautsprecher — schließt oben
   bündig mit dem Querformat und rechts bündig mit dem Hochformat ab.
   Sichtbar nur auf der spielenden Kachel. */
.gtile__sound {
  position: absolute;
  /* IN der Kachel (R25): außerhalb (-30%) überdeckte die Nachbar-Kachel
     den Button auf kleinen Kacheln → Klick kam nie an */
  right: 4px;
  top: 4px;
  z-index: 6;
  z-index: 4;
  line-height: 0;
  /* 22px-Icon + 2×11px Padding = 44px Trefferfläche (Touch) */
  padding: 11px;
  margin: -5px -5px 0 0; /* Icon bleibt optisch an seiner Position */
  background: none;
  border: 0;
  cursor: pointer;
  /* auch auf kleinen/ruhenden Kacheln sichtbar UND klickbar —
     gedimmt, auf der aktiven Kachel voll deckend */
  opacity: 0.45;
  pointer-events: auto;
  transition: opacity 0.25s ease;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.6));
}
.gtile__sound:hover {
  opacity: 1;
}
.gtile__sound svg {
  width: 22px;
  height: 22px;
  display: block;
}
.gtile__sound .snd-on {
  display: none;
}
.gtile__sound.is-on .snd-on {
  display: block;
}
.gtile__sound.is-on .snd-off {
  display: none;
}
.gtile.is-active .gtile__sound {
  opacity: 1;
}
.gtile__sound.is-on svg {
  stroke: var(--accent);
}

/* ---- Reveal-Animationen ---------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(42px);
  transition: opacity 0.9s ease, transform 1s cubic-bezier(0.34, 1.45, 0.64, 1); /* R25: elastisch */
}
.reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .scroll-cta__line::after,
  .gallery__cta-arrow--l,
  .gallery__cta-arrow--r,
  .scroll-mouse__wheel {
    animation: none;
  }
  .gtile.is-active .gtile__insta video {
    box-shadow: none;
  }
}

/* ---- Mobil ----------------------------------------------------------------- */

@media (pointer: coarse), (max-width: 720px) {
  /* Mobil: nur die Hochformat-Videos */
  .gtile__quer {
    display: none;
  }
  .gtile__insta {
    position: static;
    width: 100%;
  }
  .gtile__frame {
    width: calc(100% + 24px);
    height: calc(100% + 24px);
  }
  /* R36: o2-Galerie — Eck-Abstand mobil halbiert (24px → 12px) */
  .mtile .gtile__frame {
    top: -12px;
    left: -12px;
    width: calc(100% + 24px);
    height: calc(100% + 24px);
  }
  /* (.mtile.is-zoom-z-index jetzt global, R45) */
  /* R36: Lebenslauf — Titel und Firma näher zusammen */
  .cv-item__org {
    margin-top: -4px;
  }
  .gtile__cap {
    max-width: 100%;
  }
  .gtile__sound {
    right: 0;
    top: 0;
  }
  .gallery__hand,
  .gallery__cta-hover {
    display: none;
  }
}

@media (max-width: 720px) {
  .topbar__nav {
    gap: var(--sp-1);
  }
  .nav-link {
    font-size: 12px;
    letter-spacing: 0.12em;
  }
}

/* ---- Hamburger-Menü (Mobil) ---------------------------------------------
   Desktop unverändert; ≤720px wird die Navigation zum Vollbild-Panel. */
.nav-burger {
  display: none;
}

@media (max-width: 720px) {
  .nav-burger {
    display: grid;
    gap: 5px;
    justify-items: end;
    background: none;
    border: 0;
    padding: 12px 6px;
    min-width: 44px;
    min-height: 44px;
    align-content: center;
    cursor: pointer;
    position: relative;
    z-index: 95; /* über dem Panel */
  }
  .nav-burger span {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--text);
    transition: transform 0.25s ease, opacity 0.2s ease, background 0.2s ease;
  }
  /* offen → ✕ */
  .topbar.is-open .nav-burger span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
    background: var(--accent);
  }
  .topbar.is-open .nav-burger span:nth-child(2) {
    opacity: 0;
  }
  .topbar.is-open .nav-burger span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
    background: var(--accent);
  }

  /* Nav wird zum Vollbild-Panel — nur die 4 flachen Mobil-Links */
  .topbar__nav {
    display: none;
  }
  .nav-desktop {
    display: none !important; /* Dropdown-Nav auf Mobil komplett aus */
  }
  /* WICHTIG: backdrop-filter auf .topbar macht sie zum Containing Block
     für fixed-Kinder — »fixed inset:0« der Nav bezog sich nur auf den
     Topbar-Streifen (Panel wirkte leer/durchsichtig). Deshalb: die TOPBAR
     selbst wird im offenen Zustand zum Vollbild-Panel. */
  .topbar.is-open {
    bottom: 0;
    align-items: flex-start;
    background: rgba(5, 5, 6, 0.96);
  }
  .topbar.is-open .topbar__nav {
    position: absolute;
    inset: 0;
    z-index: 94;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-end;
    gap: var(--sp-2);
    padding: 96px calc(var(--gutter) + 6px) var(--sp-5) var(--gutter);
  }
  .topbar.is-open .nav-mobile {
    display: block; /* Basis-Regel versteckt .nav-mobile — hier zwingend zurückholen */
    font-size: clamp(22px, 6vw, 28px);
    letter-spacing: 0.08em;
    padding: 10px 0;
  }
}

/* ---- Große Monitore (z. B. 32"): Hero-Typo wächst mit ------------------- */
@media (min-width: 1800px) {
  /* 32"-Monitore: Token-Cap 104px wirkt zu klein → mit vw wachsen,
     aber gedeckelt, damit es auf 4K nicht ausufert */
  .hero__name {
    font-size: clamp(104px, 7.2vw, 190px);
  }
  .hero__slogan {
    font-size: clamp(38px, 2.4vw, 64px);
  }
}

/* ---- Mobil-Feinschliff Galerien ------------------------------------------ */
@media (pointer: coarse), (max-width: 720px) {
  /* Galerie-Navigation: unten als volle, seitlich scrollbare Leiste —
     überlappt weder Rakete-Logo noch schneidet sie Einträge ab */
  .gallery__filters {
    top: auto;
    bottom: clamp(96px, 14vh, 150px);
    left: 0;
    right: 0;
    max-width: none;
    justify-content: flex-start;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding: 4px 16px 2px;
  }
  .gallery__filter {
    padding: 10px 12px;
  }
  /* „← Zurück" oben links, kompakt unter der Topbar */
  .mosaik__back {
    top: 72px;
    left: 12px;
    padding: 10px 18px;
  }
  /* Programm-Tags überlappen mobil nur — weg damit */
  .tile__tags {
    display: none;
  }
  /* „Weiter scrollen" überlappt mobil mit der Galerie-Nav → streichen */
  .gallery__scroll {
    display: none;
  }
  /* Text-Kacheln mobil mit weniger Innenrand (mehr Platz für Typo) */
  .mtile--text {
    padding: 1.4em;
  }
}

/* Case-Link IN der Rakete-Textkachel — führt zur Case-Study „Maschinenraum"
   (Band-Optik wie „Weiter scrollen"; nur hier, nicht auf den Videos). */
.topbar a.label, a.label { text-decoration: none; }

/* ==================================================================== *
 *  MOBIL (R12): Textkacheln im Raster + Tap-Zoom-Overlay                *
 * ==================================================================== */
@media (pointer: coarse), (max-width: 720px) {
  /* Rakete-Galerie: Textkachel exakt im Kachel-Raster (9:16 wie die
     Hochformat-Videos), Inhalt beschnitten — Antippen öffnet das Overlay. */
  .gtile--text {
    aspect-ratio: 9 / 16;
    height: auto !important;
    overflow: hidden;
    cursor: pointer;
    /* Inhalt läuft unten weich aus → signalisiert „mehr" */
    -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 97%);
            mask-image: linear-gradient(to bottom, #000 72%, transparent 97%);
  }
  .mtile--text {
    overflow: hidden;
    cursor: pointer;
    -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent 97%);
            mask-image: linear-gradient(to bottom, #000 72%, transparent 97%);
  }
  /* Mini-Textkachel: Typo verkleinern, damit die Headline nicht unschön
     bricht — lesbar wird's im Tap-Overlay */
  .gtile--text h2,
  .mtile--text h2,
  .gtile--text .section-num,
  .mtile--text .section-num {
    font-size: clamp(15px, 4vw, 19px);
  }
  .gtile--text p,
  .mtile--text p {
    font-size: 12px;
  }
}

/* Tap-Zoom-Overlay: Textkachel-Inhalt in groß, X schließt (beide Galerien) */
.txtzoom {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: rgba(0, 0, 0, 0.96);
  overflow-y: auto;
  padding: clamp(64px, 10vh, 110px) var(--gutter) clamp(40px, 7vh, 80px);
}
.txtzoom[hidden] { display: none; }
.txtzoom__x {
  position: fixed;
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  font-size: 22px;
  line-height: 1;
  color: var(--text);
  background: rgba(0, 0, 0, 0.8);
  border: 2px solid var(--accent);
  cursor: pointer;
  z-index: 2;
}
.txtzoom__body {
  max-width: 640px;
  margin-inline: auto;
  display: grid;
  gap: var(--sp-2);
}
.txtzoom__body .section-num { font-size: var(--fs-h2); line-height: 0.95; }
.txtzoom__body h2 { word-spacing: -0.5ch; }
.txtzoom__body p { color: var(--text); font-size: var(--fs-body); line-height: 1.65; }
/* Rahmen-Ecken/Frames aus dem geklonten Inhalt ausblenden */
.txtzoom__body .gtile__frame,
.txtzoom__body .case-frame { display: none; }

/* ==================================================================== *
 *  R13: Dezenter BLAUER GLOW — rechteckige Elemente heben sich vom      *
 *  schwarzen Grund ab (Akzent #4D7CFF, passend zur Typo).               *
 * ==================================================================== */
.probe,
.kontakt-actions .btn,
.mtile,
.txtzoom__body img {
  /* R16: KEIN 1px-Ring/Outline mehr (global) — nur weicher Glow.
     .cv__bg (Lebenslauf-Video) ist von der Regel AUSGESCHLOSSEN. */
  box-shadow: 0 0 22px rgba(77, 124, 255, 0.31),
    0 0 52px rgba(77, 124, 255, 0.17);
  animation: glow-noise 9.4s steps(1) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .probe, .kontakt-actions .btn, .mtile, .gtile video, .gtile--text, .txtzoom__body img { animation: none; }
}

/* Hilfsklasse: Wortgruppe nie trennen (z. B. „After Effects" im Lebenslauf) */
.nowrap { white-space: nowrap; }


/* R25: Ecken „glitchen" global — kurzer System-Zucker alle ~7 s
   (angelehnt an den Namens-Glitch im Hero). */
@keyframes corner-glitch {
  0%, 91%, 100% { transform: translate(0, 0); opacity: 1; }
  92% { transform: translate(3px, -2px); opacity: 0.55; }
  93% { transform: translate(-3px, 2px); opacity: 1; }
  94.5% { transform: translate(2px, 1px); opacity: 0.7; }
  95% { transform: translate(0, 0); opacity: 1; }
}
.gtile__frame,
.probe::before,
.mtile .gtile__frame {
  animation: corner-glitch 7.3s steps(1) infinite;
}
@media (prefers-reduced-motion: reduce) {
  .gtile__frame, .probe::before, .mtile .gtile__frame { animation: none; }
}

/* R25: Glow +20 % mit ruhigem Noise (diskrete Stufen = günstig im Paint) */
@keyframes glow-noise {
  0%, 100% { box-shadow: 0 0 22px rgba(77, 124, 255, 0.31), 0 0 52px rgba(77, 124, 255, 0.17); }
  27% { box-shadow: 0 0 27px rgba(77, 124, 255, 0.27), 0 0 60px rgba(77, 124, 255, 0.20); }
  55% { box-shadow: 0 0 19px rgba(77, 124, 255, 0.36), 0 0 46px rgba(77, 124, 255, 0.15); }
  78% { box-shadow: 0 0 24px rgba(77, 124, 255, 0.30), 0 0 64px rgba(77, 124, 255, 0.21); }
}

/* R25: Text-Hierarchie GLOBAL — Abstand über einer Überschrift 2/3 em,
   darunter 1/3 em (vererbt in allen Fließtext-Blöcken). */
main p + h2, main p + h3, main ul + h2, main ul + h3,
main p + h4, main table + h3 {
  margin-top: 0.66em;
}
main h2, main h3 {
  margin-bottom: 0.33em;
}

/* R26: EINE Glow-Fläche pro Galerie-Kachel — beide Formate (hoch+quer)
   wirken als EINE Kachel. Bounds = Eck-Rahmen-Box; Shadow zeichnet nur
   außerhalb → weicher Halo um das Gesamt-Projekt. */
.gtile::after {
  content: "";
  position: absolute;
  top: -24px;
  left: -24px;
  width: calc(130% + 48px);
  height: calc(138% + 48px);
  pointer-events: none;
  z-index: 0;
  box-shadow: 0 0 22px rgba(77, 124, 255, 0.31),
    0 0 52px rgba(77, 124, 255, 0.17);
  animation: glow-noise 9.4s steps(1) infinite;
}
.gtile--text::after { display: none; } /* Textkachel glüht selbst (Liste) */
@media (pointer: coarse), (max-width: 720px) {
  .gtile::after {
    width: calc(100% + 48px);
    height: calc(100% + 48px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .gtile::after { animation: none; }
}

/* R27: Tönende Kachel — der Glow wird ANALOG ZUR AMPLITUDE heller
   (--amp 0..1 aus js/main.js). Ohne Ton flackert der normale Noise weiter. */
.gtile.is-sounding::after {
  animation: none;
  box-shadow:
    0 0 calc(22px + var(--amp, 0) * 30px)
      rgb(77 124 255 / calc(0.31 + var(--amp, 0) * 0.45)),
    0 0 calc(52px + var(--amp, 0) * 56px)
      rgb(77 124 255 / calc(0.17 + var(--amp, 0) * 0.30));
}

/* R28: MOBIL — Case-Study-Kacheln: Linien statt überlappender Ecken */
@media (max-width: 720px) {
  .probe::before { display: none; }
  .probe {
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
  }
}

/* ==================================================================== *
 *  Galerie-Erst-Hinweis (Design-Critique): „Ziehen · Klick zoomt".      *
 *  Erscheint mit der Galerie, fadet nach dem ersten Zug DAUERHAFT weg.  *
 * ==================================================================== */
.gallery__hint {
  position: absolute;
  top: clamp(76px, 12vh, 120px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 7;
  pointer-events: none;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(10, 10, 10, 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  padding: 9px 16px;
  white-space: nowrap;
  /* Standard sichtbar (robuster als Einblend-Animation bei Elementen, die aus
     display:none kommen); verschwindet dauerhaft beim ersten Zug (.is-gone). */
  opacity: 0.9;
  transition: opacity 0.4s ease;
}
.gallery__hint span { color: var(--accent); margin: 0 0.3em; }
.gallery__hint.is-gone { opacity: 0; }

/* R31: MOBIL — Ecken-Strichstärke global halbiert (4px → 2px) */
@media (max-width: 720px) {
  .gtile__frame,
  .mtile .gtile__frame,
  .probe::before {
    background: linear-gradient(var(--fc), var(--fc)) left top / 32px 2px,
      linear-gradient(var(--fc), var(--fc)) left top / 2px 32px,
      linear-gradient(var(--fc), var(--fc)) right top / 32px 2px,
      linear-gradient(var(--fc), var(--fc)) right top / 2px 32px,
      linear-gradient(var(--fc), var(--fc)) left bottom / 32px 2px,
      linear-gradient(var(--fc), var(--fc)) left bottom / 2px 32px,
      linear-gradient(var(--fc), var(--fc)) right bottom / 32px 2px,
      linear-gradient(var(--fc), var(--fc)) right bottom / 2px 32px;
    background-repeat: no-repeat;
  }
}

/* R32: Galerie-Hinweis NOCH auffälliger — groß, geglowt, sanfter Puls */
.gallery__hint {
  top: 50%;
  transform: translate(-50%, -50%);
  font-size: clamp(19px, 2.2vw, 27px);
  padding: 20px 38px;
  background: rgba(5, 5, 6, 0.85);
  box-shadow: 0 0 22px rgba(77, 124, 255, 0.31),
    0 0 52px rgba(77, 124, 255, 0.17);
  animation: hint-puls 2.4s ease-in-out infinite;
}
@keyframes hint-puls {
  0%, 100% { opacity: 0.9; }
  50% { opacity: 0.55; }
}
.gallery__hint.is-gone { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .gallery__hint { animation: none; }
}

/* R31: Kachelbeschriftung der Galerie ZENTRIERT (Ecken ragten in den Text) */
.gtile__cap {
  text-align: center;
  width: 100%;
}
.gtile__cap-row { justify-content: center; }
.tile__tags { justify-content: center; }
