/* SCHRIFTEN (04.09.2026): selbst gehostet, Latin-Subset von Google Fonts v7/v17.
   Schibsted Grotesk ist eine variable Schrift (wght 400-800), deshalb je eine Datei fuer
   aufrecht und kursiv statt sieben Schnitte. font-display: swap -- Text steht sofort. */
@font-face { font-family: "Schibsted Grotesk"; font-style: normal; font-weight: 400 800; font-display: swap; src: url("assets/fonts/schibsted-grotesk-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Schibsted Grotesk"; font-style: italic; font-weight: 400 800; font-display: swap; src: url("assets/fonts/schibsted-grotesk-italic-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Space Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("assets/fonts/space-mono-400-latin.woff2") format("woff2"); }
@font-face { font-family: "Space Mono"; font-style: normal; font-weight: 700; font-display: swap; src: url("assets/fonts/space-mono-700-latin.woff2") format("woff2"); }

:root {
  --nav-w: 0px;
  --ink: #1a1712;
  --black: #0b0a08;
  --blue-black: #071017;
  --canvas: #f1e8d7;
  --canvas-hi: #fff8ea;
  --stone: #b8ab92;
  --umber: #574631;
  --signal: #ff3a5e;
  /* Coral fuer BEDIENUNG auf dunklem Grund. Gemessen: #ff3a5e auf einem dunklen Filmbild
     erreicht nur ~2,9:1 — Coral liegt in der Mitte der Helligkeitsskala, das ist Physik und
     keine Einstellung. Diese Aufhellung bringt dieselbe Farbe auf ~5:1. Auf hellem Grund
     uebernimmt --madder dieselbe Rolle. Nur fuer Schrift in der Bedienung, nie im Bild.
     [offen] Erweiterung der Palette aus Doc 16 — Jaschas Bestaetigung ausstehend. */
  --signal-ui: #ff8095;
  --madder: #9f2f37;
  --gold: #b89a58;
  --line-dark: rgba(26, 23, 18, .22);
  --line-light: rgba(241, 232, 215, .24);
  --sans: "Schibsted Grotesk", Arial, sans-serif;
  --mono: "Space Mono", monospace;
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --ease-inout: cubic-bezier(.76, 0, .24, 1);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--black); }
body { margin: 0; color: var(--canvas); background: var(--black); font-family: var(--sans); overflow-x: hidden; }
body.scroll-locked { overflow: hidden; }  /* sperrt den Scroll, solange das Index-Overlay offen ist */

/* Safari-26-Hybridtest: Die sichtbare Scroll-Film-Engine bleibt auf ihrer stabilen fixed-
   Buehne. Nur der Root-Canvas bekommt den aktuellen Frame als echtes CSS-Hintergrundbild,
   weil Safari diesen Bereich hinter seinen Leisten darstellen kann, Canvas-Compositing aber
   nicht. Kein Element wird hier anhand des wechselnden visualViewport verschoben. */
html.ios-edge-backdrop {
  background-color: var(--black);
  background-image: var(--safari-edge-image, none);
  background-position: var(--safari-edge-position, 50%) 50%;
  background-size: cover;
  background-repeat: no-repeat;
  background-attachment: fixed;
}
html.ios-edge-backdrop body { background: transparent; }
html.ios-edge-backdrop .buehne { background: transparent; }
html.ios-edge-backdrop.ios-edge-fold { background-color: var(--canvas); background-image: none; }
button, input, select, textarea { font: inherit; }
a { color: inherit; }
img { max-width: 100%; }
::selection { color: var(--black); background: var(--signal); }

.skip-link { position: fixed; z-index: 1000; left: 18px; top: 18px; padding: 12px 16px; color: var(--ink); background: var(--canvas); transform: translateY(-160%); transition: transform .2s; }
.skip-link:focus { transform: none; }

.loader { position: fixed; z-index: 1000; inset: 0; padding: 4vh 3vw; display: grid; grid-template-columns: 1fr 1fr; align-items: end; color: var(--canvas); background: var(--black); transition: opacity .8s var(--ease-out), visibility .8s; }
.loader.ready { opacity: 0; visibility: hidden; }
.loader::before { content: ""; position: absolute; inset: 0; opacity: .12; background: linear-gradient(90deg, transparent 49.96%, var(--canvas) 50%, transparent 50.04%), linear-gradient(transparent 49.96%, var(--canvas) 50%, transparent 50.04%); }
.loader-mark { position: relative; align-self: center; justify-self: center; width: min(26vw, 330px); }
.loader-mark img { position: relative; z-index: 2; display: block; }
.loader-mark span { position: absolute; z-index: 1; width: 12px; height: 12px; right: 4%; bottom: 6%; border-radius: 50%; background: var(--signal); box-shadow: 0 0 34px var(--signal); animation: loadPulse 1.4s ease-in-out infinite; }
.loader-progress { position: relative; grid-column: 1 / -1; }
.loader-progress p { margin: 0 0 12px; display: flex; justify-content: space-between; font: 9px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
.loader-progress b { color: var(--signal); font-weight: 400; }
.loader-progress > i { display: block; height: 1px; background: var(--line-light); }
.loader-progress > i span { display: block; width: var(--load, 0%); height: 100%; background: var(--signal); transition: width .2s; }

/* ── Fold („Programm", 25.07.) ───────────────────────────────────────────────
   Ersetzt das Ton-Wahl-Gate. Der Fold beantwortet den 5-Sekunden-Test auf Creme,
   der Film beginnt beim Scrollen — „Licht aus" als Uebergang statt als Einstieg
   (Doc 16 §5). Kein Grotesk-Italic (Doc 16 §4). Coral bleibt Signal, nie Flaeche. */
.fold { position: relative; min-height: 100svh; padding: 104px 5vw 34px; padding-right: min(19vw, 250px); display: flex; flex-direction: column; color: var(--ink); background: var(--canvas); overflow: hidden; }
.fold::before { content: ""; position: absolute; inset: 0; background-image: linear-gradient(90deg, rgba(26,23,18,.055) 1px, transparent 1px); background-size: 12.5vw 100%; pointer-events: none; }
.fold > * { position: relative; }
.fold-ort { margin: 0; font: 11px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: color-mix(in srgb, var(--ink) 62%, transparent); }

.fold-programm { margin: 5vh 0 auto; padding: 0; list-style: none; }
.fold-programm li { display: grid; grid-template-columns: 74px 1fr; align-items: baseline; gap: 20px; padding: 1.6vh 0; border-top: 1px solid var(--line-dark); }
.fold-programm li:last-child { border-bottom: 1px solid var(--line-dark); }
.fold-programm b { font: 12px/1 var(--mono); font-weight: 400; letter-spacing: .1em; color: color-mix(in srgb, var(--ink) 42%, transparent); }
.fold-programm h1, .fold-programm h2 { margin: 0; font-size: clamp(29px, 4.6vw, 68px); line-height: .92; letter-spacing: -.035em; text-transform: uppercase; font-weight: 700; }
.fold-programm em { font-style: normal; color: var(--signal); }

.fold-satz { max-width: 46ch; margin: 4vh 0 0; font-size: clamp(17px, 1.4vw, 22px); line-height: 1.34; }
.fold-claim { margin: 3.4vh 0 0; font-size: clamp(19px, 1.7vw, 27px); line-height: 1; letter-spacing: -.02em; text-transform: uppercase; font-weight: 700; }
.fold-claim em { font-style: normal; color: var(--signal); }

.fold-fuss { margin-top: 30px; padding-top: 17px; border-top: 1px solid var(--line-dark); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 26px; }
.fold-beweis { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 0; font: 11px/1.5 var(--mono); letter-spacing: .09em; text-transform: uppercase; }
.fold-beweis b { font-weight: 400; color: var(--signal); }
.fold-beweis span { color: color-mix(in srgb, var(--ink) 58%, transparent); }
.fold-scroll { display: inline-flex; align-items: center; gap: 10px; font: 11px/1.5 var(--mono); letter-spacing: .09em; text-transform: uppercase; color: color-mix(in srgb, var(--ink) 58%, transparent); }
.fold-scroll i { width: 1px; height: 22px; display: block; background: linear-gradient(var(--ink), transparent); animation: foldScroll 2.2s ease-in-out infinite; }
@keyframes foldScroll { 0%, 100% { transform: scaleY(.45); transform-origin: top; } 50% { transform: scaleY(1); } }

/* Der Spalt setzt UNTER der Kopfzeile an, sonst liegt „Anfragen" auf Schwarz. */
.fold-spalt { position: absolute; z-index: 0; top: 104px; right: 0; bottom: 0; width: min(15vw, 196px); overflow: hidden; background: var(--black); }
.fold-spalt img { width: 100%; height: 100%; object-fit: cover; object-position: 62% 50%; filter: saturate(.8) contrast(1.05) brightness(.72); }
.fold-spalt em { position: absolute; left: 50%; bottom: 26px; font: 10px/1 var(--mono); font-style: normal; letter-spacing: .2em; text-transform: uppercase; color: rgba(241,232,215,.66); white-space: nowrap; transform: translateX(-50%) rotate(180deg); writing-mode: vertical-rl; }
@media (prefers-reduced-motion: reduce) { .fold-scroll i { animation: none; } }

/* Kopfzeile traegt nur noch drei Dinge: Marke, Ton, Anfragen (B3). Der world-readout ist
   raus (8 px, unlesbar, redundant), der Musik-Oeffner sitzt jetzt im Fuss der Zeitachse.
   Bedien-Typo durchgehend 11 px statt 8 px. */
.site-chrome { position: fixed; z-index: 200; inset: 0 0 auto; padding: 20px 28px; color: var(--canvas); pointer-events: none; transition: color .35s; }
.chrome-oben { display: flex; align-items: flex-start; gap: 20px; }
.chrome-ort, .chrome-fortschritt { display: none; }
.site-chrome.on-light { color: var(--ink); }
.site-brand { position: relative; width: 62px; height: 58px; pointer-events: auto; }
.site-brand img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: left top; transition: opacity .3s; }
.site-brand .logo-light { opacity: 0; }
.site-chrome.on-light .site-brand .logo-dark { opacity: 0; }
.site-chrome.on-light .site-brand .logo-light { opacity: 1; }
.site-brand .brand-product { top: 18px; right: auto; bottom: auto; left: 72px; width: 46px; height: 22px; object-position: left center; opacity: 0; transform: translateX(-8px); transition: opacity .45s ease, transform .45s ease; }
.site-brand.is-product .brand-product.product-dark { opacity: 1; transform: none; }
.site-chrome.on-light .site-brand.is-product .brand-product.product-dark { opacity: 0; }
.site-chrome.on-light .site-brand.is-product .brand-product.product-light { opacity: 1; transform: none; }
.chrome-actions { margin-left: auto; display: flex; align-items: center; gap: 18px; pointer-events: auto; }
/* Jeder Schalter misst seinen eigenen Grund — ein Messpunkt fuer den ganzen Block war falsch,
   sobald das Fenster breit wird (Jaschas Screenshot 27.07.: helle Schrift auf hellem Fresko). */
/* Schatten auf Mitteltoenen (04.09.2026, mobil bei 35.700 px angesehen: cremefarbene Schrift
   auf Nebel bei 0,5 Leuchtkraft, die Hell-Messung schlug nicht um). Auf Ink-Schrift (on-light)
   faellt der Schatten weg. */
.chrome-actions button { transition: color .35s; }
.chrome-actions button.auf-hell { text-shadow: none; }
.chrome-actions button.auf-hell { color: var(--ink); }
.chrome-actions button.stark { color: var(--canvas-hi); }
.chrome-actions button.stark.auf-hell { color: var(--ink); }
/* Der Anfragen-Knopf haengt NICHT mehr vom Bildgrund ab: eigene Flaeche, immer sichtbar.
   Er ist der einzige Weg zur Anfrage im Dauerzugriff (Audit 3.1) — er darf nicht davon
   abhaengen, welches Bild gerade laeuft. Coral auf Ink misst 5,3:1. */
.chrome-actions button { appearance: none; min-height: 44px; padding: 0; display: inline-flex; align-items: center; border: 0; color: inherit; background: none; cursor: pointer; font: 400 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
/* EIN Block statt zwei. Bis 28.07. stand die alte Codex-Regel („1px solid currentColor 55%")
   HINTER dem Fix vom 27.07. und hat ihn stillschweigend zurueckgedreht: der Knopf trug wieder
   einen dunklen Rahmen auf der Coral-Flaeche (Jascha 28.07.). Gleiche Fehlerklasse wie die
   Specificity-Falle beim Index-Knopf — deshalb ist der Knopf jetzt an genau einer Stelle
   beschrieben, ohne `border`-Eigenschaft, die eine spaetere Regel wieder fuellen koennte. */
.chrome-actions > a b { font-weight: inherit; }
/* Der Anfragen-Knopf traegt zwei Woerter (A4): am Desktop den langen Namen, mobil
   „Anfragen“. Umgeschaltet wird unter 900 px. */
.chrome-actions > a .cta-kurz { display: none; }
.chrome-actions > a { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 15px;
  border: 0; text-decoration: none; color: var(--ink); background: var(--signal);
  font: 400 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  transition: color .25s, background .25s; }
.chrome-actions > a:hover, .chrome-actions > a:focus-visible {
  color: var(--canvas-hi); background: var(--ink); }
/* Die Einladung sitzt unter dem Schalter, den sie meint — rechtsbuendig, damit sie mit ihm
   fluchtet. Sie liegt absolut, damit die Kopfzeile beim Kommen und Gehen nicht springt. */
.ton-schalter { position: relative; display: inline-flex; align-items: center; }
.ton-einladung { position: absolute; right: 0; top: 100%; margin: 2px 0 0; padding: 0;
  pointer-events: none; text-align: right; white-space: nowrap;
  font: 400 11px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: rgba(241,232,215,.62); opacity: 0; transform: translateY(-3px);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out); }
.site-chrome.on-light .ton-einladung { color: rgba(26,23,18,.6); }
.ton-einladung.da { opacity: 1; transform: none; }
/* Solange die Einladung steht, atmet der Schalter einmal alle drei Sekunden — das ist die
   ganze Bewegung. Kein Blinken, kein Puls, nichts Coralfarbenes. */
body.ton-einladung-an .sound-control .wave i { animation: atmen 3s ease-in-out infinite; }
body.ton-einladung-an .sound-control .wave i:nth-child(2) { animation-delay: .12s; }
body.ton-einladung-an .sound-control .wave i:nth-child(3) { animation-delay: .24s; }
body.ton-einladung-an .sound-control .wave i:nth-child(4) { animation-delay: .36s; }
@keyframes atmen { 0%, 62%, 100% { transform: scaleY(1); } 74% { transform: scaleY(2.6); } }
@media (prefers-reduced-motion: reduce) {
  .ton-einladung { transition: none; }
  body.ton-einladung-an .sound-control .wave i { animation: none; }
}
/* DIE FAHRT. Das Zeichen ist ein Dreieck (aus) bzw. zwei Balken (laeuft) -- gebaut aus
   Rahmen und Pseudoelementen, damit kein Icon-Satz noetig ist. Neutral wie der Ton-Schalter:
   Coral gehoert dem Ask, nicht der Bedienung (korrekturen.md 15.07.). Der Tempo-Zusatz "1,5x"
   steht nur, wenn er gilt -- ein Knopf, der immer eine Zahl traegt, liest sich wie eine Anzeige. */
/* Waehrend der Fahrt kein Einrasten: `scroll-snap` greift am Touch im Ruhezustand und wuerde
   jeden Halt am Deckblatt in einen Sprung verwandeln. */
html.faehrt { scroll-snap-type: none !important; }
.fahrt-control { display: flex; align-items: center; gap: 9px; }
.fahrt-zeichen { position: relative; width: 11px; height: 12px; display: inline-block; }
.fahrt-zeichen::before, .fahrt-zeichen::after { content: ""; position: absolute; top: 0;
  transition: opacity .2s, width .2s, border-width .2s; }
/* aus: ein Dreieck nach rechts */
.fahrt-control[data-stufe="0"] .fahrt-zeichen::before { left: 1px; width: 0; height: 0;
  border-left: 10px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent; }
.fahrt-control[data-stufe="0"] .fahrt-zeichen::after { opacity: 0; }
/* laeuft, naechster Tipp = schneller: zwei Dreiecke */
.fahrt-control[data-stufe="1"] .fahrt-zeichen::before { left: 0; width: 0; height: 0;
  border-left: 6px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent; }
.fahrt-control[data-stufe="1"] .fahrt-zeichen::after { left: 6px; width: 0; height: 0;
  border-left: 6px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent; }
/* laeuft schnell, naechster Tipp = anhalten: zwei Balken */
.fahrt-control[data-stufe="2"] .fahrt-zeichen::before { left: 0; width: 3px; height: 12px; background: currentColor; }
.fahrt-control[data-stufe="2"] .fahrt-zeichen::after  { left: 7px; width: 3px; height: 12px; background: currentColor; }
.fahrt-control .fahrt-wort { font-weight: inherit; }
@media (max-width: 900px) { .fahrt-control .fahrt-wort { display: none; } }
/* Reduced motion: die Seite bewegt sich dort nicht von selbst, also gibt es den Knopf nicht. */
@media (prefers-reduced-motion: reduce) { .fahrt-control { display: none; } }
.sound-control { display: flex; align-items: center; gap: 9px; }
.sound-control .wave i { transform-origin: center; }
.wave { height: 10px; display: flex; align-items: center; gap: 2px; }
.wave i { display: block; width: 1px; height: 3px; background: currentColor; }
.sound-control[aria-pressed="true"] .wave i { animation: wave .7s ease-in-out infinite alternate; }
.sound-control[aria-pressed="true"] .wave i:nth-child(2) { animation-delay: -.3s; }
.sound-control[aria-pressed="true"] .wave i:nth-child(3) { animation-delay: -.55s; }
/* MENUE AUCH AM DESKTOP (04.09.2026). Seit B3 fuehrte dort allein die Zeitachse -- die zweite
   Ebene (Fotografie, Film, Drohne, AI Visuals, die drei KI-Unterpunkte, Ablauf, Fragen) war am
   Desktop nur durch Scrollen erreichbar. Gleicher Knopf, gleiches Menue wie am Handy. */
.chrome-actions .index-control { display: inline-flex; gap: 8px; align-items: center; }
.index-control i, .index-close i { position: relative; width: 13px; height: 13px; border: 1px solid currentColor; border-radius: 50%; }
.index-control i::before, .index-control i::after, .index-close i::before, .index-close i::after { content: ""; position: absolute; left: 3px; right: 3px; top: 5px; height: 1px; background: currentColor; }
.index-control i::after { transform: rotate(90deg); }

.audio-player {
  --audio-progress: 0;
  position: fixed;
  z-index: 740;
  top: 72px;
  right: 28px;
  width: min(410px, calc(100vw - 40px));
  color: var(--canvas);
  background:
    linear-gradient(rgba(241,232,215,.042) 1px, transparent 1px),
    linear-gradient(90deg, rgba(241,232,215,.042) 1px, transparent 1px),
    rgba(8, 8, 7, .93);
  background-size: 48px 48px, 48px 48px, auto;
  border: 1px solid rgba(241,232,215,.26);
  box-shadow: 0 34px 100px rgba(0,0,0,.44);
  backdrop-filter: blur(26px) saturate(1.08);
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, -12px, 0) scale(.975);
  transform-origin: 100% 0;
  transition: opacity .35s, visibility .35s, transform .65s var(--ease-out);
}
.audio-player.open { opacity: 1; visibility: visible; transform: none; }
.audio-player::before { content: ""; position: absolute; left: -1px; top: -1px; width: 58px; height: 2px; background: var(--signal); }
.audio-head { padding: 16px 17px 14px; display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 1px solid rgba(241,232,215,.16); }
.audio-head p { margin: 0; display: grid; gap: 5px; }
.audio-head p span { font: 9px/1 var(--mono); letter-spacing: .17em; text-transform: uppercase; }
.audio-head p b { color: var(--stone); font: 400 6px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
.audio-close { position: relative; width: 24px; height: 24px; padding: 0; border: 1px solid rgba(241,232,215,.28); border-radius: 50%; color: inherit; background: none; cursor: pointer; transition: border-color .25s, transform .45s var(--ease-out); }
.audio-close:hover { border-color: var(--signal); transform: rotate(90deg); }
.audio-close i::before, .audio-close i::after { content: ""; position: absolute; left: 7px; right: 7px; top: 11px; height: 1px; background: currentColor; transform: rotate(45deg); }
.audio-close i::after { transform: rotate(-45deg); }
.audio-now { min-height: 104px; padding: 20px 17px 17px; display: grid; grid-template-columns: 42px 1fr 44px; align-items: center; gap: 12px; }
.audio-number { align-self: start; color: var(--signal); font: 400 30px/.82 var(--mono); letter-spacing: -.08em; }
.audio-now p { min-width: 0; margin: 0; display: grid; gap: 7px; }
.audio-now strong { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 17px; line-height: 1; letter-spacing: -.025em; font-weight: 600; }
.audio-now em { color: var(--stone); font: 400 6px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
.audio-play { position: relative; width: 44px; height: 44px; padding: 0; border: 1px solid rgba(241,232,215,.5); border-radius: 50%; color: inherit; background: none; cursor: pointer; transition: color .25s, background .25s, transform .45s var(--ease-out); }
.audio-play:hover { color: var(--black); background: var(--signal); border-color: var(--signal); transform: scale(1.06); }
.audio-play i { position: absolute; left: 17px; top: 14px; width: 0; height: 0; border-top: 7px solid transparent; border-bottom: 7px solid transparent; border-left: 11px solid currentColor; }
.audio-play[aria-pressed="true"] i { left: 15px; top: 14px; width: 13px; height: 14px; border: 0; border-left: 4px solid currentColor; border-right: 4px solid currentColor; }
.audio-timeline { padding: 0 17px 14px; display: grid; grid-template-columns: auto auto; gap: 6px 10px; color: var(--stone); font: 6px/1 var(--mono); letter-spacing: .08em; }
.audio-timeline i { position: relative; grid-column: 1 / -1; height: 1px; overflow: visible; background: rgba(241,232,215,.18); }
.audio-timeline i b { position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: var(--signal); transform: scaleX(var(--audio-progress)); transform-origin: left; }
.audio-timeline i b::after { content: ""; position: absolute; right: -2px; top: -2px; width: 5px; height: 5px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 14px rgba(255,58,94,.75); }
.audio-timeline em { justify-self: end; font-style: normal; }
.audio-tracks { margin: 0; padding: 0; list-style: none; border-top: 1px solid rgba(241,232,215,.16); }
.audio-tracks li + li { border-top: 1px solid rgba(241,232,215,.1); }
.audio-tracks button { width: 100%; min-height: 55px; padding: 10px 17px; display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 10px; border: 0; color: inherit; background: transparent; text-align: left; cursor: pointer; transition: background .25s, padding .45s var(--ease-out); }
.audio-tracks button:hover, .audio-tracks button.active { padding-left: 23px; background: rgba(241,232,215,.065); }
.audio-tracks button > b { color: var(--stone); font: 400 7px/1 var(--mono); }
.audio-tracks button.active > b { color: var(--signal); }
.audio-tracks button > span { display: grid; gap: 4px; font-size: 11px; line-height: 1; font-weight: 600; }
.audio-tracks button em { color: var(--stone); font: 400 5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.audio-tracks button > i { color: var(--stone); font: 400 6px/1 var(--mono); font-style: normal; }
.audio-foot { min-height: 55px; padding: 10px 17px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 14px; border-top: 1px solid rgba(241,232,215,.16); }
.audio-skip { display: flex; }
.audio-skip button { width: 25px; height: 25px; padding: 0; border: 1px solid rgba(241,232,215,.24); color: inherit; background: transparent; cursor: pointer; }
.audio-skip button + button { border-left: 0; }
.audio-foot label { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 8px; color: var(--stone); font: 5px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; }
.audio-volume { width: 100%; height: 14px; margin: 0; appearance: none; background: transparent; cursor: pointer; }
.audio-volume::-webkit-slider-runnable-track { height: 1px; background: rgba(241,232,215,.32); }
.audio-volume::-webkit-slider-thumb { width: 7px; height: 7px; margin-top: -3px; appearance: none; border: 0; border-radius: 50%; background: var(--signal); }
.audio-volume::-moz-range-track { height: 1px; background: rgba(241,232,215,.32); }
.audio-volume::-moz-range-thumb { width: 7px; height: 7px; border: 0; border-radius: 50%; background: var(--signal); }
.audio-foot > p { margin: 0; color: var(--stone); font: 5px/1.25 var(--mono); letter-spacing: .09em; text-align: right; text-transform: uppercase; }



.index-room { position: fixed; z-index: 800; inset: 0; padding: 22px 28px; display: grid; grid-template-rows: auto 1fr auto; overflow-y: auto; overscroll-behavior: contain; color: var(--ink); background: var(--canvas); visibility: hidden; transform: translateY(102%); transition: transform .85s var(--ease-inout), visibility .85s; }
.index-room.open { visibility: visible; transform: none; }
.index-film { position: absolute; inset: 0; background-image: var(--index-image, url("assets/stills/film.webp")); background-size: cover; background-position: center; filter: saturate(.58) contrast(1.15); opacity: .17; transition: background-image .3s, opacity .3s; transform: scale(1.05); }
.index-ground { position: absolute; inset: 0; background: linear-gradient(90deg, rgba(241,232,215,.96), rgba(241,232,215,.79) 55%, rgba(241,232,215,.92)); }
.index-ground::after { content: ""; position: absolute; inset: 0; opacity: .25; background-image: linear-gradient(rgba(26,23,18,.11) 1px, transparent 1px), linear-gradient(90deg, rgba(26,23,18,.1) 1px, transparent 1px); background-size: 12.5vw 12.5vw; }
.index-room header, .index-room footer, .index-room ol { position: relative; z-index: 2; }
.index-room header { padding-bottom: 18px; display: grid; grid-template-columns: 1fr auto 1fr; align-items: start; border-bottom: 1px solid var(--line-dark); }
.index-room header img { width: 62px; height: 58px; object-fit: contain; }
.index-room header p { margin: 3px 0 0; font: 8px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
.index-room header p span { margin-left: 28px; opacity: .56; }
.index-close { justify-self: end; display: flex; align-items: center; gap: 9px; appearance: none; border: 0; background: none; cursor: pointer; font: 8px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.index-close i::before { transform: rotate(45deg); }
.index-close i::after { transform: rotate(-45deg); }
.index-room ol { margin: auto 0; padding: 0; list-style: none; }
.index-room li { border-bottom: 1px solid var(--line-dark); }
.index-room li a { min-height: 8.5vh; display: grid; grid-template-columns: 8vw 1fr auto; align-items: center; color: inherit; text-decoration: none; transition: padding .5s var(--ease-out), color .25s; }
.index-room li a:hover { padding-left: 1.2vw; color: var(--signal); }
.index-room li b { font: 400 10px/1 var(--mono); }
.index-room li span { font-size: clamp(42px, 7vw, 118px); line-height: .78; letter-spacing: -.065em; text-transform: uppercase; }
.index-room li em { font-size: 17px; font-style: italic; }
.index-room li.index-product { margin-top: 1.2vh; border-top: 1px solid var(--signal); }
.index-room li.index-product a { min-height: 6.5vh; }
.index-room li.index-product b { color: var(--signal); letter-spacing: .12em; text-transform: uppercase; }
.index-room li.index-product span { color: var(--signal); font-size: clamp(38px, 5.6vw, 92px); }
/* Das Index-Overlay IST seit B5 das Mobil-Menue — sein Fuss ist also Bedienung und faellt
   unter Audit 8.1: >= 11 px Schrift, >= 44 px Trefferflaeche. Vorher 8 px und 14 px hoch. */
.index-room footer { padding-top: 14px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 26px;
  justify-content: space-between; border-top: 1px solid var(--line-dark);
  font: 400 11px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; }
.index-room footer a, .index-room footer button { min-height: 44px; display: inline-flex; align-items: center;
  padding: 0; border: 0; background: none; cursor: pointer; color: inherit; text-decoration: none;
  font: inherit; transition: color .25s; }
.index-room footer a:hover, .index-room footer button:hover { color: var(--signal); }
/* SEITENTEILE im Mobil-Menue (30.08.2026). Zwischen den Welten (oben) und den Werkzeugen
   (Musik/WhatsApp im Fuss) fehlte die Ebene der Seitenteile — "Ablauf" und "Fragen" waren auf
   keinem Geraet verlinkt. Gleiche Trefferflaeche und Schriftgroesse wie der Fuss (Audit 8.1:
   >= 11 px, >= 44 px), aber eigene Zeile mit Trennlinie, damit die Hierarchie lesbar bleibt. */
/* Zweite Ebene. Am Desktop fuehrt die Zeitachse, dort bleibt das Menue wie bisher —
   deshalb ist die Unterebene hier aus und wird nur mobil eingeschaltet. */
.index-unter { display: flex; flex-wrap: wrap; gap: 0 26px; margin: -8px 0 16px 8vw; padding: 0; list-style: none; }
.index-unter a { min-height: 32px; display: inline-flex; align-items: center; color: inherit; text-decoration: none; font: 400 12px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .72; transition: color .25s, opacity .25s; }
.index-unter a::before { content: none; }
.index-unter a:hover, .index-unter a:focus-visible { color: var(--signal); opacity: 1; }
.index-teile { position: relative; z-index: 2; margin-top: auto; padding-top: 12px;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 22px;
  border-top: 1px solid var(--line-dark);
  font: 400 11px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; }
.index-teile a { min-height: 44px; display: inline-flex; align-items: center;
  color: inherit; text-decoration: none; transition: color .25s; }
.index-teile a:hover { color: var(--signal); }
.index-teile a[href="#anfrage"] { color: var(--signal); }

:root { --pace: 4.2; }   /* vh Scrollstrecke je bewegungstragendem Bild — die EINE Stellschraube.
                            2,8 → 3,4 am 29.07. (4,2 war ein Umweg — die Textdauer
                            haengt am Zeitboden in app.js, nicht an der Strecke): „insgesamt zu schnell", danach „verschwindet
                            deutlich zu schnell" an 16 Textstellen (Jascha). */
/* 31.08.2026 — `--motion` folgt jetzt der BILDZAHL, nicht mehr der Bewegungsmenge.
   Grund (Jascha: „die Scrollgeschwindigkeit ist nicht sauber"): die Verteilung nach
   Bewegungsmenge hatte das Tempo um Faktor 4,4 gespreizt. Gemessen in px Scrollstrecke
   je Bild, mobil: drone 10,4 · systems 11,7 · finale 11,6 gegen visuals 45,9 —
   dieselbe Handbewegung liess den Film mal rasen, mal zaehfluessig ziehen.
   Jede Sektion steht jetzt auf 32,0 px/Bild. Die Zahl 32 ist kein Ideal, sondern der
   Wert, auf dem prologue, film, web und photography ohnehin schon lagen und zu dem es
   nie eine Klage gab. `--motion` = Bildzahl im Fenster minus Anlauf, umgerechnet:
     motion = (32 * (span - anlauf) / (vh/100) - ein) / pace     [vh 844, pace 2.3 mobil]
   ⚠️ Damit ist die GLEICHMAESSIGKEIT strukturell in `--motion` verankert und die
   Gesamtlaenge haengt allein an `--pace`. Wer die Seite insgesamt schneller oder
   langsamer will, aendert NUR `--pace` — das haelt die Sektionen zueinander im Lot.
   Wer `--motion` einzeln anfasst, verschiebt genau die Spreizung wieder hinein.
   Nachpruefen mit tools/_tempo-inventur-tmp.mjs (Spalte px/Bild muss flach sein).
   Vorher galt: Hoehe folgt der Bewegungsmenge (Plan v1 A2, tools/frame-fenster.py) —
   ausgetragen 31.08.2026, ersetzt durch die Bildzahl-Normierung. */
/* DIE EINE BUEHNE (Engine-Umbau 26.07.2026). Fest im Viewport, EIN Canvas, kein Nachbar
   — damit kann es keine zweite Bildflaeche und keine Kante dazwischen mehr geben.
   Die Inhalts-Sektionen sind deckend und liegen mit z-index 1 darueber: sie schieben sich
   beim Scrollen ueber das Bild („Licht aus") und geben es wieder frei („Licht an").
   Deshalb braucht KEINER dieser Uebergaenge zusaetzliche Scrollstrecke — nur die vier
   echten Bild-zu-Bild-Blenden haben eine (--aus, s. u.). */
/* Desktop und Browser ohne iOS-Liquid-Glass behalten die bewaehrte fixed/svh-Buehne.
   Der iPhone-Pfad darunter ueberschreibt genau diese Verankerung: Die Messung
   screen.height 896 / innerHeight 695 / lvh 735 hat gezeigt, dass weder Hoehenwahl noch
   Ueberstand das Problem loesen. Entscheidend ist, am Rand keine viewportgebundene
   fixed/sticky-Flaeche mehr anzubieten. */
/* 31.08.2026 (Jascha am iPad): beim RUNTERscrollen stand unter jedem Filmteil ein
   schwarzer Streifen, beim Hochscrollen war er weg. Ursache war `100svh` — die KLEINE
   Viewporthoehe, also die mit sichtbarer Safari-Leiste. Faehrt die Leiste beim
   Runterscrollen weg, wird das Fenster hoeher (gemessen am iPhone: 695 -> 735), die
   fixed Buehne bleibt aber auf der kleinen Hoehe und gibt unten eine Luecke frei.
   `100lvh` ist die GROSSE Viewporthoehe: die Buehne ist immer so hoch wie das Fenster
   ohne Leiste. Steht die Leiste, liegt der unterste Streifen des Films dahinter — bei
   einer Hintergrund-Bildflaeche unsichtbar und folgenlos. `100vh` davor ist der
   Rueckfall fuer Browser ohne lvh; auf iOS entspricht es ohnehin der grossen Hoehe.
   ⚠️ NICHT auf `dvh` umstellen: das folgt der Leiste in jedem Bild und liesse Buehne
   und Leinwand waehrend der Geste dauernd neu vermessen.
   Die Textebene `.scene-layer` bleibt bewusst auf `100svh` — Text muss VOR der Leiste
   liegen, nicht dahinter. */
/* Bildnachweis: klein, ruhig, unten links. Neutral gehalten (Creme auf dem Film) --
   kein Signalrot, das ist der Akzentfarbe vorbehalten und waere hier reine Deko. */
.bildquelle { position: fixed; z-index: 6; left: max(18px, 4vw); bottom: max(14px, env(safe-area-inset-bottom));
  margin: 0; max-width: min(560px, 74vw); color: var(--canvas); opacity: 0;
  font: 8px/1.5 var(--mono); letter-spacing: .14em; text-transform: uppercase;
  text-shadow: 0 1px 6px rgba(0,0,0,.55); transition: opacity .45s ease; pointer-events: none; }
.bildquelle.sichtbar { opacity: .52; }
@media (max-width: 900px) { .bildquelle { font-size: 7px; max-width: 68vw; bottom: max(10px, env(safe-area-inset-bottom)); } }

.buehne { position: fixed; z-index: 0; inset: 0 0 auto; height: 100vh; height: 100lvh; overflow: hidden; background: var(--black); }
.safari-edge-frame { display: none; position: absolute; z-index: 0; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.buehne-bild { z-index: 1; }
/* Deckungsgleich mit der Leinwand. Gleicher z-index wie .buehne-bild, aber spaeter im
   Markup -- damit liegt es exakt darueber und unter allen Koernungs- und Textebenen.
   Die Uebergabe ist kurz (130 ms): lang genug, dass es keine harte Kante gibt, kurz genug,
   dass niemand eine Blende sieht. */
.endframe-loop { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 50%; pointer-events: none;
  opacity: 0; transition: opacity .13s linear; }
.endframe-loop.laeuft { opacity: 1; }
.finale-ambient { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%;
  pointer-events: none; opacity: 0; transition: opacity .25s linear; }
.finale-ambient.laeuft { opacity: 1; }
/* Mobil freigeschaltet (01.09.2026). ⚠️ Dort zeigt der Canvas NICHT die Bildmitte: die
   mobilen Frames sind art-direktiert beschnitten (Builder: crop=405:720:'400+70*t/10.042'),
   am letzten Bild liegt das Fenster bei 470..875, die Motivmitte also bei 672,5 von 1280.
   Mit object-fit cover skaliert die Quelle auf 1500 px Breite, Ueberhang 1110 px; damit die
   Motivmitte im Kasten mittig sitzt, muss object-position X = 53,4 % statt 50 % sein.
   Bei 50 % waere die Uebergabe um rund 30 Quellpixel versetzt -- sichtbar als kleiner Ruck. */
@media (max-width: 900px) { .endframe-loop { object-position: 53.4% 50%; } }
.buehne-bild, .buehne-overlay { position: absolute; inset: 0; width: 100%; height: 100%; }

/* iOS Safari 26 / Liquid Glass.
   `fixed` oder `sticky` am oberen/unteren Viewportrand aktiviert Safaris deckende Color
   Extension. Das ist der Grund, warum der Canvas-Test die blaue CSS-Flaeche statt des
   orangefarbenen Canvas hinter den Leisten zeigte. Auf dem iPhone sind Buehne, Header und
   Texte deshalb absolut im Dokument. Buehne, Header und der aktive Take folgen in derselben
   rAF-Uhr ausschliesslich dem Dokument-Scroll. Das DOM-Bild unter dem Canvas liefert Safari
   echte Bildpixel fuer die Glas-Bereiche; der sichtbare Film bleibt der bestehende Canvas.
   `translate` ist absichtlich die eigenstaendige CSS-Eigenschaft: bestehende `transform`-
   Animationen der Navigation und der Beats bleiben dadurch unangetastet. */
.ios-edge-to-edge .buehne,
.ios-edge-to-edge .site-chrome {
  position: absolute;
  translate: 0 var(--ios-viewport-y, 0px);
}
.ios-edge-to-edge .buehne { height: var(--ios-stage-height, 100lvh); background: transparent; }
.ios-edge-to-edge .safari-edge-frame { display: block; }
.ios-edge-to-edge .fold { min-height: var(--ios-stage-height, 100lvh); }

.ios-edge-to-edge .scene-layer {
  position: absolute;
  height: var(--ios-stage-height, 100lvh);
  translate: 0 var(--ios-layer-y, 0px);
}
.ios-edge-to-edge .ledger-stage {
  position: absolute;
  inset: 0 0 auto;
  width: 100%;
  translate: 0 var(--ios-ledger-y, 0px);
}
/* Wichtig: die Inhalts-Sektionen waren teils unpositioniert — ihr Hintergrund haette
   dann UNTER der Buehne gemalt und die Buehne haette sie verdeckt. */
main > section, .fold, .site-footer { position: relative; z-index: 1; }

/* --aus = Scrollstrecke der Blende AM ENDE dieser Sektion, in vh. Die Bildfolge laeuft
   waehrend der Blende weiter (beides bewegt sich), deshalb liegt die Blende hier und
   nicht in einer eigenen Sektion. */
/* Kein "+100vh" mehr: der Fortschritt laeuft jetzt ueber die GANZE Sektionshoehe
   (progress = -rect.top / height), nicht ueber die Klebestrecke (height - vh). Die 100vh
   waren der Ueberhang, in dem die geklebte Buehne nach oben weggeschoben wurde — genau
   die Bildschirmhoehe, in der zwei Buehnen gleichzeitig zu sehen waren und nichts Neues
   passierte. 8 Film-Sektionen x 100vh = 800vh reine Leerstrecke, die wegfaellt.
   Die vier handgesetzten Hoehen sind entsprechend ihre alte Klebestrecke (alt minus 100). */
/* --halt = Standzeit am Ende: Strecke, in der das Bild steht, bevor die Blende laeuft. */
/* --halt-text (01.09.2026) ist Lesezeit, kein Film: eine Strecke, in der die Filmachse
   stillsteht. Sie zaehlt zur Hoehe, treibt aber nichts an -- deshalb bleibt px/Bild gleich. */
/* position: relative macht die Sektion nur zum Bezugsrahmen fuer .sprungmarke.
   Ohne z-index entsteht KEIN neuer Stacking-Context, und .scene-layer ist fixed —
   an der Buehne aendert sich dadurch nichts. */
.scrub-scene { position: relative; }
/* Eine Sprungmarke ist ein Ziel ohne Aussehen: sie sitzt an dem Anteil der Sektion,
   an dem der zugehoerige Textbeat seinen peak hat (--bei). Nur so lassen sich
   Abschnitte INNERHALB einer Scrub-Sektion ueberhaupt anspringen. */
.sprungmarke { position: absolute; left: 0; top: calc(var(--bei, 0) * 100%);
  width: 1px; height: 1px; pointer-events: none; }
.scrub-scene { height: calc((var(--motion, 120) * var(--pace) + var(--ein, 0) + var(--aus, 0) + var(--halt, 0) + var(--halt-text, 0)) * 1vh); background: transparent; }
.prologue-preroll { display: none; }
/* Vier feste Hoehen sind am 29.07. entfallen. Sie stammen aus dem Codex-Bestand und haben
   `--motion`/`--pace` fuer prologue, drone, systems und finale ausgehebelt — vier von acht Takes
   folgten der Verteilung nach Bewegungsmenge gar nicht, und die Verteilung vom 28.07. griff dort
   ins Leere. Es gibt jetzt genau EINE Hoehenregel; wer ein Tempo aendern will, aendert `--motion`
   (je Take) oder `--pace` (global). Keine Ausnahmen mehr, sonst wandert die Zahl wieder aus. */
/* Text-Ebene: fest im Viewport, damit die Beats exakt dort liegen wie vorher in der
   geklebten Buehne (gleiche left/top-Werte, gleiche 100svh). Nur eingeschaltet, solange
   die Sektion im Fenster ist — sonst bliebe Text als Geist stehen, weil die Beats bei
   „nicht in der Naehe" nicht mehr nachgerechnet werden. pointer-events: none ist Pflicht,
   sonst schluckt eine unsichtbare Vollbild-Ebene alle Klicks. */
.scene-layer { display: none; position: fixed; z-index: 20; inset: 0 0 auto; height: 100svh; overflow: hidden; pointer-events: none; }
.scene-layer.is-live { display: block; }
.bild-text { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Die Zeitachse belegt dauerhaft die rechte Spalte — das Arbeiten-Archiv muss davor
   enden, sonst laufen Case-Fotos unter den Labels durch (am Kontaktbogen 27.07. gesehen). */
.ledger-stage { position: sticky; top: 0; height: 100svh; overflow: hidden; padding-left: var(--nav-w); }
.scene-grade, .scene-grid, .scene-grain, .scene-vignette { position: absolute; inset: 0; pointer-events: none; }
.scene-grade { z-index: 2; background: linear-gradient(180deg, rgba(3,6,8,.32), transparent 28%, transparent 70%, rgba(3,3,2,.52)), linear-gradient(90deg, rgba(4,5,5,.22), transparent 28%, transparent 72%, rgba(4,4,3,.21)); }
.scene-grid { z-index: 3; opacity: .11; background-image: linear-gradient(rgba(241,232,215,.36) 1px, transparent 1px), linear-gradient(90deg, rgba(241,232,215,.31) 1px, transparent 1px), linear-gradient(27deg, transparent 49.93%, rgba(241,232,215,.27) 50%, transparent 50.07%); background-size: 12.5vw 12.5vw, 12.5vw 12.5vw, 100% 100%; }
.scene-grain { z-index: 4; opacity: .09; mix-blend-mode: soft-light; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 160 160' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.78' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.9'/%3E%3C/svg%3E"); }
.scene-vignette { z-index: 5; box-shadow: inset 0 0 18vw rgba(0,0,0,.45); }
.buehne-overlay { z-index: 3; pointer-events: none; mix-blend-mode: screen; }

.story-beat { --beat-alpha: 0; position: absolute; z-index: 20; opacity: var(--beat-alpha); transform: translate3d(var(--beat-x, 0), var(--beat-y, 0), 0); pointer-events: none; will-change: opacity, transform; }
.story-beat a { pointer-events: auto; }
.hero-lock { left: calc(6vw + var(--nav-w)); top: 50%; width: clamp(210px, 24vw, 380px); transform: translateY(-50%); }
.kinetic-mark { position: relative; height: min(53vh, 450px); }
.kinetic-mark img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; object-position: left center; }
.kinetic-mark .mark-register { opacity: calc(var(--beat-alpha) * .45); mix-blend-mode: screen; }
.kinetic-mark .red { transform: translate(calc((1 - var(--beat-alpha)) * -44px), 5px); filter: sepia(1) saturate(18) hue-rotate(307deg) brightness(1.3); }
.kinetic-mark .gold { transform: translate(calc((1 - var(--beat-alpha)) * 48px), -3px); filter: sepia(1) saturate(8) hue-rotate(358deg) brightness(.95); }
.hero-lock > p { margin: 10px 0 0; font: 8px/1.3 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.opening-thesis { left: calc(4vw + var(--nav-w)); right: 4vw; bottom: 8vh; }
.coordinate { margin: 0 0 17px; display: flex; gap: 28px; font: 8px/1 var(--mono); letter-spacing: .15em; text-transform: uppercase; }
.opening-thesis h2 { margin: 0; font-size: clamp(44px, 7vw, 102px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.opening-thesis h2 span, .opening-thesis h2 strong { display: block; }
.opening-thesis h2 span { transform: translateX(calc((1 - var(--beat-alpha)) * -12vw)); }
.opening-thesis h2 strong { padding-left: 17vw; color: var(--signal); font-style: italic; transform: translateX(calc((1 - var(--beat-alpha)) * 12vw)); }

.scene-copy { width: min(870px, 75vw); bottom: 10vh; }
.copy-left { left: calc(5vw + var(--nav-w)); }
.copy-right { right: 5vw; max-width: min(82vw, 1120px); text-align: right; }
.chapter-tag { margin: 0 0 17px; display: flex; gap: 16px; align-items: center; font: 8px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.chapter-tag::after { content: ""; width: 84px; height: 1px; background: currentColor; opacity: .58; transform: scaleX(var(--beat-alpha)); transform-origin: left; }
.copy-right .chapter-tag { justify-content: flex-end; }
.copy-right .chapter-tag::after { order: -1; transform-origin: right; }
.scene-copy h2 { margin: 0; font-size: clamp(38px, 5.2vw, 80px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.scene-copy h2 em { color: var(--signal); font-style: italic; font-weight: 600; text-transform: none; }
.scene-copy > p:last-child { width: min(430px, 72vw); margin: 28px 0 0; font-size: clamp(17px, 1.55vw, 24px); line-height: 1.18; }
.copy-right > p:last-child { margin-left: auto; }
.light-copy { color: var(--canvas-hi); text-shadow: 0 2px 24px rgba(0,0,0,.28); }
.portal-type { inset: 50% 3vw auto calc(3vw + var(--nav-w)); transform: translateY(-50%); color: var(--canvas); font-size: clamp(130px, 23vw, 360px); line-height: .63; letter-spacing: -.09em; text-transform: uppercase; }
.portal-type span { display: block; transform: translateX(calc((1 - var(--beat-alpha)) * -14vw)); }
.portal-type span + span { padding-left: 30vw; transform: translateX(calc((1 - var(--beat-alpha)) * 14vw)); }
.whisper { left: calc(6vw + var(--nav-w)); top: 18vh; width: min(720px, 86vw); }
.whisper > p { font: 8px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; }
.whisper h2 { margin: 15px 0 0; font-size: clamp(35px, 4.6vw, 70px); line-height: .92; letter-spacing: -.02em; text-transform: uppercase; }
.whisper strong { color: var(--signal); font-style: italic; }
/* Erste Anfrage-Moeglichkeit im Fluss (~5 % Tiefe) — Muster wie .finale-copy a */
.whisper a { margin-top: 34px; display: inline-flex; align-items: center; gap: 46px; min-height: 44px; padding: 0 0 2px; border-bottom: 1px solid currentColor; text-decoration: none; font: 11px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; transition: color .25s; }
.whisper a:hover { color: var(--signal); }
.giant-object-word { inset: auto 3vw 8vh calc(3vw + var(--nav-w)); font-size: clamp(52px, 8.5vw, 130px); line-height: .85; letter-spacing: -.03em; text-transform: uppercase; }
.giant-object-word span { display: block; }
.giant-object-word span + span { padding-left: 30vw; color: var(--signal); }
.lens-copy { top: 15vh; right: 5vw; width: min(670px, 80vw); text-align: right; }
.lens-copy > p { font: 8px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.lens-copy h2 { margin: 14px 0 0; font-size: clamp(35px, 4.8vw, 74px); line-height: .9; letter-spacing: -.02em; text-transform: uppercase; }
.lens-copy strong { color: var(--signal); }
.fog-statement { inset: auto 4vw 9vh calc(4vw + var(--nav-w)); text-align: center; }
.fog-statement > p { margin: 0 0 14px; font: 8px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; }
.fog-statement h2 { margin: 0; font-size: clamp(40px, 5.8vw, 92px); line-height: .9; letter-spacing: -.03em; }
.fog-statement strong { color: var(--signal); }
.mirror-specs { right: 5vw; bottom: 9vh; width: min(670px, 82vw); }
.mirror-specs > p { margin: 0; padding: 9px 0; display: grid; grid-template-columns: 48px 1fr; border-top: 1px solid var(--line-light); font: 8px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
.mirror-specs h2 { margin: 28px 0 0; font-size: clamp(35px, 4.8vw, 78px); line-height: .9; letter-spacing: -.03em; text-align: right; }
.mirror-specs strong { color: var(--signal); }
.visuals-manifest { right: 4vw; bottom: 8vh; width: min(900px, 86vw); text-align: right; }
.visuals-manifest > span { display: inline-block; margin-left: 24px; font: 8px/1 var(--mono); letter-spacing: .15em; }
.visuals-manifest h2 { margin: 16px 0 0; font-size: clamp(40px, 5.8vw, 92px); line-height: .9; letter-spacing: -.03em; }
.visuals-manifest strong { color: var(--signal); }
.focus-copy { left: calc(5vw + var(--nav-w)); bottom: 9vh; width: min(820px, 88vw); }
.focus-copy > p, .finale-copy > p { margin: 0 0 15px; font: 8px/1 var(--mono); letter-spacing: .15em; text-transform: uppercase; }
.focus-copy h2 { margin: 0; font-size: clamp(38px, 5.2vw, 84px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.focus-copy strong { color: var(--signal); }
.finale-copy { inset: 13vh 4vw auto calc(4vw + var(--nav-w)); }
.finale-copy h2 { margin: 0; font-size: clamp(44px, 6.6vw, 102px); line-height: .9; letter-spacing: -.03em; }
.finale-copy h2 strong { color: var(--signal); font-style: italic; }
.finale-copy a { position: absolute; right: 2vw; bottom: -9vh; display: inline-flex; gap: 70px; padding: 15px 0; border-bottom: 1px solid currentColor; text-decoration: none; font: 9px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; }

/* Blenden-Copy. Die sechs Uebergangs-Sektionen sind weg; ihre Schrift lebt als Beat weiter.
   .blende-wort  = „FILM 02" / „FPV 03", laeuft auf dem Fortschritt der Blende.
                   („FOTO 01" ist ersatzlos raus — der Welten-Titel danach sagte dasselbe.)
   .welten-brueck = Brueckensatz am ANFANG einer Welt, liegt auf dem dunklen Bild → hell.
   .blende-brueck = Brueckensatz IM Gesso-Wisch (visuals → systems) → auf Creme, also Ink. */
.blende-wort { z-index: 5; left: calc(4vw + var(--nav-w)); right: 4vw; top: 50%; display: flex; justify-content: space-between; align-items: baseline; color: var(--canvas); mix-blend-mode: difference; transform: translateY(-50%); }
.blende-wort span { font-size: clamp(130px, 23vw, 360px); line-height: .65; letter-spacing: -.09em; }
.blende-wort b { color: var(--signal); font: 400 clamp(30px, 5vw, 78px)/1 var(--mono); }
/* Mehrwortige Blende (01.09.2026): "FILM" ist ein Wort, "DROHNE & FPV" sind drei. Am Bild
   gesehen: der Satz bricht auf zwei Zeilen, und `align-items: baseline` haengt das rote
   Kapitelzeichen dann an die ERSTE Zeile -- es stand mitten im Wort statt am Ende.
   Der Umbruch selbst ist gewollt (<br> im Markup, damit er nicht vom Zufall der Breite
   abhaengt); nur das Zeichen muss mit nach unten. Die Schriftgroesse bleibt: sie kleiner
   zu machen haette dem Wort genau die Wucht genommen, wegen der es da steht. */
.blende-wort.blende-lang { align-items: flex-end; }

/* Rahmenzeile unter der A2Y-Methode: ruhig, nicht als Fussnote versteckt. */
.process-rahmen { margin: 34px 0 0; max-width: 62ch; font: 13px/1.6 var(--mono); letter-spacing: .04em; opacity: .68; }
@media (max-width: 900px) { .process-rahmen { margin-top: 26px; font-size: 12px; } }
.blende-wort.blende-lang span { font-size: clamp(90px, 17vw, 260px); }
/* Die Brueckensaetze kamen mit dem Engine-Umbau dazu und haben die B2-Regel nie bekommen —
   sie lagen bei 72 px, also 124 px UNTER der Zeitachse (Jascha 29.07., am Bild gesehen). */
.welten-brueck, .blende-brueck { z-index: 6; left: calc(5vw + var(--nav-w)); top: 50%; width: min(950px, 86vw); transform: translateY(-50%); }
.welten-brueck { color: var(--canvas); }
.blende-brueck { color: var(--ink); }
.welten-brueck > p, .blende-brueck > p { margin: 0 0 20px; display: flex; gap: 30px; font: 11px/1 var(--mono); letter-spacing: .15em; text-transform: uppercase; }
.welten-brueck h2, .blende-brueck h2 { margin: 0; font-size: clamp(40px, 5.8vw, 92px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
/* Italic bleibt, weil es im Rest der Seite so steht. Doc 16 §4 verbietet Grotesk-Italic —
   dieser Widerspruch ist als `[offen]` im HANDOVER vermerkt und Jaschas Entscheidung,
   nicht meine. Hier nichts stillschweigend anders machen. */
.welten-brueck h2 strong, .blende-brueck h2 strong { color: var(--signal); font-style: italic; }
.welten-brueck > i, .blende-brueck > i { display: block; width: 180px; height: 1px; margin-top: 34px; background: var(--signal); transform-origin: left; transform: scaleX(var(--beat-alpha, 0)); }

/* Welten-Titel als Beat AUF dem Bild (A1) — die vier Cremeseiten sind aufgeloest.
   Nebeneffekt und eigentlicher Grund: der Uebergang endete auf demselben Frame, mit
   dem die Szene beginnt — dazwischen lag die Seite. Jetzt laeuft es bildgleich weiter. */
.world-title { left: calc(5vw + var(--nav-w)); right: 5vw; top: 50%; width: auto; transform: translateY(-50%); }
/* Der Titel liegt auf dem Bild und trifft dort auf helle Stellen (Himmel, Gewand) —
   ohne Traeger bricht die Lesbarkeit weg. Weicher Verlauf von links statt Schatten
   oder Kasten: haelt die Bildbuehne offen und bleibt Doc-16-konform. */
.world-title::before { content: ""; position: absolute; z-index: -1; left: -22vw; right: -30vw; top: -46vh; bottom: -46vh; background: radial-gradient(ellipse at 32% 50%, rgba(6,6,5,.86) 0%, rgba(6,6,5,.62) 34%, rgba(6,6,5,.28) 56%, transparent 74%); }
.title-index { margin: 0 0 22px; display: flex; align-items: center; gap: 12px; font: 10px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; }
.title-index b { color: var(--signal); font-size: 16px; font-weight: 400; }
.world-title h2 { max-width: 16ch; margin: 0; font-size: clamp(40px, 6vw, 96px); line-height: .9; letter-spacing: -.035em; text-transform: uppercase; }
.title-line { max-width: 44ch; margin: 3vh 0 0; font-size: clamp(17px, 1.5vw, 24px); line-height: 1.25; }
.world-title .product-mark { position: absolute; right: 0; top: -9vh; width: 104px; height: 44px; object-fit: contain; }

/* 500vh ist der robuste Fallback ohne JavaScript. Im laufenden Build berechnet
   updateLedgerLength() die Strecke aus der echten Bahnbreite; neue Cases verlaengern
   das Archiv dadurch automatisch, ohne den Rhythmus der bestehenden Karten zu zerstoeren. */
/* LEINWAND (04.09.2026) -- ersetzt die 500-vh-Schleppe. Ruhende Creme-Sektion, Raster aus
   acht Faellen (3 Spalten, Kachel 4:3), je Kachel Poster + stiller Clip beim Zeigen, Nummer,
   Gattung, Name, Ergebniszeile. Darunter die Websites als kleinere Reihe. */
.leinwand { position: relative; padding: 12vh 5vw 12vh calc(5vw + var(--nav-w)); color: var(--ink); background: var(--canvas); }
.leinwand::before { content: ""; position: absolute; inset: 0; opacity: .25; background-image: linear-gradient(rgba(26,23,18,.12) 1px, transparent 1px), linear-gradient(90deg, rgba(26,23,18,.1) 1px, transparent 1px); background-size: 12.5vw 12.5vw; pointer-events: none; }
.leinwand > * { position: relative; z-index: 2; }
.leinwand-kopf { display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 20px 40px; margin-bottom: 7vh; }
.leinwand-kopf > p { grid-column: 1 / -1; margin: 0; font: 11px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; opacity: .72; }
.leinwand-kopf h2 { margin: 0; font-size: clamp(35px, 4.6vw, 74px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.leinwand-kopf strong { color: var(--signal); font-style: italic; }
.leinwand-kopf > span { font: 11px/1.6 var(--mono); letter-spacing: .12em; text-transform: uppercase; opacity: .62; text-align: right; }
.leinwand-raster { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5vh 3vw; }
.case { display: block; min-width: 0; color: inherit; text-decoration: none; }
.case figure { position: relative; margin: 0; aspect-ratio: 4 / 3; overflow: hidden; background: var(--stone); }
.case figure img, .case figure video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.case figure img { filter: saturate(.86) contrast(1.02); transition: transform 1s var(--ease-out), filter .4s; }
.case figure video { opacity: 0; transition: opacity .35s; }
.case.spielt figure video { opacity: 1; }
.case:hover figure img { transform: scale(1.04); filter: saturate(1); }
.case > p { margin: 14px 0 6px; display: flex; justify-content: space-between; gap: 12px; font: 11px/1.3 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .72; }
.case > p b { font-weight: 400; color: var(--signal); }
.case h3 { margin: 0; font-size: clamp(24px, 2.2vw, 36px); line-height: .92; letter-spacing: -.04em; text-transform: uppercase; transition: color .25s; }
.case:hover h3 { color: var(--signal); }
.case em { display: block; margin-top: 9px; max-width: 40ch; font-size: 15px; line-height: 1.4; font-style: normal; opacity: .78; }
.case-draft { cursor: default; }
.case-draft:hover figure img { transform: none; filter: saturate(.86) contrast(1.02); }
.case-draft:hover h3 { color: inherit; }
.case-draft figure img { opacity: .55; }
.leinwand-web { margin-top: 9vh; padding-top: 5vh; border-top: 1px solid var(--line-dark); }
.leinwand-web-kopf { margin: 0 0 3vh; display: flex; gap: 14px; font: 11px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; opacity: .72; }
.leinwand-web-kopf b { font-weight: 400; color: var(--signal); }
.leinwand-web-reihe { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 3vh 2vw; }
.case.web figure { aspect-ratio: 16 / 10; }
.case.web h3 { font-size: clamp(17px, 1.3vw, 22px); }
.case.web > p { font-size: 9px; }

.offer-ledger { position: relative; padding: 14vh 5vw 9vh calc(5vw + var(--nav-w)); color: var(--canvas); background: var(--blue-black); overflow: hidden; }
.offer-ledger::before { content: ""; position: absolute; inset: 0; opacity: .12; background-image: linear-gradient(rgba(241,232,215,.2) 1px, transparent 1px), linear-gradient(90deg, rgba(241,232,215,.18) 1px, transparent 1px); background-size: 12.5vw 12.5vw; }
.offer-ledger header, .produktion, .dazu, .offer-note { position: relative; z-index: 2; }
.offer-ledger header > p:first-child { margin: 0; font: 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; opacity: .7; }
.offer-ledger header h2 { margin: 3vh 0 0; font-size: clamp(38px, 5vw, 80px); line-height: .9; letter-spacing: -.035em; text-transform: uppercase; }
.offer-ledger header strong { color: var(--signal); font-style: italic; }
.offer-lead { max-width: 46ch; margin: 26px 0 0; font-size: 18px; line-height: 1.45; opacity: .8; }

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

/* DIE PRODUKTION (30.07.2026, ENT-82/ENT-84). Vorher standen hier drei SET-Spalten als
   Preisleiter — Jascha: „wir hatten beschlossen dass wir Beispiel-Pakete einbauen wie es
   aussehen koennte, aber nicht feste Pakete." ENT-82 nimmt die Paket-Leiter aussen komplett
   raus: es gibt EINE Produktion, die auf den Anlass zugeschnitten wird, mit Festpreis-
   Versprechen statt Stufen. Die vier Bausteine sind bewusst GLEICHWERTIG gesetzt — kein
   Groessenverhaeltnis, keine Nummerierung, keine Hervorhebung, sonst liest man wieder eine
   Leiter hinein. */
.produktion { margin: 8vh 0 0; padding-top: 34px; border-top: 1px solid var(--canvas); }
.produktion h3 { margin: 0 0 30px; font-size: clamp(30px, 3.2vw, 52px); font-weight: 700; line-height: .9; letter-spacing: -.04em; text-transform: uppercase; }

.bausteine { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 26px; }
.bausteine li { padding: 18px 0 0; border-top: 1px solid var(--line-light); font-size: 17px; line-height: 1.35; }

.bausteine-fuss { max-width: 74ch; margin: 34px 0 0; font-size: 15px; line-height: 1.5; opacity: .7; }
.produktion-satz { max-width: 62ch; margin: 26px 0 0; font-size: 19px; line-height: 1.45; }


/* Coral traegt hier Flaeche, weil es der eine Ask der Sektion ist. Ueberall sonst
   in dieser Sektion bleibt Coral Schrift. */
.offer-ask { display: inline-flex; align-items: center; min-height: 48px; margin: 34px 0 0; padding: 0 24px; background: var(--signal); color: var(--black); text-decoration: none; font: 14px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; transition: background .3s; }
.offer-ask:hover { background: var(--canvas); }

.dazu { margin: 11vh 0 0; }
.dazu h3 { margin: 0 0 4px; font: 11px/1 var(--mono); font-weight: 400; letter-spacing: .12em; text-transform: uppercase; opacity: .58; }
.dazu dl { margin: 0; }
.dazu dl > div { display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr) 130px; gap: 0 26px; align-items: baseline; padding: 30px 0; border-bottom: 1px solid var(--line-light); }
.dazu dl > div:first-of-type { border-top: 1px solid var(--line-light); }
.dazu dt { font-size: clamp(19px, 1.7vw, 25px); font-weight: 600; letter-spacing: -.02em; }
.dazu dd { margin: 0; font-size: 15px; line-height: 1.4; opacity: .74; }
.dazu dd b { display: block; font: 14px/1 var(--mono); font-weight: 400; letter-spacing: .06em; opacity: .9; }
.dazu dl > div > dd:last-child { display: contents; }

.offer-note { margin: 7vh 0 0; max-width: 70ch; font: 11px/1.7 var(--mono); letter-spacing: .07em; text-transform: uppercase; opacity: .55; }

/* LINIEN-BLOECKE (30.07.2026, Jascha). Jede der drei juengeren Linien erklaert sich DIREKT
   HINTER IHRER WELT im Film, statt gestapelt am Ende oder auf einer Unterseite: der Besucher
   hat gerade die Welt gesehen, dann steht in einem Bildschirm, was das ist und was es kostet.
   Grund gegen Unterseiten (Jascha 30.07.): die Seite ist eine durchscrollbare Welt, und fuer
   zwei der drei Linien gibt es heute keinen zeigbaren Beweis — eine Unterseite waere Text
   ohne Belege (Doc 28 §4.6). `33` §4/ENT-62 will ohnehin BEIDES: Kern-Station auf der
   Hauptseite, Unterseite spaeter als Vertiefung.
   Dunkel wie die Leistungen-Sektion, damit „Leistung" durchgehend dieselbe Farbe hat. */
.linien-block { position: relative; z-index: 1; padding: 11vh 5vw 10vh calc(5vw + var(--nav-w)); color: var(--canvas); background: var(--blue-black); }
.linien-block::before { content: ""; position: absolute; inset: 0; opacity: .1; background-image: linear-gradient(rgba(241,232,215,.2) 1px, transparent 1px), linear-gradient(90deg, rgba(241,232,215,.18) 1px, transparent 1px); background-size: 12.5vw 12.5vw; pointer-events: none; }
.linien-block > * { position: relative; z-index: 2; }

/* DECKENDE BLOECKE FUELLEN DEN BILDSCHIRM (04.09.2026, Jascha: "sollte beim scrollen ueber die
   ganze seite gehen und nicht nur einen teil bedecken"). Gemessen waren Drei Wege 0,94 (1440)
   und 0,84 (1920) Bildschirme hoch, Websites-Block 0,68, Ablauf 0,69. Die Buehne wechselt ihr
   Bild in dem Moment, in dem die Filmsektion oben hinauslaeuft -- ist der Block kuerzer als
   der Bildschirm, sieht man den Wechsel ueber oder unter ihm (docs/pruef-04-09/03, 04).
   Mindestens eine grosse Viewporthoehe (lvh: die Safari-Leiste darf den Block nicht kuerzen),
   Inhalt vertikal mittig. Zweite Haelfte des Fixes: regie() waehlt im Zwischenraum den Take,
   dessen Kante naeher liegt -- der Wechsel faellt damit auf die Blockmitte. */
.linien-block, .process, .faq, .contact, .a2y-examples { min-height: 100vh; min-height: 100lvh; display: grid; align-content: center; }

.linien-block header > p { margin: 0; display: flex; gap: 14px; font: 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; opacity: .72; }
.linien-block header > p b { color: var(--signal); font-weight: 400; }
.linien-block h2 { margin: 22px 0 6vh; font-size: clamp(32px, 3.8vw, 62px); line-height: .92; letter-spacing: -.035em; text-transform: uppercase; }
.linien-block h2 strong { color: var(--signal); font-style: italic; }

.wege-bilder { margin: -2vh 0 5vh; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.wege-bilder figure { margin: 0; }
.wege-bilder img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; border: 1px solid var(--line-light); filter: saturate(.92); }
.wege-bilder figcaption { margin-top: 8px; font: 400 9px/1.4 var(--mono); letter-spacing: .12em; text-transform: uppercase; opacity: .55; }
.linien-block dl { margin: 0; }
.linien-block dl > div { display: grid; grid-template-columns: minmax(0, 250px) minmax(0, 1fr) 175px; gap: 0 26px; align-items: baseline; padding: 28px 0; border-bottom: 1px solid var(--line-light); }
.linien-block dl > div:first-of-type { border-top: 1px solid var(--line-light); }
.linien-block dt { font-size: clamp(19px, 1.7vw, 26px); font-weight: 600; letter-spacing: -.02em; }
.linien-block dd { margin: 0; font-size: 15px; line-height: 1.45; opacity: .78; }
.linien-block dd b { display: block; font: 15px/1.3 var(--mono); font-weight: 400; letter-spacing: .04em; opacity: 1; }
.linien-block dd b i { display: block; margin-top: 6px; font: 11px/1.3 var(--mono); font-style: normal; letter-spacing: .06em; text-transform: uppercase; opacity: .6; }
.linien-block dl > div > dd:last-child { display: contents; }
.linien-lead { max-width: 62ch; margin: -3vh 0 6vh; font-size: 19px; line-height: 1.45; }
.linien-fuss { max-width: 70ch; margin: 28px 0 0; font-size: 15px; line-height: 1.45; opacity: .7; }
.linien-block .offer-ask { margin-top: 34px; }

/* Die Startseite zeigt bewusst nur noch die drei Richtungen. Vertiefung und Preise
   leben auf den jeweiligen Unterseiten; dieser Block ist Wegweiser, kein Katalog. */
.studio-map dl > div { grid-template-columns: minmax(0, 250px) minmax(0, 1fr); }
.studio-map dd { display: block !important; max-width: 70ch; }
.studio-map h2 { margin-bottom: 4vh; font-size: clamp(30px, 3vw, 48px); }
/* A2Y-Hinweis (B2): eine Zeile, kein Block. Sie steht zwischen den drei Wegen und den
   Knoepfen, deutlich leiser als ein Weg und deutlich lauter als eine Fussnote. */
.wege-hinweis { max-width: 60ch; margin: 4vh 0 3vh; font-size: 17px; line-height: 1.45; opacity: .74; }
.wege-hinweis a { color: inherit; text-underline-offset: 4px; }
.wege-hinweis a:hover, .wege-hinweis a:focus-visible { color: var(--signal); }
.studio-map-actions { display: flex; flex-wrap: wrap; gap: 14px; }
.studio-map-actions .offer-ask.secondary { background: transparent; color: var(--canvas); border: 1px solid var(--line-light); }
.studio-map-actions .offer-ask.secondary:hover { color: var(--black); background: var(--canvas); }

/* AUSLAUF VOR DEN RUHENDEN BLOECKEN (04.09.2026, Jascha am Handy: der Block
   "Was wir uebernehmen" schob sich ueber das laufende Video).
   Die Buehne liegt fixed hinter der Seite; ein ruhender Block im Fluss wandert
   beim Scrollen darueber, sobald er den unteren Rand beruehrt -- also EINE
   Bildschirmhoehe VOR dem Ende der Filmsektion. Gemessen: an dieser Stelle
   aenderte sich das Canvas-Bild noch, die Strecke war nicht zu Ende
   (tools/_framecheck-tmp.mjs, beide Bloecke).
   Der transparente Vorlauf (margin, NICHT padding -- padding traegt den
   Hintergrund und wuerde genauso decken) schiebt den Block genau um diese
   Bildschirmhoehe nach unten: das letzte Bild steht, dann kommt der Block.
   Gilt fuer die zwei Bloecke, die direkt auf eine Filmstrecke folgen. */
/* Ersetzt durch --halt an den beiden Szenen selbst (s. index.html): der Margin
   gehoerte zu KEINER Szene, und die Buehne sprang darin schon auf das Bild der
   naechsten Welt um. --halt laesst die Bildstrecke frueher enden und das letzte
   Bild INNERHALB der Sektion stehen. */

.website-details-grid { max-width: 1080px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
.website-details-grid p { margin: 0; padding: 26px 0 0; border-top: 1px solid var(--line-light); font-size: 17px; line-height: 1.5; opacity: .78; }
.website-details-grid b { display: block; margin-bottom: 8px; color: var(--canvas); font-size: 21px; }

.systems-proof-grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(280px, .55fr); gap: 4vw; align-items: end; }
.systems-proof figure { margin: 0; }
.systems-proof img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border: 1px solid var(--line-light); }
.systems-proof figcaption { margin-top: 10px; font: 8px/1.5 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .54; }
.systems-proof-grid > p { margin: 0; padding-top: 24px; border-top: 1px solid var(--line-light); font-size: 18px; line-height: 1.5; }

.a2y-intro-copy { max-width: 1120px; margin: -2vh 0 9vh; display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(280px, .9fr); gap: 5vw; }
.a2y-intro-copy > p, .a2y-intro-copy > div > p { margin: 0; font-size: 17px; line-height: 1.55; }
.a2y-intro-copy > div { padding-top: 4px; }
.a2y-intro-copy .a2y-intro-choice { margin-bottom: 22px; color: var(--signal); font-size: clamp(21px, 2vw, 30px); line-height: 1.15; letter-spacing: -.02em; }
.a2y-method-label { margin: 0 0 18px; color: var(--signal); font: 8px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.a2y-method-title { margin: 0 0 6vh; font-size: clamp(34px, 4.2vw, 68px); line-height: .92; letter-spacing: -.03em; text-transform: uppercase; }
.a2y-method-title strong { color: var(--signal); font-style: italic; }
.a2y-analysis-note { margin-top: 6vh; padding: 30px; border: 1px solid var(--line-light); }
.a2y-analysis-note > p:first-child { margin: 0 0 18px; color: var(--signal); font: 8px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; }
.a2y-analysis-note h3 { margin: 0; font-size: clamp(27px, 3vw, 46px); line-height: 1; letter-spacing: -.03em; text-transform: uppercase; }
.a2y-analysis-note > p:last-child { max-width: 72ch; margin: 22px 0 0; font-size: 16px; line-height: 1.5; opacity: .75; }

.a2y-examples { padding: 12vh 5vw 13vh calc(5vw + var(--nav-w)); color: var(--ink); background: var(--canvas); }
.a2y-examples header { max-width: 1050px; }
.a2y-examples header > p { margin: 0; font: 8px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.a2y-examples header h2 { margin: 3vh 0 22px; font-size: clamp(38px, 5vw, 80px); line-height: .9; letter-spacing: -.035em; text-transform: uppercase; }
.a2y-examples header strong { color: var(--signal); font-style: italic; }
.a2y-examples header > span { display: block; max-width: 62ch; font-size: 17px; line-height: 1.45; }
.a2y-example-list { margin-top: 7vh; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--line-dark); border-bottom: 1px solid var(--line-dark); }
.a2y-example-list article { min-width: 0; padding: 30px 28px 36px 0; border-right: 1px solid var(--line-dark); }
.a2y-example-list article + article { padding-left: 28px; }
.a2y-example-list article:last-child { border-right: 0; }
.a2y-example-type { min-height: 34px; margin: 0 0 28px; display: flex; gap: 14px; font: 8px/1.3 var(--mono); letter-spacing: .11em; text-transform: uppercase; }
.a2y-example-type b { color: var(--signal); font-weight: 400; }
.a2y-example-list dl { margin: 0; }
.a2y-example-list dl > div { padding: 17px 0; border-top: 1px solid rgba(26,23,18,.16); }
.a2y-example-list dt { margin-bottom: 8px; font: 10px/1.3 var(--mono); letter-spacing: .12em; text-transform: uppercase; opacity: .62; }
.a2y-drei dl > div:first-child dd { font-size: 19px; line-height: 1.3; font-weight: 600; letter-spacing: -.01em; }
.a2y-example-list dd { margin: 0; font-size: 15px; line-height: 1.45; }
.a2y-examples-end { max-width: 68ch; margin: 6vh 0 0; font-size: clamp(20px, 2vw, 30px); line-height: 1.3; }
.faq a { color: inherit; text-underline-offset: 4px; }

.a2y-film-shade { position: absolute; z-index: 8; inset: 0; background: linear-gradient(90deg, rgba(7,7,6,.76), rgba(7,7,6,.28) 43%, transparent 72%), linear-gradient(0deg, rgba(7,7,6,.68), transparent 54%); }
.a2y-opening { left: calc(5vw + var(--nav-w)); top: 15vh; width: min(760px, 64vw); color: var(--canvas-hi); text-shadow: 0 2px 24px rgba(0,0,0,.42); }
.a2y-opening > p { margin: 0 0 3vh; display: flex; align-items: center; gap: 20px; color: var(--signal); font: 700 clamp(38px, 5vw, 76px)/.8 var(--sans); letter-spacing: -.06em; }
.a2y-opening > p span { color: var(--canvas-hi); font: 400 8px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.a2y-opening h2 { margin: 0; font-size: clamp(43px, 6.4vw, 98px); line-height: .88; letter-spacing: -.045em; text-transform: uppercase; }
.a2y-opening h2 strong { color: var(--signal); font-style: italic; }
.a2y-product-copy { left: calc(5vw + var(--nav-w)); bottom: 8vh; width: min(740px, 64vw); color: var(--canvas-hi); text-shadow: 0 2px 24px rgba(0,0,0,.46); }
.a2y-product-copy h2 { margin: 0; font-size: clamp(42px, 5.6vw, 86px); line-height: .88; letter-spacing: -.04em; text-transform: uppercase; }
.a2y-product-copy h2 em { color: var(--signal); font-style: italic; }
.a2y-product-copy > p:not(.chapter-tag) { max-width: 48ch; margin: 2.8vh 0 0; font-size: clamp(16px, 1.35vw, 21px); line-height: 1.35; }
.a2y-actions { margin-top: 5vh; display: flex; align-items: center; flex-wrap: wrap; gap: 18px 28px; }
.a2y-actions .offer-ask { margin: 0; }
.a2y-actions .offer-ask:hover { color: var(--black); background: var(--canvas); }
.a2y-actions span { max-width: 38ch; font: 8px/1.3 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .74; }

.process { padding: 9vh 5vw 10vh calc(5vw + var(--nav-w)); color: var(--canvas); background: var(--black); }
.process-stage h2 { margin: 3vh 0 6vh; font-size: clamp(38px, 5.2vw, 84px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.process-stage strong { color: var(--signal); font-style: italic; }
.process ol { margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); list-style: none; border-top: 1px solid var(--line-light); }
.process li { min-height: 22vh; padding: 25px 28px 20px 0; border-right: 1px solid var(--line-light); }
.process li:last-child { border-right: 0; padding-left: 0; }
.process li b { display: block; margin-bottom: 5vh; color: var(--signal); font: 400 9px/1 var(--mono); }
.process li span { font-size: 24px; text-transform: uppercase; }
.process li p { max-width: 320px; font-size: 14px; line-height: 1.35; opacity: .68; }

.faq { padding: 14vh 5vw 14vh calc(5vw + var(--nav-w)); display: grid; grid-template-columns: .9fr 1.1fr; gap: 8vw; color: var(--ink); background: var(--canvas); }
.faq header { position: sticky; top: 16vh; align-self: start; }
.faq header > p { font: 8px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
.faq h2 { margin: 4vh 0 0; font-size: clamp(35px, 4.6vw, 74px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.faq h2 strong { color: var(--signal); font-style: italic; }
.faq-list { border-top: 1px solid var(--line-dark); }
.faq details { border-bottom: 1px solid var(--line-dark); }
.faq summary { min-height: 96px; display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 30px; list-style: none; cursor: pointer; font-size: 21px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary span { color: var(--signal); font: 400 25px/1 var(--mono); transition: transform .35s; }
.faq details[open] summary span { transform: rotate(45deg); }
.faq details p { max-width: 630px; margin: 0 0 28px; font-size: 16px; line-height: 1.45; }

.contact { padding: 14vh 5vw 14vh calc(5vw + var(--nav-w)); display: grid; grid-template-columns: 1fr 1fr; gap: 8vw; color: var(--canvas); background: var(--black); }
.contact-intro { position: sticky; top: 15vh; align-self: start; }
.contact-intro > p { font: 8px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; }
.contact-intro h2 { margin: 5vh 0; font-size: clamp(38px, 5.2vw, 84px); line-height: .9; letter-spacing: -.03em; text-transform: uppercase; }
.contact-intro h2 strong { color: var(--signal); font-style: italic; }
.contact-intro > div { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.contact-intro a { padding: 8px 0; border-bottom: 1px solid var(--line-light); text-decoration: none; font: 8px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.contact-side { min-width: 0; }
.contact-proof { padding-bottom: 34px; border-bottom: 1px solid var(--line-light); }
.proof-head { margin: 0; font: 8px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; opacity: .58; }
.proof-quotes { margin: 26px 0 0; display: grid; gap: 22px; }
.proof-quotes blockquote { margin: 0; padding-left: 17px; border-left: 1px solid var(--line-light); }
.proof-quotes p { margin: 0; font-size: 16px; line-height: 1.42; }
.proof-quotes cite { display: block; margin-top: 9px; font: 8px/1.5 var(--mono); font-style: normal; letter-spacing: .1em; text-transform: uppercase; opacity: .62; }
.proof-names { margin: 26px 0 0; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 10px 24px; font: 8px/1.5 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .62; }
.proof-names a { color: var(--signal); text-decoration: none; border-bottom: 1px solid currentColor; }
.contact form { padding-top: 7vh; }
.contact form[hidden], .contact-done[hidden] { display: none; }
.form-trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.contact label { display: block; border-bottom: 1px solid var(--line-light); }
.contact label span { display: block; padding-top: 23px; font: 400 14px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; opacity: .72; }
.contact input, .contact select, .contact textarea { width: 100%; padding: 13px 0 19px; border: 0; outline: 0; color: var(--canvas); background: transparent; border-radius: 0; font-size: 25px; resize: none; }
.contact select option { color: var(--ink); }
.contact label:focus-within { border-color: var(--signal); }
.contact form button { width: 100%; margin-top: 35px; padding: 22px 0; display: flex; justify-content: space-between; border: 1px solid var(--canvas); color: var(--canvas); background: transparent; cursor: pointer; font: 9px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; transition: color .25s, background .25s; }
.contact form button:hover { color: var(--black); background: var(--signal); border-color: var(--signal); }
.contact form button[disabled] { cursor: progress; opacity: .6; }
.contact form > p { font: 7px/1.45 var(--mono); letter-spacing: .04em; opacity: .54; }
/* Telefon nur auf Wunsch (A6). Der Aufklapper traegt die volle Trefferflaeche und sieht
   aus wie eine Feldzeile — er soll sich nicht als Fussnote lesen. */
.form-telefon { border-bottom: 1px solid var(--line-light); }
.form-telefon > summary { min-height: 44px; display: flex; align-items: center; gap: 9px;
  cursor: pointer; list-style: none; font: 400 14px/1 var(--mono); letter-spacing: .08em;
  text-transform: uppercase; opacity: .72; transition: opacity .25s, color .25s; }
.form-telefon > summary::-webkit-details-marker { display: none; }
.form-telefon > summary::after { content: "+"; margin-left: auto; font-size: 17px; }
.form-telefon[open] > summary::after { content: "–"; }
.form-telefon > summary:hover, .form-telefon > summary:focus-visible { opacity: 1; color: var(--signal); }
.form-telefon label { border-bottom: 0; }
/* Der Zusatz ist ein Hinweis, kein Teil des Feldnamens. Bei .72 las sich
   „BETRIEB / MARKE OPTIONAL“ wie eine einzige Beschriftung (angesehen, 01.09.). */
.contact label span i { font-style: normal; opacity: .45; letter-spacing: .04em; }
.field-error { display: block; padding: 7px 0 3px; color: var(--signal); font: 10px/1.4 var(--mono); font-style: normal; letter-spacing: .06em; }
.form-msg { margin: 22px 0 0; padding: 15px 17px; border: 1px solid var(--signal); color: var(--signal); font: 11px/1.5 var(--mono) !important; letter-spacing: .04em; opacity: 1 !important; }
.contact-done { padding-top: 7vh; }
/* Fokus wandert nach dem Absenden hierher (Ansage fuer Screenreader), aber der Block
   ist nicht bedienbar — ein Rahmen um die halbe Sektion waere nur Rauschen. Die Links
   darin behalten ihre eigene Fokus-Anzeige. */
.contact-done:focus, .contact-done:focus-visible { outline: none; }
.done-eyebrow { margin: 0; font: 8px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase; color: var(--signal); }
.done-head { margin: 22px 0 0; font-size: clamp(26px, 3.6vw, 54px); line-height: .95; letter-spacing: -.03em; text-transform: uppercase; }
.done-text { margin: 20px 0 0; max-width: 460px; font-size: 16px; line-height: 1.45; }
.done-links { margin-top: 26px; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.done-links a { padding: 8px 0; border-bottom: 1px solid var(--line-light); text-decoration: none; font: 9px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; }

/* FUSS AUF DEM FILM (01.09.2026, Jascha) -- und seit 04.09.2026 ein echter Abschluss statt
   einer Bereichszeile mit 7-px-Links. Bleibt durchsichtig auf dem Finalbild: hinter dem letzten
   Take zeichnet regie() das letzte Bild weiter. Unten ein weicher dunkler Grund, damit die
   kleinen Zeilen auf jedem Bildinhalt lesen (der Mondstreifen liegt genau dahinter). */
.site-footer { position: relative; min-height: 66vh; padding: 4vh 5vw 4vh calc(5vw + var(--nav-w)); display: grid; grid-template-columns: 1fr; grid-template-rows: auto auto auto; align-content: end; gap: 5vh 0; color: var(--canvas); background: linear-gradient(to bottom, transparent, rgba(5,5,4,.55) 45%, rgba(5,5,4,.82)); }
.site-footer a { color: inherit; text-decoration: none; transition: color .25s; }
.site-footer a:hover, .site-footer a:focus-visible { color: var(--signal); }
.site-footer > * { text-shadow: 0 1px 7px rgba(0,0,0,.6); }
.fuss-kopf { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px 30px; }
.fuss-claim { margin: 0; font-size: clamp(24px, 3vw, 46px); line-height: .95; letter-spacing: -.03em; text-transform: uppercase; font-weight: 700; }
.fuss-claim em { font-style: normal; color: var(--signal); }
.fuss-ort { margin: 0; font: 400 12px/1.6 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .82; }
.fuss-ort a { margin-left: 14px; color: var(--signal); white-space: nowrap; }
.fuss-spalten { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 30px 4vw; padding-top: 5vh; border-top: 1px solid rgba(241,232,215,.22); }
.fuss-spalten > div { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.fuss-spalten p { margin: 0 0 12px; font: 400 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; opacity: .55; }
.fuss-spalten a { min-height: 34px; display: inline-flex; align-items: center; font-size: 16px; line-height: 1.2; }
.footer-line { margin: 0; padding-top: 18px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 26px; border-top: 1px solid rgba(241,232,215,.22); font: 400 12px/1.6 var(--mono); letter-spacing: .1em; text-transform: uppercase; opacity: .82; }
.footer-line > span { display: inline-flex; flex-wrap: wrap; gap: 6px 22px; }
.fuss-oben { margin-left: auto; }


/* ======================================================================
   ZEIGER B "Punkt + Spur" (04.09.2026, Jaschas Wahl) — Mockup hinter ?cursor=b.
   Punkt folgt sofort (transform in app.js), der Ring laeuft zeitbasiert nach. Ueber dem Film
   traegt der Ring einen senkrechten Strich (Abspielkopf), auf Zielen waechst er und rahmt
   nichts mehr -- er wird zur Flaeche, in der das Wort steht. Farbe wie beim Sucher gemessen. */
.zeiger { display: none; position: fixed; z-index: 1100; left: 0; top: 0; pointer-events: none; color: var(--canvas-hi); }
body.cursor-b .zeiger { display: block; }
body.cursor-b .sucher { display: none !important; }
body.cursor-b, body.cursor-b a, body.cursor-b button, body.cursor-b summary, body.cursor-b .case { cursor: none; }
.zeiger-punkt, .zeiger-ring { position: fixed; left: 0; top: 0; opacity: 0; transition: opacity .2s; }
.zeiger.visible .zeiger-punkt, .zeiger.visible .zeiger-ring { opacity: 1; }
.zeiger-punkt { width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%; background: currentColor; }
.zeiger-ring { width: 34px; height: 34px; margin: -17px 0 0 -17px; border: 1px solid currentColor; border-radius: 50%; opacity: .75;
  display: flex; align-items: center; justify-content: center;
  transition: width .32s var(--ease-out), height .32s var(--ease-out), margin .32s var(--ease-out), background .25s, opacity .2s, border-color .25s; }
.zeiger-ring b { width: 1px; height: 14px; background: currentColor; opacity: 0; transition: opacity .25s, height .25s; }
.zeiger.im-film .zeiger-ring b { opacity: .9; }
.zeiger.im-film .zeiger-ring { opacity: .9; }
.zeiger.rastet .zeiger-ring { width: 58px; height: 58px; margin: -29px 0 0 -29px; opacity: 1; background: color-mix(in srgb, currentColor 12%, transparent); }
.zeiger.rastet .zeiger-ring b { opacity: 0; height: 0; }
.zeiger.rastet .zeiger-punkt { opacity: 0; }
.zeiger-wort { position: absolute; left: 50%; top: 100%; margin-top: 8px; transform: translateX(-50%); white-space: nowrap;
  font: 400 9px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; opacity: 0; transition: opacity .2s; }
.zeiger.rastet.mit-wort .zeiger-wort { opacity: .9; }
.zeiger.auf-hell { color: var(--ink); }
.zeiger.ist-ask { color: var(--signal); }
.zeiger.gedrueckt .zeiger-ring { width: 26px; height: 26px; margin: -13px 0 0 -13px; }
@media (max-width: 900px), (hover: none) { body.cursor-b .zeiger { display: none; } body.cursor-b, body.cursor-b a, body.cursor-b button { cursor: auto; } }
@media (prefers-reduced-motion: reduce) { .zeiger-ring { transition: none; } }

/* EINFUEHRUNG (04.09.2026). Eine Zeile unter dem Kopf, 1,5 s nach dem Laden, weg mit dem
   ersten eigenen Scroll. Desktop wie mobil; kein Speicher-Flag (KOR-12). */
.einfuehrung { position: absolute; right: 28px; top: calc(100% + 6px); margin: 0; text-align: right; font: 400 12px/1.6 var(--mono); letter-spacing: .1em; text-transform: uppercase;
  color: inherit; opacity: 0; transform: translateY(-6px); transition: opacity .6s var(--ease-out), transform .6s var(--ease-out); pointer-events: none; text-shadow: 0 1px 2px rgba(0,0,0,.55); }
.einfuehrung span { opacity: .7; }
.einfuehrung.da { opacity: 1; transform: none; }
.site-chrome.on-light .einfuehrung { text-shadow: none; }
@media (max-width: 900px) { .einfuehrung { right: 18px; top: calc(100% + 4px); max-width: 62vw; font-size: 11px; line-height: 1.5; } }


/* ======================================================================
   DOPPELKONTUR (04.09.2026, Jascha: "voll oft das problem, dass man den cursor nicht sieht,
   und das logo und die punkte in der navigation"). Die Hell/Dunkel-Messung entscheidet die
   FARBE; auf Mitteltoenen, Nebel, hellen Gewaendern reicht das nicht. Deshalb traegt helle
   Schrift ueber dem Film einen ENGEN dunklen Saum -- ohne Leuchten (ein weicher Schein sah
   billig aus, Jascha 04.09.). Dunkle Schrift auf hellem Grund bekommt KEINEN hellen Saum:
   Ink auf Hell liest von selbst, der helle Schein war das, was billig wirkte. */
.zeitachse li a { text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.zeitachse li.auf-hell a { text-shadow: none; }
.zeitachse li a::after { box-shadow: 0 1px 1px rgba(0,0,0,.35); }
.zeitachse li.auf-hell a::after { box-shadow: none; }
.za-linie { box-shadow: 0 0 0 1px rgba(0,0,0,.14); }
.za-fuss button, .za-fuss a { text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.za-fuss.auf-hell button, .za-fuss.auf-hell a { text-shadow: none; }
.site-brand .logo-dark, .site-brand .product-dark { filter: drop-shadow(0 1px 1.5px rgba(0,0,0,.55)); }
.site-brand .logo-light, .site-brand .product-light { filter: none; }
.chrome-actions button { text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.chrome-actions button.auf-hell { text-shadow: none; }
.site-chrome.on-light .chrome-ort { text-shadow: none; }
.zeiger-ring { box-shadow: 0 0 0 1px rgba(0,0,0,.45), inset 0 0 0 1px rgba(0,0,0,.45); opacity: .95; }
.zeiger-punkt { box-shadow: 0 0 0 1.5px rgba(0,0,0,.5); }
.zeiger-ring b { box-shadow: 0 0 0 1px rgba(0,0,0,.45); }
.zeiger.auf-hell .zeiger-ring { box-shadow: none; }
.zeiger.auf-hell .zeiger-punkt { box-shadow: none; }
.zeiger.auf-hell .zeiger-ring b { box-shadow: none; }
.zeiger-wort { text-shadow: 0 1px 2px rgba(0,0,0,.6); }
.zeiger.auf-hell .zeiger-wort { text-shadow: none; }

/* UNTERPUNKTE der Zeitachse: kleiner, eingerueckt, dimmer; der Elternpunkt bleibt markiert. */
.zeitachse li.za-unter a { min-height: 20px; padding-left: 44px; font-size: 9px; letter-spacing: .1em; opacity: .78; }
.zeitachse li.za-unter a::after { left: 30px; width: 6px; }
.zeitachse li.za-unter.hier a::after, .zeitachse li.za-unter a:hover::after { left: 26px; width: 12px; }
.zeitachse li.hier-eltern a { color: var(--signal-ui); }
.zeitachse li.auf-hell.hier-eltern a { color: var(--madder); }

/* NACH OBEN (04.09.2026): unten rechts ab anderthalb Bildschirmen. */
.nach-oben { position: fixed; z-index: 206; right: 22px; bottom: max(22px, env(safe-area-inset-bottom)); width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center; border: 1px solid currentColor; border-radius: 50%;
  color: var(--canvas-hi); text-decoration: none; font: 400 16px/1 var(--mono); background: rgba(7,7,6,.28); backdrop-filter: blur(6px);
  box-shadow: 0 0 0 1px rgba(0,0,0,.45), inset 0 0 0 1px rgba(0,0,0,.35); text-shadow: 0 0 1px rgba(0,0,0,.9);
  opacity: 0; visibility: hidden; transform: translateY(8px); transition: opacity .3s, transform .3s var(--ease-out), visibility .3s, color .25s, background .25s; }
.nach-oben.da { opacity: 1; visibility: visible; transform: none; }
.nach-oben:hover, .nach-oben:focus-visible { color: var(--ink); background: var(--canvas); }
body.scroll-locked .nach-oben { opacity: 0; visibility: hidden; }
@media (max-width: 900px) { .nach-oben { right: 14px; bottom: max(14px, env(safe-area-inset-bottom)); width: 40px; height: 40px; } .audio-player.open ~ .nach-oben { opacity: 0; } }

/* ======================================================================
   DER SUCHER — eigener Mauszeiger (Jascha 28.07., Richtung A)
   Vier duenne Ecken statt eines Kreises, mit Zielpunkt. Ueber einem Ziel rastet der Rahmen
   auf dessen ECHTE Masse ein: er rahmt die Einstellung, statt nur groesser zu werden.
   Kein `mix-blend-mode` mehr — die Farbe wird aus dem Grund gemessen (app.js), damit sie
   gestaltet ist und nicht das, was das Bild gerade hergibt.
   Einrasttempo .26s (Jascha 28.07.: „minimal schneller" gegenueber den .34s im Mockup).
   ====================================================================== */
.sucher { position: fixed; z-index: 1100; left: 0; top: 0; width: 26px; height: 26px;
  opacity: 0; pointer-events: none; color: var(--canvas-hi);
  transition: width .26s var(--ease-out), height .26s var(--ease-out), opacity .2s,
              transform .1s linear, color .3s; }
.sucher.visible { opacity: 1; }
/* Ueber einem Ziel legt der Rahmen eine Strecke zurueck — dort faehrt er weich statt hart. */
.sucher.rastet { transition: width .26s var(--ease-out), height .26s var(--ease-out), opacity .2s,
              transform .26s var(--ease-out), color .3s; }
.sucher i { position: absolute; width: 9px; height: 9px; }
.sucher i::before, .sucher i::after { content: ""; position: absolute; background: currentColor; }
.sucher i::before { width: 100%; height: 1px; }
.sucher i::after { width: 1px; height: 100%; }
.sucher .lo { left: 0; top: 0; }
.sucher .ro { right: 0; top: 0; }
.sucher .lu { left: 0; bottom: 0; }
.sucher .ru { right: 0; bottom: 0; }
.sucher .ro::before { right: 0; } .sucher .ro::after { right: 0; }
.sucher .lu::before { bottom: 0; } .sucher .lu::after { bottom: 0; }
.sucher .ru::before { right: 0; bottom: 0; } .sucher .ru::after { right: 0; bottom: 0; }
.sucher.auf-hell { color: var(--ink); }
/* Coral nimmt der Sucher an genau EINER Stelle an: ueber dem Ask (B1). */
.sucher.ist-ask { color: var(--signal); }
/* Der Zielpunkt sagt, wo geklickt wird — beim Einrasten uebernimmt das der Rahmen. */
.sucher b { position: absolute; left: 50%; top: 50%; width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px;
  border-radius: 50%; background: currentColor; opacity: .8; transition: opacity .25s; }
.sucher.rastet b { opacity: 0; }
/* Ein Wort steht nur dort, wo das Element selbst NICHT sagt, was passiert (Bild, Frage).
   „Anfragen", „WhatsApp" und die Zeitachse sagen es schon — die bekommen nur den Rahmen. */
.sucher .sucher-wort { position: absolute; left: 50%; top: 100%; margin-top: 11px; transform: translateX(-50%);
  white-space: nowrap; font: 400 10px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  opacity: 0; transition: opacity .25s; }
.sucher.rastet.mit-wort .sucher-wort { opacity: 1; }
/* Ruhezustand: eine Schaerfesuche, kein Blinken. */
.sucher:not(.rastet) i { animation: suchen 4.6s ease-in-out infinite; }
@keyframes suchen { 0%, 100% { transform: none; } 50% { transform: scale(1.14); } }
@media (prefers-reduced-motion: reduce) {
  .sucher, .sucher.rastet { transition: opacity .2s; }
  .sucher:not(.rastet) i { animation: none; }
}

@keyframes loadPulse { 50% { transform: scale(.55); opacity: .45; } }
@keyframes wave { to { height: 10px; } }

@media (max-width: 1350px) and (min-width: 901px) {
  .scene-copy,
  .scene-copy.copy-right {
    left: 5vw;
    right: 5vw;
    width: auto;
    max-width: none;
    text-align: left;
  }
  .copy-right .chapter-tag { justify-content: flex-start; }
  .copy-right .chapter-tag::after { order: initial; transform-origin: left; }
  .copy-right > p:last-child { margin-left: 0; }
  .scene-copy h2 { font-size: clamp(38px, 5vw, 66px); }
  .chrome-actions { gap: 13px; }
  /* Ton-Label bleibt sichtbar: ohne Wort sagen vier Striche nicht, was der Schalter tut (Audit 8.1) */
  .chrome-actions > a { padding-inline: 11px; }
}

@media (max-width: 900px) {
  /* 01.09.2026: 2.3 -> 4.2, von Jascha am Geraet abgenommen ("fuehlt sich gut an").
     Der alte Wert war nicht langsam, er war ZU SCHNELL: --pace mal Bildschirmhoehe
     ergibt die Strecke je Bild, und 2.3 bei 844 px lieferte 32,0 px/Bild gegen 62,3
     am Desktop. Gemessen heisst das 1,10 s Film je Bildschirm mobil gegen 0,60 s am
     Desktop -- bei derselben Handbewegung lief mobil fast doppelt so viel Film.
     Mit 4.2 sind es 58,4 px/Bild und ebenfalls 0,60 s: gleiche Filmzeit je
     Bildschirm auf beiden Geraeten. Die Seite ist mobil dadurch 73,1 -> 119,2
     Bildschirme lang (Desktop 117,3). Nachpruefen: tools/_tempo-inventur-tmp.mjs. */
  /* 06.09.: Jascha am Handy: "etwas schnell beim scrollen" -- mobil gibt es keine Uhr, also mehr
     Strecke je Bild: 4.2 -> 5.0 (+19 %). Vergleich am Geraet: ?pace=4.2 / ?pace=5.5. */
  :root { --pace: 5.0; }
  .site-chrome { padding: 16px 18px; grid-template-columns: 1fr auto; }
  .site-brand { width: 50px; height: 47px; }
  .chrome-actions { gap: 10px; }
  /* Dauer-CTA auf Mobil: war ausgeblendet — der einzige Weg zur Anfrage fehlte damit
     komplett (Audit 3.1). Trefferflaeche >= 44 px, Schrift >= 14 px. */
  .chrome-actions > a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 13px; font-size: 14px; letter-spacing: .06em; }
  .chrome-actions > a span { margin-left: 7px; }
  .chrome-actions button { min-height: 44px; padding-block: 0; }
  /* Ton-Label bleibt sichtbar: ohne Wort sagen vier Striche nicht, was der Schalter tut (Audit 8.1) */
  /* Musik-Oeffner faellt mobil weg: neben dem Ton-Schalter redundant, und der Platz
     gehoert dem CTA (zieht B3 „Header entschlacken" fuer Mobil vor). */
  .audio-player { top: auto; right: 12px; bottom: calc(82px + env(safe-area-inset-bottom, 0px)); width: calc(100vw - 24px); max-height: calc(100svh - 110px); overflow-y: auto; transform: translate3d(0, 18px, 0) scale(.985); transform-origin: 50% 100%; }
  .audio-player.open { transform: none; }
  .audio-foot { grid-template-columns: auto 1fr; }
  .audio-foot > p { display: none; }
  /* Fold mobil: Kopf muss atmen, Angebot zuerst, Bild danach. */
  /* Bildstreifen 19 -> 30 svh (04.09.): zwischen "KI-Systeme" und dem Satz stand ein Drittel
     Bildschirm Leerflaeche (margin auto). Der Platz gehoert dem Bild, nicht dem Raster. */
  .fold { padding: 104px 5vw calc(30svh + 22px); }
  .fold-programm { margin-top: 3.5vh; }
  .fold-programm li { grid-template-columns: 40px 1fr; gap: 12px; }
  .fold-claim { margin-top: 3vh; }
  .fold-beweis span { display: none; }
  .fold-fuss { gap: 10px 18px; }
  .fold-spalt { top: auto; left: 0; right: 0; height: 30svh; width: auto; }
  .fold-spalt img { object-position: 50% 38%; }
  .fold-spalt em { writing-mode: horizontal-tb; transform: translateX(-50%); bottom: 14px; }
  /* Der Fold endet mobil mit einem 19svh-Filmstreifen. Der ruhende Startframe liegt in
     derselben fixed Buehne wie der Canvas und wird nur im kurzen Vorlauf eingeblendet.
     So bleibt er beim Hochschieben des Folds fest und kann pixelgleich an den Canvas
     uebergeben werden, ohne seine Koordinatenbasis zu wechseln. */
  .buehne.is-prologue-preroll .prologue-preroll { display: block; }
  .prologue-preroll { position: absolute; z-index: 1; inset: 0;
    width: 100%; height: 100%; overflow: hidden; pointer-events: none; background: var(--black); }
  .prologue-preroll img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; }
  .hero-lock { left: 20px; width: 45vw; }
  .kinetic-mark { height: 39vh; }
  .opening-thesis { left: 18px; right: 18px; bottom: 13vh; }
  .opening-thesis h2 { font-size: 11vw; line-height: .9; }
  .opening-thesis h2 strong { padding-left: 2vw; }
  .scene-copy { left: 18px; right: 18px; bottom: 14vh; width: auto; text-align: left; }
  .copy-right .chapter-tag { justify-content: flex-start; }
  .copy-right .chapter-tag::after { order: initial; transform-origin: left; }
  .scene-copy h2 { font-size: 10vw; line-height: .9; }
  .scene-copy > p:last-child { font-size: 16px; }
  .portal-type { left: 18px; right: 18px; font-size: 27vw; }
  .portal-type span + span { padding-left: 6vw; }
  .giant-object-word { font-size: 15vw; }
  .giant-object-word span + span { padding-left: 6vw; }
  .whisper { left: 18px; top: 15vh; }
  .lens-copy { left: 18px; right: 18px; top: 15vh; width: auto; }
  .fog-statement { left: 18px; right: 18px; bottom: 14vh; }
  .fog-statement h2 { font-size: 10vw; line-height: .9; }
  .mirror-specs { left: 18px; right: 18px; bottom: 14vh; width: auto; }
  .visuals-manifest { left: 18px; right: 18px; bottom: 14vh; width: auto; }
  .visuals-manifest h2 { font-size: 10vw; line-height: .9; }
  .focus-copy { left: 18px; bottom: 14vh; }
  .focus-copy h2 { font-size: 10vw; line-height: .9; }
  .finale-copy { left: 18px; right: 18px; top: 16vh; }
  .finale-copy h2 { font-size: 11vw; line-height: .9; }
  .finale-copy a { right: 0; bottom: -13vh; }
  .world-title { left: 18px; right: 18px; top: 46%; }
  .world-title h2 { font-size: 10.5vw; }
  .world-title .product-mark { width: 78px; height: 34px; top: -7vh; }
  .blende-wort { left: 18px; right: 18px; }
  .blende-wort span { font-size: 25vw; }
  .welten-brueck, .blende-brueck { left: 18px; width: calc(100vw - 36px); }
  .welten-brueck h2, .blende-brueck h2 { font-size: 10vw; line-height: .9; }
  .leinwand { padding: 9vh 18px 10vh; }
  .leinwand-kopf { grid-template-columns: 1fr; margin-bottom: 5vh; }
  .leinwand-kopf h2 { font-size: 9.5vw; }
  .leinwand-kopf > span { text-align: left; }
  .leinwand-raster { grid-template-columns: 1fr 1fr; gap: 4vh 14px; }
  .case h3 { font-size: clamp(16px, 4.6vw, 22px); overflow-wrap: anywhere; }
  .case em { font-size: 13px; }
  .leinwand-web-reihe { grid-template-columns: 1fr 1fr; }
  .case.web h3 { font-size: 4.2vw; }
  /* Mobil: die vier Bausteine untereinander, weiter ohne Rangfolge. */
  .linien-block { padding: 8vh 6vw 8vh; }
  .studio-map { padding-top: 15vh; }
  .studio-map header > p { opacity: 0; }
  .linien-block h2 { font-size: 8.4vw; margin-bottom: 4vh; }
  .studio-map h2 { font-size: 8vw; }
  .linien-lead { font-size: 17px; margin: -2vh 0 4vh; }
  .linien-block dl > div { grid-template-columns: 1fr; gap: 10px; padding: 24px 0; }
  .wege-bilder { gap: 8px; margin: 0 0 4vh; }
  .wege-bilder figcaption { font-size: 7px; letter-spacing: .08em; }
  .website-details-grid, .systems-proof-grid { grid-template-columns: 1fr; gap: 24px; }
  .website-details-grid p { font-size: 16px; }
  .systems-proof-grid > p { font-size: 16px; }
  .produktion { margin-top: 6vh; }
  .bausteine { grid-template-columns: 1fr; }
  .bausteine li { padding: 14px 0; }
  .produktion h3 { font-size: 8.6vw; margin-bottom: 22px; }
  .produktion-satz { font-size: 17px; }
  .offer-lead { font-size: 17px; }
  .dazu { margin-top: 8vh; }
  .dazu dl > div { grid-template-columns: 1fr; gap: 8px; padding: 22px 0; }
  .a2y-film-shade { background: linear-gradient(0deg, rgba(7,7,6,.92), rgba(7,7,6,.26) 62%, rgba(7,7,6,.08)); }
  .a2y-opening { left: 18px; right: 18px; top: 16vh; width: auto; }
  .a2y-opening > p { font-size: 14vw; }
  .a2y-opening h2 { font-size: 11.8vw; }
  .a2y-product-copy { left: 18px; right: 18px; bottom: 7vh; width: auto; }
  .a2y-product-copy h2 { font-size: 11.4vw; }
  .a2y-product-copy > p:not(.chapter-tag) { max-width: 36ch; margin-top: 2vh; font-size: 16px; }
  .a2y-actions { margin-top: 3vh; align-items: flex-start; flex-direction: column; gap: 14px; }
  .process { padding: 9vh 18px 10vh; }
  .process-stage h2 { font-size: clamp(32px, 8.8vw, 38px); }
  .a2y-intro-copy { margin: -1vh 0 8vh; grid-template-columns: 1fr; gap: 28px; }
  .a2y-intro-copy > p, .a2y-intro-copy > div > p { font-size: 16px; }
  .a2y-intro-copy .a2y-intro-choice { margin-bottom: 18px; font-size: 22px; }
  .a2y-method-title { margin-bottom: 5vh; font-size: 8.2vw; }
  .process ol { grid-template-columns: 1fr; }
  .process li { min-height: 0; padding: 20px 0; display: grid; grid-template-columns: 45px 1fr; border-right: 0; border-bottom: 1px solid var(--line-light); }
  .process li:last-child { padding-left: 0; }
  .process li b { margin: 0; grid-row: 1 / span 2; }
  .process li p { max-width: none; }
  .a2y-analysis-note { margin-top: 5vh; padding: 22px 18px; }
  .a2y-analysis-note h3 { font-size: 7.8vw; }
  .a2y-examples { padding: 10vh 18px; }
  .a2y-examples header h2 { font-size: 10vw; }
  .a2y-example-list { grid-template-columns: 1fr; }
  .a2y-example-list article, .a2y-example-list article + article { padding: 28px 0; border-right: 0; border-bottom: 1px solid var(--line-dark); }
  .a2y-example-list article:last-child { border-bottom: 0; }
  .a2y-example-type { min-height: 0; }
  .a2y-examples-end { font-size: 21px; }
  .faq, .contact { grid-template-columns: 1fr; }
  .faq header, .contact-intro { position: static; }
  /* REIHENFOLGE IM ANFRAGEBLOCK (01.09.2026, A7 · Jaschas Entscheid).
     Soll am Handy: Ueberschrift → WhatsApp → Formular → Kundenstimmen → Google → E-Mail.
     Heute lag das Formular hinter beiden Zitaten, rund einen Bildschirm unter dem ersten
     Kontaktweg — der Weg, der eine Anfrage aufnimmt, kam zuletzt.
     WhatsApp bleibt oben: fuer ein Solo-Studio ist das der schnellste Weg. Die
     Mail-Adresse wandert nach unten, denn das Formular IST der Mail-Weg.
     display: contents loest nur die beiden reinen Layout-Huellen auf (contact-intro und
     ihr Knopf-Div, contact-side). Das <aside> mit den Stimmen bleibt eine echte Box —
     seine innere Reihenfolge ist bereits Zitate → Google, und sein aria-label soll nicht
     verloren gehen. Am Desktop bleibt alles, wie es war. */
  .contact { display: flex; flex-direction: column; }
  .contact-intro, .contact-intro > div, .contact-side { display: contents; }
  .contact-intro > p { order: 1; }
  .contact-intro h2 { order: 2; }
  .contact-intro .wa-link { order: 3; }
  .contact form, .contact-done { order: 4; }
  .contact-proof { order: 5; margin-top: 6vh; }
  .contact-intro a[href^="mailto:"] { order: 6; margin-top: 4vh; }
  .site-footer { padding: 4vh 18px 4vh; gap: 4vh 0; }
  .fuss-spalten { grid-template-columns: 1fr 1fr; gap: 26px 18px; }
  .fuss-spalten > div:last-child { grid-column: 1 / -1; }
  .fuss-spalten a { min-height: 40px; }
  .footer-line { gap: 10px 18px; }
  .fuss-oben { margin-left: 0; }
  .index-room { padding: 18px; }
  .index-film { transform: none; }
  .index-room header { grid-template-columns: 1fr 1fr; }
  .index-room header p { display: none; }
  /* MOBILES MENUE, ZWEITE EBENE (01.09.2026, A1b · Jaschas Entscheid).
     Am Handy ist dieses Menue die EINZIGE Navigation. Es hatte genau zwei Groessen:
     39 px fuer die Welten und 11 px fuer die Seitenteile — dazwischen nichts, und
     „Anfrage ↗" brach in der 11-px-Reihe um. Jetzt drei Ebenen mit Abstand zueinander:
     Welt (33 px) · Unterabschnitt (16 px) · Seitenteil (14 px).
     Die Welten werden dafuer kompakter — der Platz geht an den Inhalt, nicht an die Hoehe
     der Ueberschrift. */
  .index-room li a { min-height: 0; padding: 14px 0 4px; grid-template-columns: 42px 1fr; align-items: baseline; }
  .index-room li span { font-size: 8.5vw; }
  /* Die Erklaerzeilen standen die ganze Zeit im Quelltext und waren am Handy ausgeblendet —
     genau dort, wo man am wenigsten sieht, was eine Welt eigentlich enthaelt. */
  .index-room li em { display: block; grid-column: 2; margin-top: 4px; font-size: 13px; line-height: 1.3; opacity: .62; }
  /* Zweite Ebene: eingerueckt unter ihrer Welt, jede Zeile mit voller Trefferflaeche. */
  .index-unter { display: block; margin: 2px 0 12px; padding-left: 42px; }
  /* Die Unterpunkte sind li und erben sonst die Trennlinie der Welten. Das ergab eine
     Linie je Unterpunkt — die Gruppe zerfiel optisch, und ueber A2Y standen zwei
     Linien uebereinander (angesehen). Eine Linie je Welt reicht. */
  .index-room .index-unter li { border-bottom: 0; }
  /* .index-room li a greift auch hier (die Unterpunkte sind ebenfalls li > a) und setzt
     min-height: 0 und ein Grid. Ohne die hoehere Spezifitaet blieben die Zeilen 37,2 px
     hoch — unter der Trefferflaeche, die A3 fuer den Menue-Knopf verlangt. Gemessen. */
  .index-room .index-unter a { min-height: 44px; padding: 0; display: flex; align-items: center;
    color: inherit; text-decoration: none; font: 400 16px/1.2 var(--sans); }
  .index-room .index-unter a::before { content: "→"; margin-right: 9px; font-size: 12px; opacity: .42; }
  .index-room .index-unter a:hover, .index-room .index-unter a:focus-visible { color: var(--signal); }
  /* A2Y ist KEIN vierter Weg (B2). Bis heute las es sich genau so: coral, gleiche Groesse
     wie die Welten, eigene coral Trennlinie. Alle drei Merkmale sind hier zurueckgenommen —
     A2Y bleibt sichtbar und anspringbar, aber es steht nicht mehr in der Reihe der Wege. */
  /* Die eigene Trennlinie faellt ganz weg (B2): die Linie der vorigen Welt trennt schon,
     zwei Linien direkt uebereinander sahen nach Fehler aus (angesehen). */
  .index-room li.index-product { margin-top: .6vh; border-top: 0; }
  .index-teile { border-top: 0; }
  .index-room li.index-product a { min-height: 0; }
  .index-room li.index-product span { font-size: 5.4vw; color: var(--ink); }
  .index-room li.index-product b { color: inherit; }
  /* Seitenteile UNTEREINANDER statt in einer Reihe: nebeneinander brach „Anfrage ↗" um,
     und 11 px waren die kleinste Schrift der ganzen Seite. */
  .index-teile { flex-direction: column; align-items: stretch; gap: 0; font-size: 14px; letter-spacing: .1em; }
  .index-teile a { min-height: 44px; }
  /* Mit zweiter Ebene und den Seitenteilen untereinander ist der Inhalt hoeher als der
     Schirm (gemessen, s. _menue-tmp.mjs). Ein Menue, das mehr enthaelt als auf den Schirm
     passt, muss scrollen duerfen — sonst ist der letzte Punkt unerreichbar. */
  .index-room { overflow-y: auto; overscroll-behavior: contain; grid-template-rows: auto auto auto auto; align-content: start; }
  .index-room ol { margin: 12px 0 0; }
  .index-teile { margin-top: 12px; }
  /* Der Deko-Grund darf beim Scrollen des Menues nicht mitwandern. */
  .index-film, .index-ground { position: fixed; }
  .index-room footer span { display: none; }
  .sucher { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .scrub-scene { --aus: 20; }   /* kurze Blenden statt eigener Uebergangs-Sektionen */
  .case figure video { display: none; }
}

/* ======================================================================
   DIE ZEITACHSE (Schritt 4, 27.07.2026 — LINKS, direkt ueber dem Bild)
   Kein Band, kein Traeger, kein Schatten. Lesbar wird sie, weil jedes Label die ECHTEN PIXEL
   hinter sich ausliest (app.js, `helligkeitHinter`) und danach Ink oder Creme wird: auf
   Inhalts-Sektionen entscheidet die Geometrie, auf dem Film die gemessene Leuchtkraft des
   Canvas. Damit braucht die Bedienung keinen reservierten Streifen.
   Typo nach Jaschas Referenz: 11 px Mono, Versalien, weite Sperrung, inaktiv 42 %, aktiv voll.
   Strich-Marken links vom Wort: kurz = Ziel, lang = hier.
   Jeder Eintrag sitzt an seiner echten Scrollposition; die Abstaende sind die tatsaechlichen
   Anteile der Seite. Ersetzt untere Leiste, Welten-Menue, Fortschritt und Index (Desktop).
   ====================================================================== */
/* top/bottom statt 0: die Achse ist vertikal zentriert, also stieg ihr erster Eintrag bei
   niedrigen Fenstern in die Kopfzone. Gemessen bei 1440x753: Kopfmarke (28,20)-(90,78) gegen
   "00 Prolog" (0,63)-(93,97) -- 15 px Ueberlappung. Die Einzuege halten sie unten wie oben frei. */
.zeitachse { position: fixed; z-index: 205; left: 0; top: 92px; bottom: 76px; width: 236px;
  display: none; align-items: center; pointer-events: none;
  opacity: 0; visibility: hidden; transition: opacity .6s var(--ease-out), visibility .6s; }
/* Erst wenn der Fold weg ist — sonst liegt die Achse auf der Schlagzeile, die dieselben
   drei Bereiche schon als Programm auffuehrt. */
.zeitachse.sichtbar { opacity: 1; visibility: visible; }
.za-rolle { position: relative; width: 100%; height: min(80vh, 700px); pointer-events: auto; }
/* EINE senkrechte Linie: Rueckgrat der Eintraege und Fortschritt. Mittelton, damit sie auf
   Bild wie auf Creme sitzt, ohne selbst umzuschalten. */
/* Die Linie muss auf DERSELBEN Skala liegen wie die Eintraege — also im Kasten der Leiste,
   nicht ueber die ganze Fensterhoehe. Sonst zeigt der Fortschrittspunkt neben den Eintrag,
   auf den er zeigen soll (27.07. aufgefallen, als der Punkt farbig wurde). */
.za-linie { position: absolute; left: 27px; top: 0; bottom: 0; width: 1px; background: rgba(138,128,110,.3); }
/* Gelaufene Strecke in Coral — Jascha 27.07.: man soll sofort sehen, wo man ist. Eine 1-px-Linie
   ist Signal, keine Flaeche (Doc 16). Am Kopf sitzt ein Punkt: die Laenge sagt "wie weit",
   der Punkt sagt "hier". */
.za-linie b { display: block; position: relative; width: 1px; height: var(--gelaufen, 0%); background: var(--signal); }
.za-linie b::after { content: ""; position: absolute; left: -2px; bottom: -2px; width: 5px; height: 5px;
  border-radius: 50%; background: var(--signal); box-shadow: 0 0 12px rgba(255,58,94,.7); }
.za-kopf { display: none; }
.zeitachse ol { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; }
.zeitachse li { position: absolute; left: 0; top: var(--pos, 0%); transform: translateY(-50%); }
.zeitachse li a { position: relative; display: flex; align-items: center; min-height: 34px;
  padding-left: 44px; white-space: nowrap; text-decoration: none;
  font: 400 11px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase;
  color: rgba(241,232,215,.66); transition: color .35s; }
.zeitachse li.auf-hell a { color: rgba(26,23,18,.62); }
.zeitachse li em { display: none; }
.zeitachse li a::after { content: ""; position: absolute; left: 22px; width: 12px; height: 1px;
  background: rgba(138,128,110,.65); transition: width .35s var(--ease-out), background .35s, left .35s var(--ease-out); }
/* Auf uneindeutigem Grund (Mittelton) wird die Schrift kraeftiger statt heller oder dunkler —
   das ist der Unterschied zwischen "Farbe umschalten" und "lesbar sein". */
.zeitachse li.stark a { color: rgba(241,232,215,.94); }
.zeitachse li.stark.auf-hell a { color: rgba(26,23,18,.9); }
.zeitachse li.stark a::after { background: rgba(241,232,215,.8); }
.zeitachse li.stark.auf-hell a::after { background: rgba(26,23,18,.7); }
.za-fuss.stark button, .za-fuss.stark a { color: rgba(241,232,215,.95); }
.za-fuss.stark.auf-hell button, .za-fuss.stark.auf-hell a { color: rgba(26,23,18,.92); }
/* Hover ist farbig, nicht nur heller (Jascha 27.07.) — Coral auf dunklem, Madder auf hellem
   Grund, damit es in beiden Faellen als dieselbe Handlung gelesen wird. */
/* Der Bereich, in dem man ist, ist FARBIG — Text UND Strich (Jascha 27.07.): so sieht man die
   Position, ohne die Linie zu lesen. Steht bewusst NACH den .stark-Regeln, damit "hier" die
   Staerke-Anpassung schlaegt (gleiche Spezifitaet, spaeter gewinnt). */
.zeitachse li.hier a { color: var(--signal-ui); }
.zeitachse li.auf-hell.hier a { color: var(--madder); }
/* Auf einem MITTELTON erreicht Coral als Textfarbe rechnerisch keine 3:1 — mit keiner der
   beiden Toenungen (gemessen mit tools/kontrast.mjs: bestenfalls 1,9:1). Dort gilt deshalb
   Kontrast vor Farbe: der Text geht auf volle Creme bzw. Ink, und das Coral wandert auf die
   Strich-Marke. Die Position bleibt farbig markiert, nur nicht im Buchstaben. */
.zeitachse li.stark.hier a { color: var(--canvas-hi); }
.zeitachse li.stark.auf-hell.hier a { color: var(--ink); }
.zeitachse li.stark.hier a::after { background: var(--signal-ui); }
.zeitachse li.stark.auf-hell.hier a::after { background: var(--madder); }
.zeitachse li.stark.za-ask a { color: var(--canvas-hi); }
.zeitachse li.stark.auf-hell.za-ask a { color: var(--ink); }
.zeitachse li.stark.za-ask a::after { background: var(--signal-ui); width: 22px; left: 16px; }
.zeitachse li.stark.auf-hell.za-ask a::after { background: var(--madder); }
.zeitachse li.hier a::after { left: 16px; width: 22px; background: var(--signal-ui); }
.zeitachse li.auf-hell.hier a::after { background: var(--madder); }
.zeitachse li a:hover, .zeitachse li a:focus-visible { color: var(--signal-ui); }
.zeitachse li a:hover::after, .zeitachse li a:focus-visible::after { width: 22px; left: 16px; background: var(--signal-ui); }
.zeitachse li.auf-hell a:hover, .zeitachse li.auf-hell a:focus-visible { color: var(--madder); }
.zeitachse li.auf-hell a:hover::after, .zeitachse li.auf-hell a:focus-visible::after { background: var(--madder); }
.zeitachse li.za-ask a { color: var(--signal-ui); }
.zeitachse li.auf-hell.za-ask a { color: var(--madder); }
.zeitachse li.za-ask a::after { background: var(--signal-ui); }
.zeitachse li.auf-hell.za-ask a::after { background: var(--madder); }
.za-fuss { position: absolute; left: 44px; bottom: -46px; margin: 0; display: flex; gap: 16px; align-items: center; }
.za-fuss button, .za-fuss a { min-height: 44px; display: inline-flex; align-items: center; padding: 0;
  border: 0; background: none; cursor: pointer; text-decoration: none;
  font: 400 11px/1 var(--mono); letter-spacing: .18em; text-transform: uppercase;
  color: rgba(241,232,215,.7); transition: color .35s; }
.za-fuss.auf-hell button, .za-fuss.auf-hell a { color: rgba(26,23,18,.66); }
.za-fuss button:hover, .za-fuss a:hover { color: var(--signal-ui); }
.za-fuss.auf-hell button:hover, .za-fuss.auf-hell a:hover { color: var(--madder); }

/* ---------- WhatsApp, Richtung A „Tippen" (Jascha 28.07.) ----------
   Heute stand dort nur das Wort — man sah nicht, dass dahinter direkt eine Nachricht liegt.
   Jetzt: das Zeichen sagt WO, die tippende Sprechblase sagt WAS PASSIERT, das Wort sagt es
   noch einmal in Worten. Im Ruhezustand bleibt es still, weil der Fuss auf dem Film liegt.
   Das Zeichen laeuft in `currentColor` mit — keine Fremdfarbe (Doc 16, Coral gehoert dem Ask).
   Bewegt werden ausschliesslich `opacity` und `transform`: die erste Fassung im Mockup hat
   `width`/`padding` animiert und damit bei jedem Bild das Layout neu gerechnet — waehrend
   der Film scrubbt. */
/* Die Geometrie haengt an drei Groessen statt an festen Pixeln — derselbe Bausatz sitzt damit
   im 11-px-Mono-Fuss der Zeitachse UND in den groesseren Zeilen im Anfrage-Block. */
.wa-link { --wa-zeichen: 16px; --wa-luft: 9px; --wa-blase-w: 32px; }
.zeichen-ablage { position: absolute; width: 0; height: 0; overflow: hidden; }
.wa-mark { width: var(--wa-zeichen, 16px); height: var(--wa-zeichen, 16px); display: block; flex: none; }
.wa-link { position: relative; display: inline-flex; align-items: center; gap: var(--wa-luft); }
.wa-wort { position: relative; display: block; }
.wa-blase { position: absolute; left: calc(var(--wa-zeichen) + var(--wa-luft)); top: 50%;
  margin-top: -8px; box-sizing: border-box;
  display: flex; align-items: center; gap: 4px; width: var(--wa-blase-w); height: 16px; padding: 0 7px;
  border-radius: 9px; background: color-mix(in srgb, currentColor 18%, transparent);
  opacity: 0; transform: scaleX(.2); transform-origin: left center;
  transition: opacity .28s, transform .42s var(--ease-out); }
.wa-blase i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .35; }
/* Gemessen vom Anfang des WORTES (nicht des Knopfes): direkt hinter der Blase, plus Luft. */
.wa-zweit { position: absolute; left: calc(var(--wa-blase-w) + var(--wa-luft) + 3px);
  top: 50%; margin-top: -.5em; white-space: nowrap;
  opacity: 0; transform: translateY(4px); transition: opacity .3s, transform .3s var(--ease-out); }
.wa-erst { display: block; transition: opacity .3s, transform .3s var(--ease-out); }
.wa-link:hover .wa-blase, .wa-link:focus-visible .wa-blase { opacity: 1; transform: none; }
.wa-link:hover .wa-blase i, .wa-link:focus-visible .wa-blase i { animation: tippen 1.05s ease-in-out infinite; }
.wa-blase i:nth-child(2) { animation-delay: .18s; }
.wa-blase i:nth-child(3) { animation-delay: .36s; }
.wa-link:hover .wa-erst, .wa-link:focus-visible .wa-erst { opacity: 0; transform: translateY(-4px); }
.wa-link:hover .wa-zweit, .wa-link:focus-visible .wa-zweit { opacity: 1; transform: none; }
@keyframes tippen { 0%, 100% { opacity: .28; transform: translateY(0); } 45% { opacity: 1; transform: translateY(-2px); } }
/* Wer Bewegung abbestellt hat, bekommt den Zustand — nicht den Weg dorthin. */
@media (prefers-reduced-motion: reduce) {
  .wa-blase, .wa-zweit, .wa-erst { transition: none; }
  .wa-link:hover .wa-blase i, .wa-link:focus-visible .wa-blase i { animation: none; }
}
/* Anfrage-Block und Danke-Zustand: dieselbe Bewegung, groesser (Jascha 28.07. — dort will er
   sie ausdruecklich auch). Zwei Anpassungen, die der Ort verlangt:
   1. Die Zeile traegt dort eine Unterlinie. Weil der Hover-Text laenger ist als „WhatsApp ↗",
      wuerde er ueber die Linie hinauslaufen — also haelt das Wort seine volle Breite frei,
      auch im Ruhezustand. Die Linie steht damit still, statt zu wachsen.
   2. Die Zeilen standen auf 8 px (Anfrage) und 9 px (Danke) — Audit 8.1 verlangt fuer
      Bedienung 14 px, Schritt 4 hat das fuer die Formular-Beschriftungen erledigt und diese
      beiden uebersehen. Bei 8 px waere die Tipp-Blase ohnehin nicht lesbar. */
.wa-gross { --wa-zeichen: 19px; --wa-luft: 11px; --wa-blase-w: 34px; }
.wa-gross .wa-wort { min-width: 15.5em; }
.contact-intro a, .done-links a { font-size: 14px; letter-spacing: .08em; }
.contact-intro .wa-link, .done-links .wa-link { padding-block: 10px; }

@media (min-width: 901px) {
  :root { --nav-w: 196px; }
  .zeitachse { display: flex; }
}

/* Zentrieren geht nur, solange der Inhalt hineinpasst. Bei niedrigen Fenstern ist die Achse
   hoeher als der Platz, und `align-items: center` schiebt den Ueberstand nach BEIDEN Seiten --
   der erste Eintrag landet dann in der Kopfzone. Gemessen bei 1440x753 lag "00 Prolog" trotz
   92-px-Einzug noch bei y=71 und damit unter der Kopfmarke, die bis y=78 reicht.
   Ab hier oben ausgerichtet: der erste Eintrag kann den Einzug dann nicht mehr verlassen. */
@media (min-width: 901px) and (max-height: 860px) {
  .zeitachse { align-items: flex-start; }
}

@media (max-width: 900px) {
  /* Zweizeilig: oben Marke + Handlung, darunter der Standort. Einzeilig ging nicht — bei
     390 px bleiben nach Logo, Index und „Anfragen" ~106 px, „Motion-Websites" braucht mehr
     und bricht um (am Mockup gesehen, nicht geschaetzt). */
  .site-chrome { padding: calc(12px + env(safe-area-inset-top, 0px)) 16px 0; }
  .chrome-oben { gap: 8px; align-items: center; }
  .site-brand { width: 52px; height: 46px; }
  /* Das Produktzeichen sitzt in der KI-Szene selbst. Im engen Mobilkopf kollidierte die
     zweite Ausspielung mit Ton und Standortzeile. */
  .site-brand .brand-product { display: none; }
  /* 4 px reichten nur, solange der Anfragen-Knopf einen Rahmen hatte, der die Trennung
     uebernahm. Seit der Rahmen weg ist (28.07.), klebt „Index" an der Coral-Flaeche —
     am Ausschnitt gesehen, nicht gerechnet. 12 px passen bei 390 px noch in eine Zeile. */
  .chrome-actions { gap: 12px; }
  /* Der mobile Standort sitzt direkt unter der Kopfzeile. Die einmalige Musik-Einladung
     kollidiert dort mit dem Kapiteltext; der beschriftete Schalter bleibt selbsterklaerend. */
  .ton-einladung { display: none; }
  .chrome-actions > a .cta-lang { display: none; }
  .chrome-actions > a .cta-kurz { display: inline; }
  /* TREFFERFLAECHE (01.09.2026, A3). Gemessen 32 x 44 px — das Wort „Menü“ ist bei
     11 px Mono schmaler als der Daumen. 44 x 44 ist die Untergrenze, unter der
     Fehlgriffe anfangen. min-width statt padding, damit die Kopfzeile ihre
     Abstaende behaelt. */
  .chrome-actions .index-control { display: inline-flex; min-width: 44px; justify-content: center; }
  .index-control i { display: none; }
  .chrome-ort { display: flex; align-items: center; gap: 9px; margin: 8px 0 0;
    font: 400 11px/1 var(--mono); letter-spacing: .09em; text-transform: uppercase;
    color: color-mix(in srgb, currentColor 72%, transparent); }
  /* Mobil ist die Standortzeile die EINZIGE Anzeige — also ganz farbig (Jascha 27.07.). */
  .chrome-ort { color: var(--signal); text-shadow: 0 1px 2px rgba(0,0,0,.55); }
  .site-chrome.on-light .chrome-ort { text-shadow: none; }
  /* Auf hellem Grund (Nebel, Creme) las Madder nicht (04.09., angesehen bei 35.700 px): Ink. */
  .site-chrome.on-light .chrome-ort { color: var(--ink); }
  .chrome-ort b { font-weight: 400; opacity: .7; }
  /* Die ruhigen Abschnitte (Drei Wege, Arbeiten, Ablauf, Fragen, Anfrage) sind keine
     Welt und tragen deshalb keine Nummer. Ohne diese Regel bliebe die Luecke stehen,
     die der leere <b> samt gap reisst. (01.09.2026, A1a) */
  .chrome-ort.ohne-nummer b { display: none; }
  /* A2 (01.09.2026) — SICHERER ABSTAND auf den ruhigen Abschnitten.
     Der Kopf ist 87 px hoch und bleibt transparent: ueber dem Film ist das gewollt.
     Wer aber ueber das Menue auf einen ruhigen Abschnitt springt, landete dessen
     Oberkante bei 0 — beim Ablauf stand die erste Zeile dann 91,9 px hoch, also
     knapp 5 px unter dem Fortschrittsbalken (86 px). 87 + 12 px Luft = 99 px.
     WIRKT NUR BEIM SPRUNG. Der Durchlauf beim freien Scrollen bleibt davon
     unberuehrt — gemessen laufen dort in allen fuenf Abschnitten Zeilen bis zur
     vollen Kopfhoehe durch (_a2-durchlauf-tmp.mjs). Das kann ein Abstand nicht
     loesen; es liegt Jascha als Frage vor. */
  #arbeiten, #leistungen, #studio-leistungen, #ablauf, #fragen, #anfrage { scroll-margin-top: 99px; }
  /* WEICHER KOPFGRUND (01.09.2026, A2 — Jaschas Entscheid).
     Nur auf den ruhigen Abschnitten und nur mobil: oben deckend in der Farbe DIESES
     Abschnitts (app.js liest sie aus und setzt --kopf-grund), nach unten auslaufend.
     Keine Leiste, kein Rand — der Verlauf endet weich unterhalb des Fortschrittsbalkens.
     UEBER DEM FILM bleibt der Kopf voellig unangetastet: dort ist das Schweben gewollt. */
  .site-chrome::before {
    content: ""; position: absolute; inset: 0 0 auto; height: calc(100% + 40px);
    /* Deckend bis 70 % (= rund 89 px) — also bis UNTER den Fortschrittsbalken (86 px);
       erst danach laeuft es aus. Erste Fassung deckte bis 42 % (47 px): das Logo war frei,
       aber die Ueberschrift schnitt weiter durch Standortzeile und Balken (angesehen,
       nicht gerechnet). */
    background: linear-gradient(to bottom, var(--kopf-grund, transparent) 0 70%, transparent 100%);
    opacity: 0; transition: opacity .3s var(--ease-out); pointer-events: none; z-index: -1;
  }
  .site-chrome.auf-ruhe::before { opacity: 1; }
  .chrome-fortschritt { display: block; height: 1px; margin-top: 9px; background: color-mix(in srgb, currentColor 14%, transparent); }
  .chrome-fortschritt b { display: block; height: 100%; width: var(--site-progress-pct, 0%); background: var(--signal); }
}

/* RAD AUF DER UHR (06.09.2026): am Rad setzt app.js die native Scrollposition jeden Frame --
   deshalb darf `scroll-behavior: smooth` (html, oben) hier nie greifen, sonst animiert der Browser
   jeden Schritt der Uhr. Am Touch-Geraet bleibt alles nativ und direkt; die Deckblaetter rasten
   ein, damit ein Wisch auf dem Block landet und ihn nicht ueberfliegt (Jascha 06.09.). */
html.rad-an { scroll-behavior: auto !important; }
@media (hover: none) and (pointer: coarse) {
  html { scroll-snap-type: y proximity; }
  main > section:not(.scrub-scene) { scroll-snap-align: start; }
}

/* Audit 07.09.2026: the tour is optional; ordinary content is on index.html. */
.loader { display:none; }
.film-fallback { display:none; }
.film-static body > :not(.film-fallback):not(script):not(style) { display:none!important; }
.film-static .film-fallback { display:block; position:relative; padding:40px clamp(22px,5vw,80px); color:var(--ink); background:var(--canvas); font-size:18px; line-height:1.6; }
.film-static .film-fallback header { max-width:850px; margin-bottom:50px; }
.film-static .film-fallback h1 { font-size:clamp(42px,7vw,90px); line-height:1; letter-spacing:-.04em; }
.film-static .film-fallback a { display:inline-block; padding:12px 0; }
.film-static .film-stills { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:40px; }
.film-static .film-stills img { width:100%; height:auto; aspect-ratio:16/9; object-fit:cover; }
.film-static .film-stills h2 { font-size:28px; line-height:1.15; letter-spacing:-.025em; }
.film-static .film-stills p { max-width:50ch; }
.film-static .film-fallback footer { margin-top:40px; }
.film-static body { overflow:auto; }
:focus-visible { outline:3px solid var(--madder); outline-offset:5px; }
.fold-beweis b,.fold-beweis>a { color:var(--madder); font-size:13px; }
.index-room .index-unter { display:flex; flex-wrap:wrap; gap:4px 24px; margin:6px 0 20px 8vw; }
.index-room .index-unter li { border:0; margin:0; padding:0; }
.index-room .index-unter a { display:inline-flex; min-height:44px; width:auto; padding:0; font-size:13px; line-height:1.5; letter-spacing:.03em; opacity:1; }
.index-room .index-unter a:hover,.index-room .index-unter a:focus-visible { color:var(--madder); }
.chrome-actions .tour-back { background:var(--canvas); color:var(--ink); }
@media(max-width:900px){.chrome-actions{gap:10px}.chrome-actions .tour-back{display:none}.index-room .index-unter{margin-left:42px;gap:0 16px}.index-room .index-unter a{font-size:13px}.film-static .film-stills{grid-template-columns:1fr}}
.index-close { min-height:44px; font-size:12px; }
.index-room li.index-product span,.index-room li.index-product a:hover { color:var(--madder); }
