/* ============================================================
   iPii.TV Showcase Hub
   Full-bleed device stage with responsive safe zones.
   DOM stays fixed: #hub-stage, .hub-video, #hub-copy, controls.
   ============================================================ */

/* P0-3: Fremd-Widgets (Pet-Toggle-Tab, Sound-Button) aus der Hub-Bedien-Zone heben.
   hub.css lädt NUR im Hub → automatisch Hub-scoped, keine Regression auf mobile/tv/web.
   .dots sitzt bottom 96px (mittig), .open-cue bottom 30px (mittig). Die rechten Widgets
   bekommen hier mehr Bodenabstand, damit sie klar über/neben dem Dock liegen und nie
   damit konkurrieren (z-index der Widgets ist hoch, würde sonst das Dock überdecken). */
/* toggle-tab (h 46px) sitzt bei 150px → reicht bis 196px; sound-btn (h 40px) MUSS klar darüber
   liegen (≥ 196 + Puffer), sonst überlappen die zwei Widgets. → sound-btn bottom 220px. */
#ipii-toggle-tab{ bottom:150px !important; }
#ipii-sound-btn{ bottom:max(224px, calc(216px + env(safe-area-inset-bottom))) !important; }

#hub-stage{
  position:fixed;
  inset:0;
  z-index:0;
  overflow:hidden;
  isolation:isolate;
  background:
    radial-gradient(1200px 720px at 70% 46%, rgba(179,54,47,.16), rgba(179,54,47,0) 62%),
    radial-gradient(980px 620px at 36% 36%, rgba(255,255,255,.055), rgba(255,255,255,0) 58%),
    linear-gradient(180deg, #090807 0%, #050404 48%, #020202 100%);
}

#hub-stage::before{
  content:"";
  position:absolute;
  inset:-12%;
  z-index:0;
  pointer-events:none;
  background:
    linear-gradient(115deg, transparent 0 42%, rgba(255,255,255,.035) 49%, transparent 58%),
    radial-gradient(100% 72% at 62% 54%, transparent 0 52%, rgba(0,0,0,.52) 83%, #000 100%);
  opacity:.8;
}

#hub-stage::after{
  content:"";
  position:absolute;
  left:0;
  right:0;
  bottom:-12%;
  height:44%;
  z-index:0;
  pointer-events:none;
  background:
    radial-gradient(64% 40% at 58% 38%, rgba(253,243,243,.08), transparent 62%),
    linear-gradient(180deg, transparent, rgba(0,0,0,.76) 72%, #000);
}

.hub-backdrop{
  /* HG-Video ganz hinten (unterste Ebene): füllt das Browserfenster STUFENLOS in jeder Größe.
     Kanonische „fixiertes Video-Hintergrund"-Formel: am Container verankert (top/left:0) + width/height:
     100% statt inset:0 (inset+width/height konkurrieren bei ersetzten Elementen → Chrome fiel auf die
     intrinsische 1280×720-Größe zurück, Video skalierte nicht mit). display:block + min-* erzwingen
     volle Füllung; object-fit:cover skaliert dynamisch jedes Seitenverhältnis. Kein transform:scale. */
  position:absolute;
  top:0; left:0;
  display:block;
  width:100%;
  height:100%;
  min-width:100%;
  min-height:100%;
  z-index:0;
  background:#050404 url("../assets/hub/studio-backdrop.png") center center/cover no-repeat;
  opacity:.46;
}
/* bewegter Studio-Backdrop (Video) — cover, füllt jedes Format randlos + stufenlos (kein Beschnitt-
   Sprung). object-position:center hält Boden/Horizont/Rauch mittig. */
video.hub-backdrop-vid{
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:center center;
  background:#050404;
}

.hub-backdrop::after{
  content:"";
  position:absolute;
  inset:0;
  background:
    radial-gradient(96% 76% at 58% 48%, transparent 24%, rgba(5,4,4,.45) 72%, rgba(0,0,0,.92) 100%),
    linear-gradient(90deg, rgba(0,0,0,.62), transparent 28%, transparent 74%, rgba(0,0,0,.5));
}

/* (Entfernt 2026-06-26: totes hub3d-*-Schichtsystem — gehörte zu js/hub-stage3d.js,
   das nie in hub.html eingebunden war. Lebendes System = Backdrop-Video + .hub-video + .grade.) */

/* Full-bleed video layer. The layer is never cropped into columns; all layout
   changes happen through object-position, transform scale and safe zones. */
.hub-video{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  z-index:1;
  contain:layout paint style;
  object-fit:contain;
  object-position:var(--dev-pos, 50% 58%);
  transform-origin:var(--dev-origin, 50% 58%);
  transform:translate3d(var(--dev-x, 0px), var(--dev-y, 0px), 0) scale(var(--dev-off-scale, .985));
  opacity:0;
  filter:blur(10px) saturate(.96) contrast(1.02);
  pointer-events:none;
  cursor:pointer;
  transition:
    opacity .56s cubic-bezier(.22,.61,.36,1),
    transform .72s cubic-bezier(.16,1,.3,1),
    filter .46s ease;
  -webkit-mask-image:var(--dev-mask, radial-gradient(116% 94% at 50% 52%, #000 58%, rgba(0,0,0,.72) 79%, transparent 100%));
          mask-image:var(--dev-mask, radial-gradient(116% 94% at 50% 52%, #000 58%, rgba(0,0,0,.72) 79%, transparent 100%));
  /* VIDEOTREUE MASKE (Montage-Kanten-Fix 2026-07-01): mask-size = exakter
     object-fit:contain-Bereich des Videos (AR-adaptiv via svw/svh, Stage ist fixed inset:0
     = Viewport), mask-position folgt object-position (--dev-pos, identische Semantik).
     Die Maske liegt damit bei JEDEM Fenster-Seitenverhaeltnis exakt auf dem Videobild;
     Letterbox-Zonen des Elements sind durch no-repeat komplett transparent. Vorher bezog
     sich die Maske aufs volle Element -> beim 9:16-Phone federte sie im Leeren und die
     echte Videokante blieb hart (sichtbarer dunkler Streifen im Backdrop). */
  -webkit-mask-repeat:no-repeat;
          mask-repeat:no-repeat;
  -webkit-mask-position:var(--dev-pos, 50% 58%);
          mask-position:var(--dev-pos, 50% 58%);
  -webkit-mask-size:var(--mask-size, 100% 100%);
          mask-size:var(--mask-size, 100% 100%);
}

.hub-video.on{
  opacity:1;
  filter:blur(0) saturate(1.04) contrast(1.04);
  pointer-events:auto;
  transform:translate3d(var(--dev-x, 0px), var(--dev-y, 0px), 0) scale(var(--dev-scale, 1));
}

.hub-video[data-device="phone"],
.hub-video[data-device="tv"],
.hub-video[data-device="laptop"]{
  /* Wide-HG-Videos (1:1, Gerät zentral ~43%, HG schon eingebaut + Ränder schwarz):
     zentrierte Quelle, nur moderat skaliert; das Gerät bleibt vollständig sichtbar.
     Die Maske sitzt nur am äußeren Rand, weil die Videos selbst bereits ins Schwarz laufen.
     Phone folgt seit 2026-06-24 derselben Behandlung (eigenes Wide-Video, keine Sondermasken). */
  /* MACHBARKEITS-CHECK Geometrie-Formel (2026-07-01, Vertiefungs-Plan Schritt 3): geprüft, ob
     --dev-x/-scale/-pos über alle Breakpoints hinweg durch eine einzige parametrisierte Funktion
     aus Viewport-Breite/-Höhe ersetzt werden können, statt pro Breakpoint hart codierter Werte.
     ERGEBNIS: NICHT sauber möglich. --dev-x sinkt z.B. von 17vw (min-width:1180px) auf 11vw
     (min-width:1600px) bei wachsender Breite — nicht-monoton, weil die Copy-Box (#hub-copy)
     dort anders mit dem Viewport skaliert als der Video-Screen. Die separaten Landscape/
     max-height-Breakpoints (14vw) liegen wieder unabhängig von beiden. Das sind Punkte, die
     einzeln per Auge/Screenshot gegen echten Overlap kalibriert wurden (siehe P1-Fixes weiter
     unten), keine Stützstellen einer stetigen Kurve. Eine Formel würde pro Breakpoint eigene
     Korrekturterme brauchen — keine echte Vereinfachung, nur andere Verpackung derselben
     Handkalibrierung, mit dem Risiko neuer Overlap-Bugs an den Übergängen. Bleibt bei den
     bestehenden, bereits abgenommenen Breakpoint-Werten. */
  --dev-pos:50% 50%;
  --dev-origin:50% 50%;
  --dev-x:0px;
  --dev-y:0px;
  --dev-scale:1.06;
  --dev-off-scale:1.02;
  /* MASKEN-NEUBAU 2026-07-01 (Henrik: „hub 3d video darstellungen haben noch sehr viele kanten
     und montagefehler"). Wurzel der alten Kanten: die Masken bezogen sich aufs VOLLE Element
     (inset:0 = Viewport), die Videos liegen aber per object-fit:contain nur in einem Teilbereich
     — beim 9:16-Phone federten die X-Stops im LEEREN Letterbox-Bereich und die echte Videokante
     blieb hart (sichtbarer dunkler Streifen); bei TV/Laptop lagen die Rampen im hellen Video-Glow
     und wirkten als Abdunklungs-Naht gegen den helleren Rauch-Backdrop.
     NEU: mask-size/-position (auf .hub-video oben) legen die Maske EXAKT auf den Videobereich —
     die Stops hier sind daher VIDEO-Koordinaten (aus den echten Frames vermessen, ffmpeg-Grid):
     Vollzone = Geraet + Puffer, Auslauf endet VOR der Videokante (transparent 99%).
     EINE elliptische Maske pro Geraet statt 3-fach-Intersect: organischer Verlauf, keine
     Ecken-Artefakte, keine mask-composite-Fallen. Y darf frueher enden — das Material laeuft
     oben/unten selbst ins Dunkle aus. Breakpoint-Sondermasken entfallen (AR-adaptiv). */
  --mask-size: min(100%, calc(100svh * 16 / 9)) min(100%, calc(100svw * 9 / 16));
  /* KEIN mix-blend-mode auf den Geraete-Videos (Henrik 2026-07-02): lighten liess den
     diffusen Backdrop-Rauch durch dunkle Geraeteflaechen scheinen = Grauschleier.
     Geraete bleiben voll deckend (Kanten loest die videotreue Maske); die Rauch-Tiefe
     kommt stattdessen von der separaten .hub-smoke-Ebene DARUEBER (nur klare Schwaden). */
}
.hub-video[data-device="tv"]{
  /* TV-Geraet im Frame: x 20-78%, y 6-80%, Reflexion bis ~92% */
  --dev-mask: radial-gradient(50% 85% at 49% 47%, #000 58%, rgba(0,0,0,.5) 80%, transparent 99%);
}
.hub-video[data-device="laptop"]{
  /* Laptop im Frame: x 24-80%, y 8-80%, Reflexion bis ~95% */
  --dev-mask: radial-gradient(50% 85% at 52% 47%, #000 56%, rgba(0,0,0,.5) 80%, transparent 99%);
}

/* PHONE = echtes 9:16-Video (1080x1920): eigene mask-size (Hochformat-Contain-Masse)
   + engere X-Vollzone (Geraet x 28-66%, Glow links/rechts weich auslaufen lassen). */
#hub-stage .hub-video[data-device="phone"]{
  --mask-size: min(100%, calc(100svh * 9 / 16)) min(100%, calc(100svw * 16 / 9));
  /* NUR X-Feder (Henrik-Feinschliff 2026-07-02): das 9:16-Video fuellt die Viewport-HOEHE
     komplett — obere/untere Videokante clippt der Bildschirmrand von selbst. Die fruehere
     Ellipse dunkelte unnoetig auch vertikal ab und FRASS Bodenreflexion + roten Studio-Glow
     (Phone schwebte ueber totem Schwarz). Breite seitliche Rampen = weiche Kanten,
     Reflexion/Glow bleiben voll erhalten. */
  --dev-mask: linear-gradient(to right, transparent 2%, #000 26%, #000 72%, transparent 98%);
}

/* ── Rauch-Schwaden-Ebene UEBER den Geraeten (Henrik 2026-07-02: „nur einzelne klare
   Rauchschwaden ueber die Geraete schlaengeln, kein Grauschleier"). Photoshop-Logik:
   Backdrop-Video dupliziert, steile Tonwertkurve (brightness+contrast) drueckt das flaue
   Grundgrau auf Schwarz — bei Negativ-Multiplizieren (screen) bleibt damit NUR das helle
   Schwaden-Relief sichtbar, alles andere ist unsichtbar. Gespiegelt (scaleX -1) + eigenes
   Tempo, damit die vorderen Schwaden nicht als Kopie des Hintergrunds lesbar sind (Tiefe).
   z-index 2: ueber den Geraeten (1), unter grade/Copy/Controls (3+). ── */
.hub-smoke{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position:center;
  z-index:2; pointer-events:none;
  mix-blend-mode:screen;
  /* Henrik 3x nachjustiert ("zu doll, nicht smooth/fluessig"): hoher contrast
     verstaerkt JEDE Pixel-Aenderung zwischen Frames -> wirkt bei langsamem
     Video wie Ruckeln statt fliessender Bewegung. Kurve deutlich flacher. */
  filter:brightness(1.15) contrast(1.6) saturate(.8);
  opacity:.22;
  transform:scaleX(-1);
}
@media (prefers-reduced-motion:reduce){ .hub-smoke{ display:none; } }

@media (prefers-reduced-motion:reduce){
  .hub-video,
  .hub-video.on{
    transition:opacity .2s ease;
    transform:translate3d(var(--dev-x, 0px), var(--dev-y, 0px), 0) scale(var(--dev-scale, 1));
  }
}

/* (Entfernt 2026-06-26: .hub-still/.hub-stack/@keyframes hubSwivel — gehörten zum toten
   layers3d/still3d-Pfad; kein META-Eintrag nutzt sie, alle Geräte sind reine <video>.) */

/* ── EINE generische Schwebe-Animation für ALLE aktiven Geräte-Videos (P1-3) ──
   Bewegung ist damit GARANTIERT (unabhängig vom Video-Dekoder); Amplitude pro Gerät via
   --float-rot (rotateY) und --float-lift (vertikales Heben). Phone schwebt am stärksten
   („in der Hand"), TV am ruhigsten („steht am Boden"), Laptop dazwischen. transform-origin
   pro Gerät, damit die Drehachse stimmt (TV am Standfuß). */
.hub-video.on{
  animation:hubFloat 12s ease-in-out infinite alternate;
  will-change:transform;
}
.hub-video[data-device="tv"].on   { --float-rot:1.6deg; --float-lift:5px;  transform-origin:50% 72%; animation-duration:16s; }
.hub-video[data-device="laptop"].on{ --float-rot:2.6deg; --float-lift:9px;  transform-origin:50% 60%; animation-duration:14s; }
.hub-video[data-device="phone"].on { --float-rot:6deg;   --float-lift:14px; transform-origin:50% 58%; animation-duration:11s; }
@keyframes hubFloat{
  0%  { transform:translate3d(var(--dev-x,0),calc(var(--dev-y,0) - var(--float-lift,8px)),0) scale(calc(var(--dev-scale,1) * .99))  perspective(1500px) rotateY(calc(var(--float-rot,3deg) * -1)) rotateX(.8deg); }
  100%{ transform:translate3d(var(--dev-x,0),calc(var(--dev-y,0) + var(--float-lift,8px)),0) scale(calc(var(--dev-scale,1) * 1.01)) perspective(1500px) rotateY(var(--float-rot,3deg)) rotateX(-.6deg); }
}
/* reduced-motion: keine Schwebe-Animation, aber Gerät bleibt sichtbar (Basis-transform aus .on). */
@media (prefers-reduced-motion:reduce){ .hub-video.on{ animation:none; } }

.grade{
  position:fixed;
  inset:0;
  z-index:3;
  pointer-events:none;
  background:
    radial-gradient(120% 96% at 58% 48%, transparent 44%, rgba(0,0,0,.36) 78%, rgba(0,0,0,.76) 100%),
    linear-gradient(180deg, rgba(0,0,0,.2), transparent 18%, transparent 72%, rgba(0,0,0,.42));
}
/* PHONE-Ansicht: sanfte Seiten-Vignette (roter Studio-Schein + Bodenreflexion bleiben sichtbar,
   nur äußere ~14% pro Seite weich ins Schwarz). P0-2: aus hub.html hierher konsolidiert. */
#hub-stage[data-active="phone"] ~ .grade{
  background:
    linear-gradient(90deg, rgba(0,0,0,.78) 0%, rgba(0,0,0,.32) 9%, transparent 22%, transparent 78%, rgba(0,0,0,.32) 91%, rgba(0,0,0,.78) 100%),
    radial-gradient(150% 120% at 50% 46%, transparent 56%, rgba(0,0,0,.34) 82%, rgba(0,0,0,.7) 100%);
  transition:background .5s ease;
}

/* Top navigation: restrained glass, brand stays crisp. */
.topbar{
  z-index:8;
  padding:24px clamp(18px, 4vw, 48px);
}

.brand .logo{
  height:27px;
  filter:drop-shadow(0 8px 22px rgba(0,0,0,.34));
}

.brand .word{
  letter-spacing:0;
}

.btn{
  height:42px;
  letter-spacing:0;
  border-radius:999px;
}

.btn-ghost{
  background:rgba(253,243,243,.045);
  border-color:rgba(253,243,243,.13);
  -webkit-backdrop-filter:saturate(150%) blur(18px);
          backdrop-filter:saturate(150%) blur(18px);
}

.btn-red{
  background:linear-gradient(180deg, #c2403a 0%, var(--cta) 100%);
  box-shadow:
    0 18px 42px -18px rgba(179,54,47,.9),
    inset 0 1px 0 rgba(255,255,255,.24),
    inset 0 -1px 0 rgba(0,0,0,.22);
}

.btn:hover{
  transform:translateY(-1px);
}

/* Copy safe zone. */
#hub-copy{
  position:fixed;
  left:50%;
  top:calc(78px + env(safe-area-inset-top));
  z-index:6;
  width:min(90vw, 420px);
  transform:translateX(-50%);
  text-align:center;
  pointer-events:none;
  text-wrap:balance;
  transition:opacity .36s cubic-bezier(.22,.61,.36,1), transform .36s cubic-bezier(.22,.61,.36,1);
}

#hub-copy.swap{
  opacity:0;
  transform:translateX(-50%) translateY(8px);
}

#hub-copy .eyebrow{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:9px;
  margin-bottom:12px;
  color:var(--ink-red);
  font-family:var(--mono);
  font-size:10px;
  font-weight:700;
  letter-spacing:.13em;
  text-transform:uppercase;
}

#hub-copy .eyebrow::before{
  content:"";
  width:22px;
  height:1px;
  background:linear-gradient(90deg, transparent, var(--mark,#b3362f));
}

#hub-copy h1{
  color:var(--ink,#FDF3F3);
  font-size:32px;
  line-height:1.05;
  font-weight:760;
  letter-spacing:0;
  text-shadow:0 18px 48px rgba(0,0,0,.46);
}

#hub-copy h1 em{
  font-style:normal;
  color:var(--ink-red);
}

#hub-copy .sub{
  margin:12px auto 0;
  max-width:35ch;
  color:rgba(253,243,243,.68);
  font-size:14px;
  line-height:1.48;
  font-weight:500;
}

/* Segmented device control. */
/* Klobige Tab-Pille entfernt (Henrik) → schlanke Punkte+Strich-Leiste (.dots) ist jetzt das Dock. */
.hub-tabs{display:none}

/* Schlankes mittiges Dock: 3 Punkte, aktiver = roter Strich (Apple-Pager-Anmutung).
   Sitzt klar ÜBER dem open-cue (Gerätewahl oben, „Seite öffnen" darunter) — vorher
   kollidierten dots (bottom 40) und open-cue (bottom 34) mittig unten. */
.dots{
  position:fixed;
  left:50%;
  bottom:calc(96px + env(safe-area-inset-bottom));
  z-index:7;
  display:flex;
  align-items:center;
  justify-content:center;
  gap:12px;
  padding:10px 16px;
  transform:translateX(-50%);
  border-radius:999px;
  background:rgba(10,9,9,.32);
  -webkit-backdrop-filter:saturate(150%) blur(14px);
          backdrop-filter:saturate(150%) blur(14px);
}
.dots .dot-btn{
  width:8px;height:8px;border-radius:999px;padding:0;border:0;cursor:pointer;
  background:rgba(253,243,243,.28);
  -webkit-tap-highlight-color:transparent;
  transition:background .3s var(--ease-cine,ease), width .42s cubic-bezier(.34,1.56,.64,1);
}
.dots .dot-btn:hover{background:rgba(253,243,243,.55)}
.dots .dot-btn.active{
  width:30px;background:var(--cta);
  box-shadow:0 0 14px var(--glow);
}
.dots .dot-btn:focus-visible{outline:2px solid var(--glow);outline-offset:3px}

.nav-arrow{
  display:none;
  position:fixed;
  top:50%;
  z-index:7;
  width:52px;
  height:52px;
  align-items:center;
  justify-content:center;
  border:1px solid rgba(253,243,243,.13);
  border-radius:50%;
  background:rgba(18,15,15,.5);
  color:rgba(253,243,243,.66);
  -webkit-backdrop-filter:saturate(160%) blur(22px);
          backdrop-filter:saturate(160%) blur(22px);
  box-shadow:
    0 18px 42px -20px rgba(0,0,0,.85),
    inset 0 1px 0 rgba(255,255,255,.08);
  transform:translateY(-50%);
  -webkit-tap-highlight-color:transparent;
  transition:color .24s ease, background .24s ease, border-color .24s ease, transform .2s cubic-bezier(.34,1.56,.64,1);
}

.nav-arrow svg{
  width:22px;
  height:22px;
}

.nav-arrow:hover{
  color:#fff;
  border-color:rgba(253,243,243,.28);
  background:rgba(32,27,27,.66);
  transform:translateY(-50%) scale(1.05);
}

.nav-arrow:active{
  transform:translateY(-50%) scale(.96);
}

.nav-arrow:focus-visible{
  outline:2px solid var(--glow);
  outline-offset:3px;
}

.nav-arrow.left{left:clamp(24px, 3vw, 48px)}
.nav-arrow.right{right:clamp(24px, 3vw, 48px)}

/* Rechtslinks immer erreichbar (P1-Fix Multi-Agent-Review 2026-07-01): hub.html hat
   keinen Scroll-Footer, Rechtslinks waren sonst nur im Cookie-Banner sichtbar und
   verschwanden nach der Consent-Entscheidung. Dezent unten links, außerhalb der
   Dots/Open-Cue/Toggle-Widget-Zonen (Mitte + rechts).
   P0-Fix (Multi-Agent-Live-Audit 2026-07-01): solange der Cookie-Banner offen ist, saß
   .hub-legal exakt an derselben Stelle und wurde von ihm komplett verdeckt (Banner
   z-index 80 > .hub-legal z-index 7). Verschiebt sich jetzt per --cookie-banner-h
   (von js/cookie-consent.js gesetzt) automatisch über den Banner. Touch-Targets von
   reiner 11px-Zeilenhöhe auf echte Padding-Buttons vergrößert (Empfehlung ~44px). */
.hub-legal{
  position:fixed;
  left:clamp(16px, 3vw, 32px);
  bottom:calc(14px + env(safe-area-inset-bottom) + var(--cookie-banner-h, 0px));
  z-index:7;
  display:flex;
  gap:6px;
  transition:bottom .25s var(--ease,ease);
}
.hub-legal a{
  font-size:11px;
  display:inline-flex;
  align-items:center;
  min-height:44px;
  padding:0 10px;
  color:rgba(253,243,243,.5);
  letter-spacing:.02em;
  transition:color .2s var(--ease,ease);
}
.hub-legal a:hover{color:rgba(253,243,243,.9)}
.hub-legal-cookies{font:inherit;font-size:11px;display:inline-flex;align-items:center;min-height:44px;
  padding:0 10px;color:rgba(253,243,243,.5);letter-spacing:.02em;cursor:pointer;
  transition:color .2s var(--ease,ease)}
.hub-legal-cookies:hover{color:rgba(253,243,243,.9)}
@media(max-width:560px){.hub-legal{gap:2px}.hub-legal a,.hub-legal-cookies{font-size:10px;padding:0 7px}}

.open-cue{
  position:fixed;
  left:50%;
  bottom:calc(30px + env(safe-area-inset-bottom));
  z-index:7;
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:6px;
  color:rgba(253,243,243,.58);
  background:none;
  border:0;
  transform:translateX(-50%);
  -webkit-tap-highlight-color:transparent;
  transition:color .24s ease, transform .24s cubic-bezier(.34,1.56,.64,1);
}

.open-cue:hover{
  color:#fff;
  transform:translateX(-50%) translateY(-2px);
}

.open-cue:active{
  transform:translateX(-50%) scale(.96);
}

.open-cue:focus-visible{
  outline:2px solid var(--glow);
  outline-offset:4px;
  border-radius:8px;
}

.oc-label{
  font-size:13px;
  font-weight:700;
  letter-spacing:0;
}

.oc-arrow svg{
  width:20px;
  height:20px;
  animation:ocbob 1.8s cubic-bezier(.22,.61,.36,1) infinite;
}

@keyframes ocbob{
  0%,100%{transform:translateY(0);opacity:.58}
  50%{transform:translateY(4px);opacity:1}
}

body.committing .hub-video.on{
  filter:blur(0) saturate(1.08) contrast(1.06);
}

body.committing #hub-copy{
  opacity:0;
}

body.committing .grade{
  background:radial-gradient(120% 100% at 58% 48%, transparent 30%, rgba(0,0,0,.72) 74%, #000 100%);
}

body.committing{
  transition:opacity .42s ease;
}

@media (max-width:420px){
  .topbar{
    padding:23px 24px;
  }

  .brand .word{
    font-size:18px;
  }

  .btn{
    height:40px;
    padding:0 15px;
    font-size:13px;
  }

  .btn-ghost{
    display:none;
  }

  #hub-copy h1{
    font-size:31px;
  }

  .hub-tab{
    padding:0 13px;
    gap:6px;
    font-size:12.5px;
  }
}

@media (min-width:561px){
  #hub-copy{
    top:calc(88px + env(safe-area-inset-top));
    width:min(82vw, 560px);
  }

  #hub-copy .eyebrow{
    font-size:11px;
    letter-spacing:.14em;
    margin-bottom:13px;
  }

  #hub-copy h1{
    font-size:42px;
  }

  #hub-copy .sub{
    font-size:15px;
    max-width:42ch;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-pos:50% 50%;
    --dev-origin:50% 50%;
    --dev-y:0px;
    --dev-scale:1.04;
    --dev-off-scale:1.0;
  }
  /* P1-1: TV/Laptop (16:9/16:10) füllen in dieser Breite vertikal wenig (contain → limitiert
     auf Breite) → größer skalieren + höher rücken, damit das Gerät dominant statt verloren wirkt.
     Phone (9:16) NICHT anfassen — passt bereits formatfüllend. */
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-pos:50% 42%;
    --dev-scale:1.22;
  }
}

@media (min-width:760px) and (orientation:portrait){
  #hub-copy{
    top:calc(94px + env(safe-area-inset-top));
    width:min(78vw, 620px);
  }

  #hub-copy h1{
    font-size:46px;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-pos:50% 50%;
    --dev-origin:50% 50%;
    --dev-y:0px;
    --dev-scale:1.08;
    --dev-off-scale:1.04;
  }
  /* P1-1: im Tablet-Hochformat noch mehr ungenutzte Höhe → TV/Laptop kräftiger füllen.
     P1-Fix (Audit 2026-07-01): --dev-pos 40% + scale 1.32 schob den TV-Screen-Inhalt
     ("Aurora Nights"+Abspielen) so weit nach oben, dass er direkt unter die Headline
     rutschte (Screenshot-bestätigt 834x1194, Text auf Screen kaum noch lesbar). Gerät
     etwas tiefer + etwas kleiner → klare Trennung Copy-Block/Geräte-Screen. */
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-pos:50% 52%;
    --dev-scale:1.2;
  }

  .open-cue{
    bottom:calc(38px + env(safe-area-inset-bottom));
  }
}

/* Large tablet / small notebook: still stacked, with a defined middle device zone. */
@media (min-width:861px) and (max-width:1179px) and (min-height:640px){
  #hub-copy{
    top:calc(82px + env(safe-area-inset-top));
    width:min(72vw, 640px);
  }

  #hub-copy h1{
    font-size:44px;
  }

  #hub-copy .sub{
    margin-top:10px;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    /* Phone braucht hier keine intersect-Sondermaske mehr — eigenes 1:1-Wide-Video
       läuft selbst ins Schwarz, also dieselbe schlanke Rand-Maske wie tv/laptop. */
    --dev-pos:50% 50%;
    --dev-origin:50% 50%;
    --dev-x:0px;
    --dev-y:48px;
    --dev-scale:1.0;
    --dev-off-scale:.96;
    /* Breakpoint-Sondermaske entfernt: videotreue Basis-Maske (mask-size) ist AR-adaptiv */
  }
  /* P1-1: Tablet/Notebook-Zwischenbreite — TV/Laptop größer + etwas höher (Phone bleibt). */
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-pos:50% 44%;
    --dev-scale:1.18;
  }

  .open-cue{
    bottom:calc(24px + env(safe-area-inset-bottom));
  }

  .nav-arrow{
    display:flex;
  }
}

/* Desktop: quiet split composition. Copy is constrained, device frame is shifted
   and scaled inside the unchanged full-bleed video layer. */
@media (min-width:1180px) and (min-height:700px){
  #hub-stage{
    background:
      radial-gradient(1320px 760px at 74% 48%, rgba(179,54,47,.17), rgba(179,54,47,0) 62%),
      radial-gradient(980px 680px at 32% 38%, rgba(253,243,243,.06), rgba(253,243,243,0) 58%),
      linear-gradient(180deg, #0b0908 0%, #050404 52%, #020202 100%);
  }

  .hub-backdrop{
    opacity:.52;
  }

  #hub-copy{
    left:clamp(72px, 7vw, 132px);
    top:50%;
    width:min(38vw, 560px);
    transform:translateY(-50%);
    text-align:left;
  }

  #hub-copy.swap{
    transform:translateY(-50%) translateY(10px);
  }

  #hub-copy .eyebrow{
    justify-content:flex-start;
    margin-bottom:16px;
  }

  #hub-copy h1{
    font-size:64px;
    line-height:.98;
  }

  #hub-copy .sub{
    margin-top:18px;
    margin-left:0;
    margin-right:0;
    max-width:34ch;
    font-size:16px;
    line-height:1.55;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    /* Apple-Split rechts: Gerät nach rechts versetzt, Copy links. Phone teilt jetzt
       dieselbe Wide-Geometrie (1:1) und denselben Versatz wie tv/laptop.
       P1-Fix (Audit 2026-07-01): 12vw Versatz reichte nicht — bei contain+object-position:50%
       sitzt das TV/Laptop-Bild trotz Versatz noch so weit links, dass "groß gemacht."/lange
       h1-Zeilen den Screen-Inhalt (Aurora-Nights-Card, Abspielen-Button) überdecken
       (Screenshot-bestätigt 1440x900). Mehr Versatz schafft klare Trennung. */
    --dev-pos:50% 50%;
    --dev-origin:50% 50%;
    --dev-x:17vw;
    --dev-y:0px;
    --dev-scale:1.02;
    --dev-off-scale:.98;
    /* Breakpoint-Sondermaske entfernt: videotreue Basis-Maske (mask-size) ist AR-adaptiv */
  }

  .hub-tabs{
    left:auto;
    right:clamp(72px, 7vw, 132px);
    bottom:calc(74px + env(safe-area-inset-bottom));
    transform:none;
  }

  .open-cue{
    left:auto;
    right:clamp(104px, 8vw, 154px);
    bottom:calc(22px + env(safe-area-inset-bottom));
    transform:none;
  }

  .open-cue:hover{
    transform:translateY(-2px);
  }

  .open-cue:active{
    transform:scale(.96);
  }

  .nav-arrow{
    display:flex;
  }

  body.committing #hub-copy{
    transform:translateY(-50%);
  }
}

@media (min-width:1600px) and (min-height:800px){
  .topbar{
    padding-left:56px;
    padding-right:56px;
  }

  #hub-copy h1{
    font-size:72px;
  }

  #hub-copy .sub{
    font-size:17px;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-x:11vw;
    --dev-scale:1.04;
    --dev-off-scale:1.0;
  }
}

/* Short landscape phones: split, compact controls, no vertical collisions. */
@media (orientation:landscape) and (max-height:620px) and (max-width:1179px){
  .topbar{
    padding:12px clamp(14px, 4vw, 30px);
  }

  .brand .logo{
    height:23px;
  }

  .brand .word{
    font-size:16px;
  }

  .btn{
    height:36px;
    padding:0 13px;
    font-size:12.5px;
  }

  #hub-copy{
    left:clamp(18px, 4vw, 42px);
    top:50%;
    width:min(38vw, 310px);
    transform:translateY(-50%);
    text-align:left;
  }

  #hub-copy.swap{
    transform:translateY(-50%) translateY(8px);
  }

  #hub-copy .eyebrow{
    justify-content:flex-start;
    gap:7px;
    margin-bottom:8px;
    font-size:9px;
    letter-spacing:.12em;
  }

  #hub-copy .eyebrow::before{
    width:17px;
  }

  #hub-copy h1{
    font-size:28px;
    line-height:1.04;
  }

  #hub-copy .sub{
    margin:9px 0 0;
    max-width:29ch;
    font-size:12.5px;
    line-height:1.42;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-pos:50% 50%;
    --dev-origin:50% 50%;
    --dev-x:14vw;
    --dev-y:0px;
    --dev-scale:1.06;
    --dev-off-scale:1.02;
    /* Breakpoint-Sondermaske entfernt: videotreue Basis-Maske (mask-size) ist AR-adaptiv */
  }

  .hub-tabs{
    left:auto;
    right:clamp(14px, 4vw, 30px);
    bottom:calc(12px + env(safe-area-inset-bottom));
    min-height:46px;
    padding:4px;
    gap:3px;
    transform:none;
  }

  .hub-tab{
    height:38px;
    padding:0 12px;
    gap:6px;
    font-size:12px;
  }

  .hub-tab svg{
    width:14px;
    height:14px;
    flex-basis:14px;
  }

  .open-cue{
    display:none;
  }

  .nav-arrow{
    display:none;
  }

  body.committing #hub-copy{
    transform:translateY(-50%);
  }
}

@media (max-height:430px) and (orientation:landscape){
  #hub-copy h1{
    font-size:25px;
  }

  #hub-copy .sub{
    font-size:12px;
  }

  .hub-video[data-device="phone"],
  .hub-video[data-device="tv"],
  .hub-video[data-device="laptop"]{
    --dev-x:14vw;
    --dev-y:0px;
    --dev-scale:1.06;
    --dev-off-scale:1.02;
  }

  .hub-tab{
    padding:0 10px;
  }
}
