/* ============================================================
   Licht-Intro – LED-Ringleuchte über der Hero-Section.
   Alles im li-Namespace, weil styles.css --glow und --text
   bereits belegt. JS setzt nur die --li-Variablen und die
   Zustandsklassen am <body>:
     li-on        Licht logisch an
     li-revealed  Hero-Inhalt freigelegt (bleibt danach gesetzt)
     li-settled   Einschalt-Sequenz abgeschlossen
     li-torchlive Taschenlampe hat die Maus schon gesehen
     li-notorch   Touch-Gerät, keine Taschenlampe
   ============================================================ */
:root{
  --li-lit: 0;                  /* 0/1 – Licht logisch an */
  --li-glow: 0;                 /* 0..1 – momentane Helligkeit (flackert) */
  --li-color: #ff9d3d;          /* ~2000 K, rampt auf #ffd9a0 (~2700 K) */
  --li-sat: 1.4;
  --li-mx: 50vw;
  --li-my: 38vh;
  --li-ix: 50vw;                /* Mausposition relativ zu .hero__inner */
  --li-iy: -20vh;

  /* Bühne = was nach dem Header vom ersten Bildschirm übrig bleibt.
     Die Leuchte darf davon höchstens --li-lamp-share einnehmen, sonst
     schiebt ihr padding-top den Hero-Inhalt aus dem Viewport – auf iPad
     und Laptop lag die CTA dadurch unter der Kante. */
  --li-stage: calc(100svh - var(--header-h));
  --li-lamp-share: 0.34;

  /* Leuchte: viewBox 520 x 330 */
  --li-lamp-w: min(80vw, 600px, calc(var(--li-stage) * var(--li-lamp-share) / 0.635));
  --li-lamp-h: calc(var(--li-lamp-w) * 0.635);
}

@media (prefers-reduced-motion: no-preference){
  html{ scroll-behavior:smooth; }
}

/* Ohne JS bleibt die Seite exakt wie vorher */
html.no-js .li-layer{ display:none; }

/* Mit JS: bis zum Reveal kein Scroll, Header unsichtbar */
html.js body:not(.li-revealed){ overflow:hidden; }
html.js body:not(.li-revealed) .header{ opacity:0; pointer-events:none; }
.header{
  transition:
    background .35s var(--ease),
    border-color .35s var(--ease),
    backdrop-filter .35s var(--ease),
    opacity .8s ease .25s;
}

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

/* ============================================================
   Hero wird zur Bühne
   ============================================================ */
/* Der Hintergrund bleibt durchgehend schwarz – kein Bild */
html.js .hero{
  min-height:100svh;
  background:#000;
  --li-outro:clamp(4rem, 12svh, 10rem);
  /* garantiert, dass der Text unter den Ringen beginnt */
  padding-top:calc(var(--header-h) + var(--li-lamp-h) * 0.84);
}

/* Die Bühne läuft unten in die Grundfläche der Seite aus, sonst schneidet
   ihr Schwarz hart gegen den ersten Abschnitt ab.
   Der Verlauf muss über Regal-Scrim und Vignette liegen (beide bis z-index 2)
   – im Hintergrund der .hero säße er darunter und käme nur zu gut einem
   Drittel durch, die Kante bliebe. Unter dem Inhalt (z-index 3) bleibt er
   trotzdem, deshalb darf er ruhig bis in die Fact-Zeile reichen.
   Die Zwischenstopps runden die Rampe an ihren Enden ab. */
html.js .hero::after{
  content:"";
  position:absolute;
  inset:auto 0 0;
  height:var(--li-outro);
  z-index:2;
  pointer-events:none;
  background:linear-gradient(
    to bottom,
    color-mix(in srgb, var(--ink-900) 0%, transparent) 0%,
    color-mix(in srgb, var(--ink-900) 16%, transparent) 25%,
    color-mix(in srgb, var(--ink-900) 50%, transparent) 50%,
    color-mix(in srgb, var(--ink-900) 84%, transparent) 75%,
    var(--ink-900) 100%
  );
}
html.js body:not(.li-on) .hero{ cursor:pointer; }

.li-vignette{
  position:absolute; inset:0; z-index:2;
  pointer-events:none;
  opacity:calc(var(--li-glow) * .62);
  background:radial-gradient(ellipse 104% 94% at 50% 44%, transparent 64%, rgba(0,0,0,.7) 100%);
}

/* ============================================================
   Raum im Hintergrund
   Kulisse hinter allem (z-index 0): die Halle, in der die Leuchte hängt.
   Der Fluchtpunkt liegt auf der Höhe, aus der auch die Ringe gesehen
   werden – Kulisse und Leuchte stehen dadurch im selben Raum. Ein
   frontaler Aufriss hinter einer perspektivischen Leuchte kann das Auge
   nicht zusammenbringen; genau daran scheiterte das Regal, das hier
   vorher stand.
   Drei Mittel halten den Raum von der Schrift getrennt, ohne ihn
   unsichtbar zu machen:
     1. Tiefenunschärfe – die Headline bleibt die einzige scharfe Kante
     2. eine Maske, deren Zentrum auf dem Lichtfleck sitzt
     3. ein weicher Scrim genau dort, wo der Hero-Text steht
   Die Helligkeit hängt an --li-glow: im Dunkeln ahnt man den Raum nur,
   beim Einschalten kommt er mit der Leuchte hoch.
   ============================================================ */
/* Breiter als der Viewport – und zwar bewusst: der Raum bleibt am unteren
   Rand verankert, über die Breite hinaus skaliert wächst er also nach oben.
   Bei Viewportbreite lag die Decke genau auf der Headline, die Leuchtenreihen
   liefen quer durch „Professionelle“. Skaliert steht man näher am
   Fluchtpunkt: die Decke sitzt über der Schrift, der Boden behält seinen
   Kontakt zur Unterkante – eine reine Verschiebung nach oben würde ihn dort
   abreißen lassen. Dieselbe Lesart wie auf dem Handy weiter unten.
   Wo die Decke landet, hängt an der Höhe des Raums, und die Höhe hängt bei
   festem Seitenverhältnis (1600:620) an der Breite. Deshalb steht neben der
   Viewportbreite ein Maß in svh: auf flachen, schmalen Schirmen (Tablet quer)
   reichten 128 % nicht, dort sitzt die Headline relativ höher. 202svh
   entspricht rund 78 svh Raumhöhe – der größere der beiden Werte gewinnt. */
.li-room{
  position:absolute; z-index:0;
  left:50%; bottom:0;
  width:max(128%, 202svh, 620px);
  transform:translateX(-50%);
  pointer-events:none;
}
.li-room__svg{
  display:block;
  width:100%; height:auto;
  /* Deckel gegen zu hohe Räume auf breiten Schirmen. Er muss zur Breite
     oben passen: bliebe er bei 72svh, käme die Skalierung nicht an – die
     Höhe wäre schon vorher gekappt und die Decke stünde wieder auf der
     Headline.                                                            */
  max-height:86svh;
  margin-inline:auto;
  opacity:calc(.05 + var(--li-glow) * .52);
  filter:blur(1.4px);
  /* Zwei Masken im Schnitt: die Ellipse setzt den Schwerpunkt auf den
     Lichtfleck am Boden, der lineare Verlauf löst die Decke nach oben ins
     Dunkel auf – sonst zögen die Deckenkanten als harte Linien durch die
     Headline. Ohne mask-composite bleibt die Vereinigung übrig: dann ist
     der Raum etwas präsenter, aber nichts bricht. */
  -webkit-mask-image:
    radial-gradient(ellipse 82% 90% at 52% 56%,
      #000 16%, rgba(0,0,0,.62) 52%, transparent 92%),
    linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.55) 5%, #000 15%);
          mask-image:
    radial-gradient(ellipse 82% 90% at 52% 56%,
      #000 16%, rgba(0,0,0,.62) 52%, transparent 92%),
    linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.55) 5%, #000 15%);
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-composite:source-in;
          mask-composite:intersect;
}
/* Scrim – liegt über dem Raum, aber unter dem Inhalt (z-index 3) */
.li-room::after{
  content:"";
  position:absolute; inset:0 -6% 0 -6%;
  /* Schwächer als beim Regal: dort musste ein ganzes Möbel weggedrückt
     werden, hier laufen nur dünne Linien durch – und die Fluchtlinien
     sind der Punkt der ganzen Kulisse. Ganz weggedrückt bliebe rechts
     ein halber Raum ohne Fluchtpunkt übrig.                            */
  background:
    radial-gradient(ellipse 54% 58% at 24% 62%,
      rgba(0,0,0,.72), rgba(0,0,0,.42) 46%, transparent 80%),
    linear-gradient(to bottom, transparent 0%, rgba(0,0,0,.28) 62%, rgba(0,0,0,.56) 100%);
}

/* Konturen. Der Verlauf ist radial um den Lichtfleck am Boden gelegt und
   läuft nach außen in die Durchsichtigkeit: der Raum ist dort zu sehen,
   wo Licht auf ihn fällt, und löst sich am Rand auf, statt an einer
   Bildkante abgeschnitten zu werden.                                   */
.li-rm-stop-a{ stop-color:#c3d4dd; stop-color:color-mix(in srgb, #c3d4dd 55%, var(--li-color)); }
.li-rm-stop-b{ stop-color:#5d6b73; stop-opacity:.7; }
.li-rm-stop-c{ stop-color:#1b2429; stop-opacity:0; }

/* Die Rückwand bleibt eine reine Kontur. Gefüllt setzte sie eine große,
   etwas hellere Fläche mitten hinter die Headline – genau die Kante, an
   der schon das Regal gescheitert ist. Sie muss auch nichts verdecken:
   das Bodenraster endet ohnehin an ihrem Fuß.                          */
.li-rm-plane{
  fill:none;
  stroke:url(#liRmEdge);
  stroke-width:1.5;
}
/* Die Stützen dagegen füllen: sie stehen im Raster und müssen die Fugen
   hinter sich abdecken, sonst sind sie durchsichtig. */
.li-rm-post{
  fill:url(#liRmBody);
  stroke:url(#liRmEdge);
  stroke-width:1.5;
}
/* Der Boden ist die Fläche, auf die das Licht fällt – er trägt den Raum
   und steht deshalb nicht zurück. Zurück steht alles, was außerhalb des
   Lichtflecks liegt, und das regelt schon der Verlauf.                 */
.li-rm-grid{ fill:none; stroke:url(#liRmEdge); stroke-width:1.2; opacity:.9; }
.li-rm-line{ fill:none; stroke:url(#liRmEdge); stroke-width:1.7; }
/* Lichtbänder in der Decke und die Leuchtenreihe der Halle – bewusst
   schwach, sie sollen der Headline keine Konkurrenz machen. Beide hängen
   an --li-glow und kommen mit der Leuchte hoch.                        */
.li-rm-band{
  fill:none;
  stroke:var(--li-color);
  stroke-width:3;
  stroke-linecap:round;
  opacity:calc(.1 + var(--li-glow) * .34);
}
.li-rm-lamp{
  fill:var(--li-color);
  stroke:none;
  opacity:calc(.08 + var(--li-glow) * .38);
}

/* ============================================================
   Ringleuchte
   ============================================================ */
.li-assembly{
  position:absolute; z-index:1;
  top:0; left:calc(50% - var(--li-lamp-w) / 2);
  width:var(--li-lamp-w); height:100%;
  transform-origin:50% 0;              /* Aufhängung an der Decke */
}
body.li-on:not(.li-settled) .li-assembly{ filter:saturate(var(--li-sat)); }
.li-assembly.li-swing{ animation:liSway 4s ease-in-out; }
@keyframes liSway{
  0%{ transform:rotate(0deg); }
  10%{ transform:rotate(1.9deg); }
  28%{ transform:rotate(-1.4deg); }
  46%{ transform:rotate(.95deg); }
  64%{ transform:rotate(-.55deg); }
  82%{ transform:rotate(.24deg); }
  100%{ transform:rotate(0deg); }
}

.li-lamp{
  position:absolute; top:0; left:50%;
  transform:translateX(-50%);
  width:var(--li-lamp-w); height:var(--li-lamp-h);
  display:block; overflow:visible;
}

/* Aufhängeseile – nach oben ins Dunkel verlaufend (Gradient im SVG) */
.li-wires rect{ fill:url(#liWire); }

/* Farbstops, die der Lampenfarbe folgen */
.li-stop-c{ stop-color:var(--li-color); }
.li-stop-w{ stop-color:#fff; stop-color:color-mix(in srgb, #ffffff 78%, var(--li-color)); }

/* Gehäuse: im Aus-Zustand sichtbares Metall mit Rim-Light von oben */
.li-shell{
  fill:none;
  stroke:url(#liMetal);
  opacity:.86;
  transition:opacity .6s ease;
}
body.li-on .li-shell{ opacity:1; }

/* warmer Reflex auf dem Metall, sobald die LED brennt */
.li-warm{
  fill:none;
  stroke:url(#liWarm);
  opacity:var(--li-glow);
}

/* Leuchtstreifen, sitzt an der Innenkante des Profils */
.li-led{
  fill:none;
  stroke:url(#liLed);
  opacity:var(--li-glow);
}
/* schmaler, fast weißer Kern – gibt der LED Schärfe */
.li-core{
  fill:none;
  stroke:#fff;
  stroke:color-mix(in srgb, #ffffff 82%, var(--li-color));
  opacity:calc(var(--li-glow) * .85);
}
/* weicher Lichthof direkt am Ring (feGaussianBlur statt drop-shadow) */
.li-bloom{
  fill:none;
  stroke:var(--li-color);
  opacity:calc(var(--li-glow) * .55);
}

/* Ringmaße: Gehäuse dick, LED schmal, Kern haarfein */
.li-ring--a .li-shell{ stroke-width:11; }
.li-ring--a .li-warm { stroke-width:11; }
.li-ring--a .li-led  { stroke-width:4.6; }
.li-ring--a .li-core { stroke-width:1.4; }
.li-ring--a .li-bloom{ stroke-width:9; }
.li-ring--b .li-shell{ stroke-width:9; }
.li-ring--b .li-warm { stroke-width:9; }
.li-ring--b .li-led  { stroke-width:3.8; }
.li-ring--b .li-core { stroke-width:1.2; }
.li-ring--b .li-bloom{ stroke-width:7.5; }
.li-ring--c .li-shell{ stroke-width:7.5; }
.li-ring--c .li-warm { stroke-width:7.5; }
.li-ring--c .li-led  { stroke-width:3.1; }
.li-ring--c .li-core { stroke-width:1; }
.li-ring--c .li-bloom{ stroke-width:6; }

/* ---------- Zugschalter ---------- */
.li-pull{
  position:absolute; z-index:3;
  left:calc(50% + var(--li-lamp-w) * .105);
  top:calc(var(--li-lamp-h) * .70);
  width:40px; height:88px; margin-left:-20px;
  background:none; border:0; padding:0;
  cursor:pointer; display:block;
  opacity:.25;
  animation:liCordPulse 3s ease-in-out infinite;
}
.li-pull .li-cord{
  position:absolute; left:50%; top:0;
  width:1px; height:52px; margin-left:-.5px;
  background:#79838b;
}
.li-pull .li-knob{
  position:absolute; left:50%; top:52px;
  width:4px; height:16px; margin-left:-2px;
  border-radius:2px;
  background:linear-gradient(to right, #4b545b, #9aa4ab, #4b545b);
}
@keyframes liCordPulse{ 0%,100%{ opacity:.15; } 50%{ opacity:.35; } }
/* Einmal gezogen, hat der Schalter seinen Zweck erfüllt – er fährt
   nach der Zugbewegung weg und lässt die Leuchte clean stehen */
body.li-on .li-pull{
  animation:none;
  opacity:0;
  pointer-events:none;
  transition:opacity .7s ease .5s;
}
.li-pull:focus-visible{
  opacity:.75; outline:1px solid rgba(245,237,225,.45);
  outline-offset:6px; border-radius:8px;
}
.li-pull.li-pulling{
  animation:liCordPulse 3s ease-in-out infinite,
            liCordPull .55s cubic-bezier(.34,1.56,.64,1);
}
body.li-on .li-pull.li-pulling{ animation:liCordPull .55s cubic-bezier(.34,1.56,.64,1); }
@keyframes liCordPull{
  0%{ transform:translateY(0); }
  35%{ transform:translateY(12px); }
  60%{ transform:translateY(-3px); }
  80%{ transform:translateY(1px); }
  100%{ transform:translateY(0); }
}

/* ---------- Lichtwurf ----------
   Kein Polygon-Kegel mehr: gestapelte weiche Ellipsen, deren oberste
   der Form der Ringe folgt und die nach unten größer und schwächer
   werden. Weil jede Stufe weich ausläuft, entsteht nirgends eine
   sichtbare Kante. Die Box ist breiter als die Leuchte, damit das
   Licht seitlich auslaufen kann.                                    */
.li-wash{
  position:absolute; inset:0 -150%;
  pointer-events:none;
  mix-blend-mode:screen;
  opacity:var(--li-glow);
  background:
    /* Lichtaustritt an den Ringen selbst */
    radial-gradient(ellipse calc(var(--li-lamp-w) * .30) calc(var(--li-lamp-h) * .30)
      at 46.5% calc(var(--li-lamp-h) * .42),
      color-mix(in srgb, var(--li-color) 26%, transparent), transparent 72%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .24) calc(var(--li-lamp-h) * .24)
      at 52.5% calc(var(--li-lamp-h) * .54),
      color-mix(in srgb, var(--li-color) 20%, transparent), transparent 72%),
    /* nach unten auslaufender Wurf */
    radial-gradient(ellipse calc(var(--li-lamp-w) * .44) calc(var(--li-lamp-h) * .66)
      at 49% calc(var(--li-lamp-h) * .82),
      color-mix(in srgb, var(--li-color) 22%, transparent), transparent 74%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .66) calc(var(--li-lamp-h) * 1.1)
      at 49% calc(var(--li-lamp-h) * 1.35),
      color-mix(in srgb, var(--li-color) 15%, transparent), transparent 76%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .95) calc(var(--li-lamp-h) * 1.7)
      at 49% calc(var(--li-lamp-h) * 2.2),
      color-mix(in srgb, var(--li-color) 13%, transparent), transparent 78%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * 1.3) calc(var(--li-lamp-h) * 2.4)
      at 49% calc(var(--li-lamp-h) * 3.4),
      color-mix(in srgb, var(--li-color) 9%, transparent), transparent 80%),
    /* Grundschein: Die Stufen oben folgen der Leuchte und wären auf halber
       Hero-Höhe zu Ende – diese beiden sind an der Bühne selbst bemessen
       (Prozent = Boxmaß) und tragen das Licht bis in die Ecken. */
    radial-gradient(ellipse 46% 58% at 49% 30%,
      color-mix(in srgb, var(--li-color) 7%, transparent), transparent 76%),
    radial-gradient(ellipse 62% 96% at 49% 46%,
      color-mix(in srgb, var(--li-color) 4%, transparent), transparent 82%);
}
body.li-on:not(.li-settled) .li-wash{ filter:saturate(var(--li-sat)); }

/* ---------- Staub im Licht ----------
   Dieselbe Ellipsenform als Maske: die Partikel sitzen exakt dort,
   wo Licht ist, und faden am Rand des Lichts weich aus.             */
.li-dust{
  position:absolute; inset:0 -95%;
  -webkit-mask-image:
    radial-gradient(ellipse calc(var(--li-lamp-w) * .34) calc(var(--li-lamp-h) * .34)
      at 46.5% calc(var(--li-lamp-h) * .42), #000, transparent 72%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .44) calc(var(--li-lamp-h) * .66)
      at 49% calc(var(--li-lamp-h) * .85), #000, transparent 74%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .6) calc(var(--li-lamp-h) * 1.0)
      at 49% calc(var(--li-lamp-h) * 1.4), #000, transparent 76%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .82) calc(var(--li-lamp-h) * 1.4)
      at 49% calc(var(--li-lamp-h) * 2.2), #000, transparent 78%);
          mask-image:
    radial-gradient(ellipse calc(var(--li-lamp-w) * .34) calc(var(--li-lamp-h) * .34)
      at 46.5% calc(var(--li-lamp-h) * .42), #000, transparent 72%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .44) calc(var(--li-lamp-h) * .66)
      at 49% calc(var(--li-lamp-h) * .85), #000, transparent 74%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .6) calc(var(--li-lamp-h) * 1.0)
      at 49% calc(var(--li-lamp-h) * 1.4), #000, transparent 76%),
    radial-gradient(ellipse calc(var(--li-lamp-w) * .82) calc(var(--li-lamp-h) * 1.4)
      at 49% calc(var(--li-lamp-h) * 2.2), #000, transparent 78%);
  opacity:calc(var(--li-lit));
  transition:opacity 1s ease;
}
/* Einblenden erst 300 ms nach dem finalen Helligkeitssprung */
body.li-on .li-dust{ transition-delay:.3s; }
body:not(.li-on) .li-dust{ transition-duration:.45s; transition-delay:0s; }
.li-dust span{
  position:absolute;
  border-radius:50%;
  background:var(--li-color);
  opacity:0;
  animation:liRiseA var(--dur) linear var(--del) infinite;
}
.li-dust span[data-v="1"]{ animation-name:liRiseB; }
.li-dust span[data-v="2"]{ animation-name:liRiseC; }
@keyframes liRiseA{
  0%{ transform:translate3d(0,30px,0); opacity:0; }
  12%{ opacity:var(--po); }
  34%{ transform:translate3d(calc(var(--dx) * .45), -6px, 0); opacity:calc(var(--po) * .45); }
  55%{ opacity:var(--po); }
  78%{ transform:translate3d(calc(var(--dx) * .7), -32px, 0); opacity:calc(var(--po) * .55); }
  100%{ transform:translate3d(var(--dx), -52px, 0); opacity:0; }
}
@keyframes liRiseB{
  0%{ transform:translate3d(0,24px,0); opacity:0; }
  14%{ opacity:var(--po); }
  30%{ transform:translate3d(calc(var(--dx) * -.5), 2px, 0); }
  42%{ opacity:calc(var(--po) * .4); }
  66%{ opacity:var(--po); }
  100%{ transform:translate3d(calc(var(--dx) * .6), -48px, 0); opacity:0; }
}
@keyframes liRiseC{
  0%{ transform:translate3d(0,14px,0); opacity:0; }
  10%{ opacity:calc(var(--po) * .7); }
  38%{ transform:translate3d(calc(var(--dx) * .5), -12px, 0); opacity:var(--po); }
  58%{ opacity:calc(var(--po) * .5); }
  82%{ opacity:var(--po); }
  100%{ transform:translate3d(calc(var(--dx) * -.4), -40px, 0); opacity:0; }
}

/* ============================================================
   Hero-Inhalt: erst Taschenlampen-Kontur, dann Reveal
   Der Container trägt die Taschenlampen-Maske, die Kinder die
   Reveal-Animation – so braucht es keine Ghost-Kopie im DOM.
   ============================================================ */
html.js .hero__inner{ position:relative; z-index:3; }
html.js body:not(.li-revealed) .hero__inner{ pointer-events:none; }

/* Ausgangszustand: nur unter dem Lichtfleck als schwache Kontur

   --li-ix/--li-iy ist die Mausposition relativ zu diesem Element. Sie darf
   nicht im Gradienten selbst stehen: WebKit erzeugt das Maskenbild einmal
   und rechnet es nicht neu, wenn sich eine darin verwendete Custom Property
   ändert. In Safari blieb der Lichtfleck deshalb auf seinem Startwert
   (50vw / -20vh, also oberhalb der Box) stehen – der Kegel wanderte, aber
   aufgedeckt wurde nie etwas. Das Maskenbild ist jetzt fest (320 × 320,
   Kreis in der Mitte); bewegt wird nur noch mask-position, und die wird
   zuverlässig neu aufgelöst. Die Geometrie ist dieselbe wie vorher: Radius
   150 px, Stufen bei 45 / 90 / 147 px. */
html.js body:not(.li-on):not(.li-revealed) .hero__inner{
  opacity:.25;
  filter:blur(1.4px);
  -webkit-mask-image:radial-gradient(circle 150px at 160px 160px, #000 30%, rgba(0,0,0,.55) 60%, transparent 98%);
          mask-image:radial-gradient(circle 150px at 160px 160px, #000 30%, rgba(0,0,0,.55) 60%, transparent 98%);
  -webkit-mask-size:320px 320px; mask-size:320px 320px;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:calc(var(--li-ix) - 160px) calc(var(--li-iy) - 160px);
          mask-position:calc(var(--li-ix) - 160px) calc(var(--li-iy) - 160px);
  transition:opacity .5s ease;
}
/* Touch-Geräte und noch nie bewegte Maus: gar keine Kontur */
html.js body:not(.li-on):not(.li-revealed):not(.li-torchlive) .hero__inner,
html.js body.li-notorch:not(.li-on):not(.li-revealed) .hero__inner{ opacity:0; }

/* Ab dem Einschalten dauerhaft frei – die Kinder tragen den Reveal */
html.js body.li-on .hero__inner,
html.js body.li-revealed .hero__inner{
  opacity:1;
  filter:none;
  -webkit-mask-image:none; mask-image:none;
}
html.js body.li-on .hero__inner > *{
  opacity:0;
  transform:translateY(20px);
  filter:blur(8px);
  /* Aufdeck-Maske, wandert von unten (verdeckt) nach oben (frei) */
  -webkit-mask-image:linear-gradient(to bottom, #000 0%, #000 40%, transparent 62%);
          mask-image:linear-gradient(to bottom, #000 0%, #000 40%, transparent 62%);
  -webkit-mask-size:100% 300%; mask-size:100% 300%;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-position:0 100%; mask-position:0 100%;
}
html.js body.li-revealed .hero__inner > *{
  opacity:1;
  transform:none;
  filter:blur(0);
  -webkit-mask-position:0 0; mask-position:0 0;
  transition:
    opacity .7s ease,
    transform .9s cubic-bezier(.22,.9,.3,1),
    filter .9s ease,
    -webkit-mask-position .9s ease,
    mask-position .9s ease,
    text-shadow .8s ease,
    box-shadow .8s ease;
}
/* Die Aufdeck-Maske klippt am Rand der Elementbox. Bliebe sie liegen,
   würde sie auch alles wegschneiden, was über die Box hinaus gemalt wird –
   der warme Schein um „LED-Technik“ und die Schlagschatten endeten dann an
   einer sichtbaren Kante unter der Headline. Nach dem Reveal kommt sie weg. */
html.js body.li-clear .hero__inner > *{
  -webkit-mask-image:none; mask-image:none;
}

/* Stagger 120 ms */
html.js body.li-revealed .hero__inner > .eyebrow{ transition-delay:0s; }
html.js body.li-revealed .hero__inner > h1{ transition-delay:.12s; }
html.js body.li-revealed .hero__inner > .hero__text{ transition-delay:.24s; }
html.js body.li-revealed .hero__inner > .hero__cta{ transition-delay:.36s; }
html.js body.li-revealed .hero__inner > .hero__facts{ transition-delay:.48s; }

/* ---------- Licht wirft Schatten ---------- */
html.js .hero h1,
html.js .hero__text,
html.js .hero__cta .btn,
html.js .hero__facts dt{
  text-shadow:none;
  transition:text-shadow .8s ease, box-shadow .8s ease;
}
html.js body.li-on.li-revealed .hero h1{
  text-shadow:
    0 4px 6px rgba(0,0,0,.5),
    0 18px 40px rgba(0,0,0,.85),
    0 40px 80px rgba(0,0,0,.6);
}
html.js body.li-on.li-revealed .hero__text,
html.js body.li-on.li-revealed .hero__facts dt{
  text-shadow:
    0 2px 3px rgba(0,0,0,.3),
    0 8px 18px rgba(0,0,0,.38),
    0 18px 36px rgba(0,0,0,.26);
}
/* Der Button bekommt zusätzlich eine helle Oberkante, als schiene
   die Lampe auf seine Kante */
html.js body.li-on.li-revealed .hero__cta .btn{
  box-shadow:
    0 16px 34px -10px rgba(0,0,0,.6),
    0 30px 60px -18px rgba(0,0,0,.4),
    inset 0 1px 0 rgba(255,217,160,.2);
  box-shadow:
    0 16px 34px -10px rgba(0,0,0,.6),
    0 30px 60px -18px rgba(0,0,0,.4),
    inset 0 1px 0 color-mix(in srgb, var(--li-color) 22%, transparent);
}

/* ============================================================
   Taschenlampen-Cursor
   ============================================================ */
.li-torchlayer{
  position:absolute; inset:0; z-index:4;
  pointer-events:none;
  opacity:0; transition:opacity .5s ease;
}
body.li-torchlive .li-torchlayer{ opacity:1; }
body.li-on .li-torchlayer{ opacity:0; transition-duration:.4s; }
body.li-notorch .li-torchlayer{ display:none; }
.li-spot{
  position:absolute; left:0; top:0;
  width:440px; height:440px; border-radius:50%;
  transform:translate3d(calc(var(--li-mx) - 220px), calc(var(--li-my) - 220px), 0);
  will-change:transform;
  mix-blend-mode:screen;
  /* harte Mitte, mehrstufig ausgefranste Kante */
  background:radial-gradient(circle at 50% 50%,
    rgba(247,234,214,.16) 0 26%,
    rgba(247,234,214,.12) 33%,
    rgba(247,234,214,.05) 44%,
    rgba(247,234,214,.085) 49%,
    rgba(247,234,214,.028) 57%,
    rgba(247,234,214,.05) 61%,
    rgba(247,234,214,.012) 70%,
    transparent 76%);
}

/* ---------- Hinweis ---------- */
/* Die Hero ist höher als ein Viewport – der Hinweis muss trotzdem
   im ersten Bildschirm sichtbar bleiben */
.li-hint{
  position:absolute; z-index:5;
  left:0; right:0; top:calc(100svh - 3.75rem);
  margin:0; text-align:center;
  font-family:var(--body, sans-serif);
  font-size:.72rem; letter-spacing:.34em; text-transform:uppercase;
  color:rgba(245,237,225,.34);
  opacity:0;
  animation:liHintIn 1.2s ease 2s forwards;
  pointer-events:none;
}
@keyframes liHintIn{ to{ opacity:1; } }
body.li-on .li-hint, body.li-revealed .li-hint{
  animation:none; opacity:0; transition:opacity .4s ease;
}

/* ============================================================
   Responsiv
   ============================================================ */
@media (max-width: 640px){
  :root{
    /* schmale Geräte dürfen die Ringe seitlich anschneiden */
    --li-lamp-w: min(104vw, 480px, calc(var(--li-stage) * var(--li-lamp-share) / 0.635));
  }
  html.js .hero{ padding-top:calc(var(--header-h) + var(--li-lamp-h) * 0.92); }
  .li-hint{ top:calc(100svh - 2.75rem); }
  /* Bei Viewportbreite bliebe vom Raum nur ein Streifen am unteren Rand.
     Über die Breite hinaus skaliert wächst er in die Höhe – man steht
     dann näher am Fluchtpunkt, sieht also einen Ausschnitt der Halle
     statt der ganzen Halle. Das ist auf einem Handy die bessere Lesart.
     Fester Wert statt der svh-Formel von oben: die würde hier auf über
     1700px gehen und den Raum ins Riesenhafte ziehen. Auf dem Handy steht
     die Headline ohnehin tiefer, die Decke liegt ihr nicht im Weg.       */
  .li-room{ width:max(100%, 1080px); }
}

/* ---------- flache Viewports: Laptop, iPad quer, Handy quer ----------
   Nicht die Leuchte allein entscheidet, ob die CTA im ersten Bildschirm
   liegt – Zeilenhöhe und Abstände des Hero-Textes zählen mit. Beides
   wird an die Höhe gekoppelt, nicht nur an die Breite.                 */
@media (max-height: 900px){
  :root{ --li-lamp-share: 0.30; }
  html.js .hero{ padding-bottom:clamp(1.5rem, 4svh, 3rem); }
  html.js .hero h1{ font-size:clamp(1.75rem, min(9vw, 11svh), 5.75rem); }
  html.js .hero__text{ margin-top:clamp(0.75rem, 2svh, 1.75rem); }
  html.js .hero__cta{ margin-top:clamp(1.25rem, 3.5svh, 2.5rem); }
  html.js .hero__facts{
    margin-top:clamp(1.5rem, 4svh, 4.5rem);
    padding-top:clamp(1rem, 2.5svh, 2rem);
  }
}

@media (max-height: 700px){
  :root{ --li-lamp-share: 0.24; }
  html.js .hero__text{ font-size:1rem; }
}

/* Handy im Querformat: für Lampe, Fließtext und Fakten ist kein Platz –
   sichtbar bleibt, was zählt: Marke, Headline, Handlungsaufforderung. */
@media (max-height: 500px) and (orientation: landscape){
  :root{ --li-lamp-share: 0.20; }
  html.js .hero__text{ display:none; }
  html.js .hero__facts{ display:none; }
  html.js .hero h1{ font-size:clamp(1.5rem, min(7.5vw, 14svh), 3.25rem); }
}

/* ============================================================
   Reduzierte Bewegung: einfacher 300 ms Crossfade
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  .li-led, .li-core, .li-bloom, .li-warm, .li-wash, .li-vignette{
    transition:opacity .3s linear;
  }
  .li-assembly.li-swing, .li-pull.li-pulling{ animation:none; }
  .li-dust{ transition:opacity .3s linear; }
  .li-dust span{ animation:none; opacity:calc(var(--po) * .85); }
  html.js body.li-revealed .hero__inner > *{
    transition-duration:.3s; transition-delay:0s;
  }
}
