/* =====================================================================
   fiberONE · Laser-Holodeck „FOUR Frankfurt“ — Startseiten-Einbettung
   Sektion Wohnungswirtschaft, Einstieg (Eyebrow, h2, Absatz, Checkliste): das Hologramm steht dort, wo bis
   22.10.2026 die stilisierte Hochhaus-Grafik (.tower-fig) stand (CEO: „mach es einfach an die Stelle wo das andere
   Hochhaus ist“); der Block „Die Architektur: zentral versorgbar, dezentral gedacht“ ist entfallen. CEO danach:
   „das Hologramm muss kleiner“ — es lebt im Bereich der rechten Spalte; nur Schein, äußerer Plattformrand und
   einzelne Ring-/Trassenlinien dürfen weich Richtung Textspalte laufen, die Türme nie. Dann: „und weiter nach rechts“ —
   ab 980 px sitzt der Anker (und damit das Motiv) um --hd-shift rechts der Spaltenmitte, bis in den rechten
   Seitenrand; zwischen Text und Türmen bleibt eine ruhige Lücke.
   Komponente: assets/laser-holodeck.js (angepasste Kopie von arbeit/laser-holodeck/final/holodeck.js).
   ---------------------------------------------------------------------
   Aufbau im Markup:
     .holo-intro#towerGrid                 Einstiegs-Raster (ab 980 px zwei Spalten, darunter gestapelt);
                                           id bleibt für den Photon-Lader der DE-Seite (Rückfall ohne WebGL)
       .holo-intro-txt[data-holo-exclude]   linke Spalte: Eyebrow, h2, Absatz, Checkliste (Texte unverändert)
       .holo-col[data-holodeck-scroll]      rechte Spalte (Handy/Tablet: über dem Text, randlos)
         figure.holo-stage[data-holodeck-sticky][data-holo-anchor]
                                           ANKER, quadratisch: das Motiv gehört mittig auf ihn, seine Höhe ist die
                                           Canvas-Höhe (senkrechtes FOV fest → Motivgröße = quadratische Bühne dieser
                                           Größe); auch Maß für den Start bei 40 % Sichtbarkeit. Nicht sticky.
           .holo-frame                     Canvas + Beschriftungen (.hd-lbls, vom Script) + HUD
           figcaption.hd-sr                Beschreibung für Screenreader
   Drei Darstellungen (--hd-layout, erbt bis zum Canvas):
     bleed  Nacht, ab 980 px: Canvas = Anker, waagrecht um --hd-ext-l / --hd-ext-r verbreitert (ohne Linsenverschiebung
            symmetrisch → Motiv mittig auf dem Anker), gleiche Höhe wie der Anker. Liegt HINTER dem Text (Text z-index 2,
            Ebene 0), keine harten Kanten (Maske). Reicht der linke Auslauf in die Textspalte, ist er dort auf höchstens
            ~--hd-dim abgeblendet; der Text hat einen dunklen Schein. HUD (Bildunterschrift + Quellenangabe) liegt
            deckungsgleich auf dem Anker, unten.
     panel  Tag (body.day), alle Breiten: dunkles, abgerundetes Glaspanel = genau der Anker (Cyan braucht dunklen Grund);
            ab 980 px rechts bündig mit der Inhaltskante der .wrap (--hd-shift 0, wie die Karten darunter).
     stack  Nacht, unter 980 px: Canvas über die volle Fensterbreite, Höhe = Anker (Handy: Anker = volle Breite,
            Tablet: Anker 560 px mittig, seitlich Auslauf bis an die Fensterkanten), weiche Ränder.
   Größen für das Script (Custom Properties, erben bis zum Canvas):
     --hd-labels: wide | narrow   (alle Beschriftungen | reduzierte Handy-Fassung)
     --hd-lod:    0 | 1           (1 = Handy-LOD: feine Struktur- und Rasterlinien entfallen)
     --hd-start:  0 … 1           (sichtbarer Anteil des Ankers, ab dem der Aufbau startet: überall .4)
     --hd-dim:    0 … 1           (Deckkraft des Hologramms am Übergang in die Textspalte, nur bleed)
     --hd-ext-l / --hd-ext-r      (Verbreiterung des Canvas links/rechts über den Anker hinaus, nur bleed;
                                   ungleiche Werte verschieben das Motiv um (l − r)/2 nach links → dann braucht das
                                   Script die Linsenverschiebung auf die Ankermitte - das macht es immer: der Anker ist
                                   der Motivrahmen (autoFrame). Klasse hd-lens am [data-holodeck-scroll] (im Markup
                                   gesetzt) = breiterer linker Auslauf, siehe unten)
     --hc / --hg                  (Ankerbreite = rechte Spalte / Spaltenabstand, ab 980 px)
     --hd-room / --hd-shift       (Platz von der Inhaltskante der .wrap bis zur Fensterkante / Verschiebung des Ankers
                                   nach rechts, ab 980 px; das Script braucht sie nicht — es misst den Anker)
   Alle Klassen mit Präfix hd- bzw. holo- (die Seite hat eigene .bar/.lbl). CSP: nur diese Datei, keine Inline-Styles.
   ===================================================================== */

/* ---------- Einstiegs-Raster: Handy/Tablet (gestapelt, Hologramm über dem Text wie früher die Hochhaus-Grafik) ---------- */
.holo-intro{
  --hd-mono:var(--mono,"IBM Plex Mono",ui-monospace,"SFMono-Regular",Consolas,monospace);
  --hd-layout:stack; --hd-labels:narrow; --hd-lod:1; --hd-start:.4; --hd-dim:1; --hd-ext-l:0px; --hd-ext-r:0px;
  --hp:clamp(20px,5vw,48px);                    /* Seitenrand der .wrap */
  --ha:min(560px,100%);                         /* Ankerbreite gestapelt (Handy: volle Breite, Tablet: 560 px) */
  position:relative;isolation:isolate;
  display:flex;flex-direction:column;gap:clamp(36px,6vw,52px);
}
.holo-intro-txt{position:relative;z-index:2;min-width:0}
/* randlos: die Spalte reicht über den Seitenrand der .wrap bis an die Fensterkanten (ohne 100vw, kein Überlauf) */
.holo-col{order:-1;position:relative;margin:0 calc(-1*var(--hp))}
.holo-stage{position:relative;margin:0 auto;width:var(--ha);aspect-ratio:1/1}
/* Sicherung gegen seitlichen Überlauf (die Verbreiterung hält ohnehin >= 16 px Abstand zur Fensterkante);
   overflow-x:clip macht keinen Scroll-Container */
#wohnungswirtschaft{overflow-x:clip}

/* ---------- Bühne (Grundform = panel: genau der Anker) ---------- */
/* overflow:hidden: die weiche Abdunklung hinter der Bildunterschrift (.hd-bl::before, ±24 px) darf nicht über die
   Bühne ragen (Handy: sonst seitlich scrollbar) */
.holo-frame{position:absolute;inset:0;z-index:0;isolation:isolate;overflow:hidden}
.holo-frame::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none}
.holo-frame canvas{position:absolute;inset:0;z-index:1;display:block;width:100%;height:100%;max-width:none;pointer-events:none;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 5%,#000 95%,transparent 100%),linear-gradient(to bottom,transparent 0,#000 4%,#000 96%,transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(to right,transparent 0,#000 5%,#000 95%,transparent 100%),linear-gradient(to bottom,transparent 0,#000 4%,#000 96%,transparent 100%);
  mask-composite:intersect}

/* ---------- stack: Nacht, gestapelt — Canvas über die volle Breite, Höhe = Anker, keine harten Kanten ---------- */
body:not(.day) .holo-stage{position:static}   /* Bezugsrahmen der Ebene ist dann .holo-col (volle Breite, Höhe = Anker) */
/* ganz leichte Abdunklung hinter dem Motiv (Sterne des Warp-Hintergrunds treten zurück), elliptisch um den Anker */
body:not(.day) .holo-frame::before{
  background:radial-gradient(closest-side at 50% 50%,rgba(4,7,15,.4),rgba(4,7,15,.16) 66%,rgba(4,7,15,0))}
/* seitlich: voll im Anker, Auslauf bis zur Fensterkante (Handy: Anker = volle Breite → 5 %); oben/unten 5 % */
body:not(.day) .holo-frame canvas{
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 max(5%,calc(50% - var(--ha)/2)),#000 min(95%,calc(50% + var(--ha)/2)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 5%,#000 95%,transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 max(5%,calc(50% - var(--ha)/2)),#000 min(95%,calc(50% + var(--ha)/2)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 5%,#000 95%,transparent 100%)}
/* HUD deckungsgleich mit dem Anker (Bildunterschrift unten im Quadrat wie bisher, nicht im Auslauf) */
body:not(.day) .holo-frame .hd-hud{top:0;bottom:0;left:calc(50% - var(--ha)/2);right:auto;width:var(--ha)}

/* ---------- Desktop ab 980 px: zwei Spalten — links Text, rechts der Anker ---------- */
@media (min-width:980px){
  .holo-intro{
    --hd-layout:panel; --hd-labels:narrow; --hd-lod:1; --hd-start:.4;
    /* Anker: 980 px → 380, 1188 px → 514, ab 1197 px 520 (1440: 520); bei niedrigen Fenstern höchstens 100vh − 180 */
    --hc:clamp(380px,min(calc(64.5vw - 252px),calc(100vh - 180px)),520px);
    --hg:clamp(32px,4vw,56px);
    /* Platz rechts der Spalte: Inhaltskante der .wrap → Fensterkante (980–1276 px: nur der Seitenrand 48 px; 1280: 98;
       1440: 178; 1920: 418). 100vw zählt eine klassische Scrollleiste mit → real bis ~9 px weniger (Abstände unten
       deshalb großzügig) */
    --hd-room:calc(max(0px,(100vw - var(--max,1180px))/2) + var(--hp));
    /* „weiter nach rechts“: Anker um bis zu 24 % seiner Breite nach rechts (1440/1920: 125 px), in den Seitenrand hinein,
       aber mit dem Rand >= 28 px vor der Fensterkante (1024: 20 px, 1280: 70 px) */
    --hd-shift:clamp(0px,calc(var(--hd-room) - 28px),calc(var(--hc)*.24));
    /* Verbreiterung je Seite, symmetrisch (= Motiv ohne Linsenverschiebung mittig auf dem Anker): so viel, wie rechts bis
       16 px vor die Fensterkante passt, höchstens 30 % des Ankers (1280: 12 px, 1440: 37 px, 1920: 156 px) */
    --hd-ext-r:clamp(0px,calc(var(--hd-room) - var(--hd-shift) - 16px),calc(var(--hc)*.3));
    --hd-ext-l:var(--hd-ext-r);
    display:grid;grid-template-columns:minmax(0,1fr) var(--hc);column-gap:var(--hg);align-items:center;
  }
  /* die Spalte behält ihre Breite (--hc) und rückt um --hd-shift nach rechts (Ränder statt transform: Rechtecke,
     IntersectionObserver und Klickflächen stimmen, kein Layout-Sprung). Oberer Rand: der Anker sitzt etwas unter der
     Mitte der Textspalte und beginnt so auch bei kurzem Text (ZH: Eyebrow einzeilig) nicht über der Oberkante der h2 */
  .holo-col{order:0;margin:clamp(32px,3.4vw,56px) calc(-1*var(--hd-shift)) 0 var(--hd-shift)}
  .holo-stage{width:100%}
  /* Tag: das harte Glaspanel schließt rechts bündig mit der Inhaltskante der .wrap (wie die Karten darunter) statt in den
     Seitenrand zu ragen (Review 23.10.: 125 px Überhang bei 1440/1920) — nachts verdeckt der weiche Auslauf das, dort
     bleibt die Verschiebung */
  body.day .holo-intro{--hd-shift:0px}
  body:not(.day) .holo-intro{--hd-layout:bleed; --hd-dim:.4}
  /* hd-lens (im Markup gesetzt): weil das Script das Projektionszentrum immer auf die Ankermitte legt (Motivrahmen =
     Anker), darf der linke Auslauf breiter werden als der rechte — Ring- und
     Trassenlinien laufen dann weich bis höchstens 15 % der Ankerbreite unter den Rand der Textspalte (dort <= ~--hd-dim,
     Türme bleiben im Anker). 1440: 234 px → 53 px unter dem Text; 1024: 122 px → 41 px */
  body:not(.day) .holo-col.hd-lens{--hd-ext-l:max(var(--hd-ext-r),min(calc(var(--hc)*.45),calc(var(--hg) + var(--hd-shift) + var(--hc)*.15)))}

  /* bleed: Canvas = Anker, links/rechts verbreitert, gleiche Höhe; hinter dem Text (Text z-index 2, Ebene 0) */
  body:not(.day) .holo-stage{position:relative}
  body:not(.day) .holo-frame{top:0;bottom:0;left:calc(-1*var(--hd-ext-l));right:calc(-1*var(--hd-ext-r))}
  body:not(.day) .holo-frame::before{
    background:radial-gradient(closest-side at calc(var(--hd-ext-l) + var(--hc)/2) 50%,rgba(4,7,15,.42),rgba(4,7,15,.16) 66%,rgba(4,7,15,0))}
  /* Maske, waagrecht: Canvas-Rand 0 → bei 55 % des linken Auslaufs --hd-dim → kurz hinter der Ankerkante voll; rechts
     spiegelbildlich (ohne Text dort: .45). Jede Seite blendet über mindestens 14/28 px aus (auch wenn der Auslauf
     schmal ist oder fehlt → nie eine harte Kante; ragt die Blende dann bis 16 px in den Anker, liegt der Plattformrand
     mit ~6 % Abstand zur Ankerkante noch voll sichtbar). Ein Auslauf
     unter der Textspalte bleibt damit unter ~--hd-dim. Senkrecht: 5 % Auslauf oben/unten (Anker so hoch wie der Canvas) */
  body:not(.day) .holo-frame canvas{
    -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,var(--hd-dim)) max(calc(var(--hd-ext-l)*.55),14px),#000 max(calc(var(--hd-ext-l) + 2%),28px),#000 calc(100% - max(calc(var(--hd-ext-r) + 2%),28px)),rgba(0,0,0,.45) calc(100% - max(calc(var(--hd-ext-r)*.55),14px)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 5%,#000 95%,transparent 100%);
    mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,var(--hd-dim)) max(calc(var(--hd-ext-l)*.55),14px),#000 max(calc(var(--hd-ext-l) + 2%),28px),#000 calc(100% - max(calc(var(--hd-ext-r) + 2%),28px)),rgba(0,0,0,.45) calc(100% - max(calc(var(--hd-ext-r)*.55),14px)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 5%,#000 95%,transparent 100%)}
  /* HUD deckungsgleich mit dem Anker: Bildunterschrift + Quellenangabe unten im Anker, nie unter dem Text */
  body:not(.day) .holo-frame .hd-hud{top:0;bottom:0;left:var(--hd-ext-l);right:var(--hd-ext-r);width:auto}
  /* Lesbarkeit: dunkler Schein um die Schrift (auf dunklem Grund unsichtbar, trennt sie von Linien dahinter) */
  body:not(.day) .holo-intro-txt{text-shadow:0 0 2px rgba(4,7,15,.9),0 0 10px rgba(4,7,15,.85),0 0 22px rgba(4,7,15,.6)}
}
/* volle Beschriftung (Trassen, Anschluss T1–T4, Straßennamen) ab 1188 × 646 (Anker dann 514–520 px; Messung der
   alten quadratischen Bühne: 448 px viele Konflikte, 511 px einzelne, 552 px keine; im Einstieg 23.10. über Aufbau und
   volle Drehung neu gemessen: 0 harte Konflikte bei 1280–1920 px) */
@media (min-width:1188px) and (min-height:646px){
  .holo-intro{--hd-labels:wide}
}

/* ---------- panel: Tag — dunkles Glaspanel (wie die Glasflächen der Seite, nur dunkel), feine Cyan-Kante ---------- */
body.day .holo-intro{--hd-layout:panel; --hd-dim:1}   /* alle Breiten (sonst meldet das Handy tags „stack“) */
body.day .holo-frame{border-radius:22px;
  background:radial-gradient(120% 95% at 50% 32%,#0B1630 0%,#070D1C 46%,#04070F 100%);
  box-shadow:0 26px 60px -34px rgba(20,52,90,.55),0 2px 10px -6px rgba(20,52,90,.25)}
body.day .holo-frame::before{background:linear-gradient(180deg,rgba(174,228,255,.05),transparent 90px)}
body.day .holo-frame::after{content:"";position:absolute;inset:0;z-index:4;border-radius:inherit;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(57,194,255,.30),inset 0 1px 0 rgba(174,228,255,.22)}
@media (max-width:599.98px){body.day .holo-frame{border-radius:0}}

/* kein WebGL: Bühne ausblenden, Text nimmt die ganze Breite */
.holo-col.hd-nogl{display:none}
@media (min-width:980px){.holo-intro:has(.hd-nogl){grid-template-columns:minmax(0,1fr)}}

/* Screenreader-Text */
.hd-sr{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- HUD: Bildunterschrift (Aufbau-Phase, am Ende die Schlusszeile), Fortschritt, Quellenangabe ---------- */
.hd-hud{position:absolute;inset:0;z-index:3;pointer-events:none;
  font:500 10px/1.4 var(--hd-mono);letter-spacing:.1em;text-transform:uppercase;color:rgba(174,228,255,.66)}
.hd-hud.is-off>:not(.hd-attr){display:none}
.hd-hud .hd-bl{position:absolute;left:max(14px,4%);right:max(14px,4%);bottom:30px;display:flex;align-items:flex-end;gap:12px;z-index:0}
.hd-hud .hd-phase{flex:1;min-width:0;color:#AEE4FF;transition:color .6s ease}
.hd-hud.is-final .hd-phase{color:#fff}
.hd-hud .hd-pct{flex:none;color:#39C2FF;font-variant-numeric:tabular-nums}
.hd-hud.is-final .hd-pct{display:none}
.hd-hud .hd-pct:empty{display:none}
.hd-hud .hd-track{position:absolute;left:0;right:0;bottom:-8px;height:1px;background:rgba(57,194,255,.16);overflow:hidden}
.hd-hud .hd-bar{display:block;height:100%;background:#39C2FF;transform-origin:0 50%;transform:scaleX(0);box-shadow:0 0 6px #39C2FF}
.hd-hud.is-final .hd-track{opacity:.45;transition:opacity 1s ease}
/* weiche Abdunklung hinter der Bildunterschrift: die Szene läuft nie durch den Text */
.hd-hud .hd-bl::before{content:"";position:absolute;z-index:-1;left:-24px;right:-24px;top:-22px;bottom:-22px;
  background:linear-gradient(to top,rgba(4,7,15,.72) 0%,rgba(4,7,15,.5) 55%,rgba(4,7,15,0) 100%);
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 24px,#000 calc(100% - 24px),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 24px,#000 calc(100% - 24px),transparent 100%)}
/* Quellenangabe Lageplan (ODbL): klein, zurückhaltend, lesbar, als Link */
.hd-hud .hd-attr{position:absolute;right:max(14px,4%);bottom:7px;z-index:1;font:400 9.5px/1.2 var(--hd-mono);letter-spacing:.04em;text-transform:none;color:rgba(174,228,255,.62)}
.hd-hud .hd-attr a{pointer-events:auto;color:inherit;text-decoration:underline;text-decoration-color:rgba(174,228,255,.35);text-underline-offset:2px}
.hd-hud .hd-attr a:hover{color:#DEF4FF;text-decoration-color:currentColor}

/* ---------- Beschriftungen mit Führungslinie (Script positioniert sie) ---------- */
.hd-lbls{position:absolute;inset:0;z-index:2;overflow:hidden;pointer-events:none;
  font:600 9px/1.35 var(--hd-mono);letter-spacing:.12em;text-transform:uppercase}   /* 9 px: bei 552 px Bühne 0 Label-Konflikte (10 px: 63 von 186 Bildern) */
.hd-lbl-svg{position:absolute;inset:0;width:100%;height:100%;max-width:none;display:block}
.hd-lbl-svg polyline{fill:none;stroke:rgba(174,228,255,.62);stroke-width:1;vector-effect:non-scaling-stroke}
.hd-lbl-svg rect{fill:#AEE4FF}
.hd-lbl-svg rect.hd-frm{fill:none;stroke:rgba(222,244,255,.78);stroke-width:1;vector-effect:non-scaling-stroke}
.hd-lbl{position:absolute;left:0;top:0;white-space:nowrap;padding:1px 4px;background:rgba(4,7,15,.55);color:rgba(222,244,255,.96);
  text-shadow:0 0 3px #04070F,0 0 8px rgba(4,7,15,.9);opacity:0;will-change:transform,opacity;transition:none}
.hd-lbl-st{position:absolute;left:0;top:0;white-space:nowrap;transform-origin:0 0;font:400 9.5px/1 var(--hd-mono);
  letter-spacing:.1em;text-transform:none;color:rgba(174,228,255,.72);text-shadow:0 0 3px #04070F;opacity:0;will-change:transform,opacity;transition:none}
.hd-lbl-n{position:absolute;left:0;top:0;font:600 11px/1 var(--hd-mono);letter-spacing:0;color:rgba(174,228,255,.78);
  text-shadow:0 0 3px #04070F,0 0 6px #04070F;opacity:0;will-change:transform,opacity;transition:none}
/* Handy/Tablet (gestapelt): etwas kleinere Schrift */
@media (max-width:979.98px){
  .hd-hud{font-size:9.5px;letter-spacing:.1em}
}
/* Chinesisch: serifenlose CJK-Schrift als Rückfall hinter der Mono-Schrift (sonst greift für die Schriftzeichen eine
   Serifen-Schrift wie SimSun), keine Versalien-Sperrung, etwas größer (Schriftzeichen bei 9–10 px kaum lesbar) */
.holo-intro:lang(zh){--hd-mono:"IBM Plex Mono",ui-monospace,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC","Noto Sans SC","Source Han Sans SC",sans-serif}
.hd-lbls:lang(zh),.hd-hud:lang(zh){letter-spacing:.04em}
.hd-lbls:lang(zh){font-size:11px}
.hd-hud:lang(zh){font-size:12px}
@media (max-width:979.98px){.hd-hud:lang(zh){font-size:11px}}

/* reduzierte Bewegung: statisches Endbild (Script); Layout wie oben — es gibt keine Scroll-Strecke und kein sticky mehr */
