/* ==========================================================================
 * NEUES REDESIGN — Eventseite HAMBURG, Scope `live80-v2`
 * --------------------------------------------------------------------------
 * 🔴 ERZEUGTE DATEI — NICHT VON HAND AENDERN.
 *    Quellen: _source/mockups/koeln-extra.css  (gemeinsames Eventkapitel)
 *             hamburg-extra.css                (Anreise + Partybus)
 *    Bauweg : python3 exports/wp-builds/live80-v2/hamburg/scope-css-hamburg.py
 *
 * ERGAENZUNG zu live80-v2.css, kein Ersatz. Das Designsystem (Tokens, Typo,
 * Header, Footer, Act-Karten, Karussell, FAQ, Chatbot, Countdown-Leiste)
 * steht dort und wird auf jeder `_live80_v2`-Seite geladen — auch hier.
 *
 * Teil 1 = das gemeinsame Eventseiten-Kapitel, aus Koeln abgeleitet: die
 *          sechs Hero-Klassen tragen hier `hamburg-` statt `koeln-`, alle
 *          WERTE sind unveraendert. Wer am Eventdesign etwas aendert, aendert
 *          `koeln-extra.css` — beide Seiten ziehen dann mit.
 * Teil 2 = die WordPress-Bruecke.
 * Teil 3 = was es NUR in Hamburg gibt: Anreise OEPNV, Anreise Auto, Partybus.
 * ========================================================================== */

/* ---------- Teil 1: gemeinsames Eventseiten-Kapitel ---------- */
/* ===========================================================================
   20. KÖLN – Eventseite
   ---------------------------------------------------------------------------
   Alles darueber ist das unveraenderte Designsystem der Startseite v3 – auch
   die Act-Karten mit Retro-Bildschirm, das Karussell und die Video-Lightbox.
   Dieses Kapitel ergaenzt NUR, was es dort nicht gibt: den Event-Hero mit
   Stadion-Kulisse und die Lichteffekte.

   ⚠️ Historie, damit es niemand zurueckdreht: Eine erste Fassung zeigte
   Fotokarten mit Spotify-Button, weil fuer die 13 Koelner Acts keine
   YouTube-IDs belegt waren (die Live-Seite verlinkt dort Spotify). Auf
   Kundenwunsch sind es jetzt Videos. Die IDs wurden einzeln recherchiert und
   zweistufig geprueft (Existenz per oEmbed, Einbettbarkeit per IFrame-API
   unter der echten Domain) – Details stehen ueber dem ACTS-Array in der
   koeln-app.js. Erfundene IDs waeren Fehlinformation gewesen, deshalb der
   Umweg.
   =========================================================================== */
/* --- Hero ---------------------------------------------------------------- */
/* Die Neon-Illustration des Stadions liegt als Kulisse hinter dem Hero.
   ⚠️ Zwei Dinge sind Absicht:
   (1) Sie sitzt am UNTEREN Rand und wird nach oben ausmaskiert – sonst
       schneidet sie als sichtbare Kastenkante durch die Headline (dieselbe
       Falle wie beim Horizontglühen, Checkliste 76).
   (2) object-fit:contain, nicht cover: die Illustration traegt Schriftzuege
       und ist randlos komponiert (siehe CLAUDE.md, "Event-Kacheln"). */
.live80-v2 .hamburg-hero{min-height:min(96svh,940px);padding-block:var(--s8) var(--s9)}
/* ⚠️ Deckkraft ist gemessen, nicht geschaetzt: bei .5 stieg die Illustration
   hinter der Textsaeule so weit auf, dass die cyanfarbene Spielstaetten-Zeile
   im unguenstigsten Fall (hellste 5 % der Textflaeche) nur noch 2,39:1
   erreichte – unter der Norm von 3:1 fuer Grossschrift. */
/* ⚠️ transform-origin unten: die Scroll-Skalierung waechst dadurch nach OBEN,
   die Unterkante bleibt stehen. Ohne das entsteht beim Scrollen eine sichtbare
   Farbkante am Fuss des Hero (siehe Kommentar in koeln-app-a.js). */
.live80-v2 .hamburg-skyline{position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  transform-origin:50% 100%;
  width:min(150%,1900px);aspect-ratio:3/2;z-index:0;pointer-events:none;opacity:.34;
  -webkit-mask-image:linear-gradient(to top,#000 0 34%,rgba(0,0,0,.55) 62%,transparent 88%);
          mask-image:linear-gradient(to top,#000 0 34%,rgba(0,0,0,.55) 62%,transparent 88%)}
.live80-v2 .hamburg-skyline img{width:100%;height:100%;object-fit:contain;object-position:50% 100%}
.live80-v2 .hamburg-hero .hero-inner{position:relative;z-index:3;text-align:center;display:grid;
  justify-items:center;gap:var(--s5)}
.live80-v2 .hamburg-logo{width:clamp(150px,17vw,250px);filter:drop-shadow(0 0 24px rgba(255,45,149,.6))}
/* Das Datum ist auf einer Eventseite die wichtigste Zahl der Seite – es steht
   deshalb als eigener Block ueber dem Stadtnamen, nicht als Nebenzeile. */
.live80-v2 .hamburg-date{display:inline-flex;align-items:baseline;gap:var(--s3);flex-wrap:wrap;
  justify-content:center;
  font-family:'Core Sans M','Asap',sans-serif;font-weight:800;
  font-size:clamp(20px,1rem + 1.1vw,30px);letter-spacing:.06em;text-transform:uppercase;
  color:var(--c-gold);
  /* 🔴 DUNKLER Saum ZUERST, Glimmen danach. Auf einem Foto-/Illustrations-
     grund traegt ein reines Leuchten die Lesbarkeit nicht – es hellt die
     Umgebung zusaetzlich auf. Dieselbe Logik wie bei .chrome (siehe dort). */
  text-shadow:0 2px 0 rgba(var(--c-shadow),.85), 0 0 10px rgba(var(--c-shadow),.95),
              0 0 26px rgba(var(--c-shadow),.7), var(--glow-gold)}
.live80-v2 .hamburg-date strong{font-size:.66em;letter-spacing:.2em;color:var(--c-ink-2);
  text-shadow:0 1px 0 rgba(var(--c-shadow),.9), 0 0 12px rgba(var(--c-shadow),.9)}
.live80-v2 .hamburg-city{font-size:var(--fs-4xl);line-height:.86}
/* 🔴 Die Spielstaetten-Zeile sitzt auf einer dunklen Plakette, nicht frei auf
   dem Grund. Grund ist gemessen, nicht Geschmack: Cyan auf dem hellen Hero-
   Pink kam im unguenstigsten Fall auf 2,30:1 – unter der Norm von 3:1 fuer
   Grossschrift. Ein dunkler Textsaum allein loest das nicht (WCAG rechnet
   Schatten nicht an, und die Umgebung bleibt hell); erst eine eigene Flaeche
   unter der Schrift tut es. Optisch passt sie zu den Eckdaten-Pillen darunter.
   ⚠️ Wer die Plakette entfernt, muss die Schriftfarbe auf Weiss stellen. */
.live80-v2 .hamburg-venue{display:inline-block;
  font-family:'Core Sans M','Asap',sans-serif;font-size:clamp(17px,.9rem + .8vw,27px);
  letter-spacing:.2em;text-transform:uppercase;color:var(--c-cyan);
  padding:.3em .95em;border-radius:var(--r-pill);
  border:1px solid rgba(38,224,255,.35);
  background:rgba(var(--c-shadow-deep),.72);backdrop-filter:blur(7px);
  text-shadow:0 0 14px rgba(38,224,255,.5)}
.live80-v2 .hero-actions{display:flex;gap:var(--s4);flex-wrap:wrap;justify-content:center}
/* --- Stadion-Sektion ------------------------------------------------------ */
/* Eigene Rampe, weil "RHEINENERGIESTADION" als ein Wort nicht umbrechen kann:
   die untere Grenze ist an ihm ausgemessen (327px Platz bei 375px Viewport),
   nach oben laeuft sie auf denselben Wert wie --fs-2xl.
   ⚠️ Der Selektor MUSS .sec-head enthalten: das Designsystem setzt
   `.sec-head h2{font-size:var(--fs-3xl)}` (Spezifitaet 0,1,1). Eine einzelne
   Klasse verliert dagegen – nachgemessen, die Ueberschrift blieb bei 40px
   statt 21px und ragte weiter aus dem Bild. */
.live80-v2 .sec-head .venue-h{font-size:clamp(21px,5.2vw,50px)}
.live80-v2 .venue-sec{position:relative;overflow:hidden}
.live80-v2 .venue-illu{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.42}
.live80-v2 .venue-illu img{width:100%;height:100%;object-fit:cover;object-position:50% 42%}
/* Schleier in Magenta, NICHT in Schwarz – Schwarz entsaettigt den Grund und
   erzeugt genau den "schmutzigen" Eindruck (Checkliste 89). */
.live80-v2 .venue-sec::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(122,11,99,.72),rgba(58,17,96,.86))}
.live80-v2 .venue-sec>.wrap{position:relative;z-index:2}
/* --- Der Textblock unter der Ueberschrift ---------------------------------
   🔴 Vorgeschichte in zwei Stufen, damit niemand zurueckdreht (beide am
   2026-08-05, beide vom Kunden abgelehnt):
     1. Ausgangsfassung: drei zentrierte Absaetze in Kleinschrift, frei im
        Raum -> "muss besser umbrochen werden und auch besser gestyled".
     2. Mein erster Umbau: jeder Act auf eigener Zeile, Songtitel cyan,
        Anrede als cyanfarbene Versalzeile, Satzbreite 64ch (518px)
        -> "richtig beschissen, mach es wieder breiter und nicht so chaotisch".
   Stufe 2 war zu viel: Sie hat einen FLIESSTEXT in eine Liste zerlegt und ihn
   mit drei Farben und zwei Schriftschnitten ueberzeichnet – und dabei die
   Zeilen auch noch schmaler gemacht, obwohl "zu eng" nie das Problem war.

   Jetzt: Fliesstext wie im Original, aber BREITER als vorher (860px gegen
   655px), ruhig gesetzt, und mit dem einzigen Eingriff, um den es
   ursprunglich ging – Kuenstlername und Songtitel brechen nicht mehr um.
   Farbe traegt nur noch der Name (weiss/fett), sonst nichts.
   ⚠️ .nobr NICHT durch white-space:nowrap auf dem Absatz ersetzen – dann
   laeuft die ganze Zeile aus dem Bild.
   ------------------------------------------------------------------------- */
.live80-v2 .nobr{white-space:nowrap}
.live80-v2 .venue-copy{position:relative;max-width:860px;margin:var(--s7) auto 0;
  padding:var(--s7) clamp(20px,4vw,56px);
  border-radius:var(--r-lg);
  border:1px solid rgba(38,224,255,.22);
  background:linear-gradient(180deg,rgba(58,17,96,.55),rgba(42,11,73,.66));
  box-shadow:0 26px 70px rgba(var(--c-shadow),.4)}
/* Eine einzige Zierlinie oben – kein zusaetzliches Element, kein Layout. */
.live80-v2 .venue-copy::before{content:"";position:absolute;left:clamp(20px,4vw,56px);right:clamp(20px,4vw,56px);top:-1px;
  height:2px;border-radius:2px;
  background:linear-gradient(90deg,transparent,var(--c-pink),var(--c-cyan),transparent);
  box-shadow:0 0 16px rgba(255,45,149,.5)}
.live80-v2 .venue-copy p{margin:0;font-size:var(--fs-md);line-height:1.75;color:var(--c-ink-2);
  text-align:center;text-wrap:pretty;hyphens:manual}
.live80-v2 .venue-copy p + p{margin-top:var(--s5)}
/* Nur der Name wird hervorgehoben. Songtitel bleiben im Fliesstext stehen –
   sie zusaetzlich einzufaerben war der "chaotisch"-Anteil. */
.live80-v2 .venue-copy b{font-family:'Core Sans M','Asap',sans-serif;font-weight:700;letter-spacing:.03em;color:#fff}
/* Die Ansage etwas groesser; balance gleicht die Restzeile aus, statt eine
   Waise ("in Köln.") stehenzulassen. */
.live80-v2 .vc-lead{font-size:var(--fs-lg);line-height:1.5;text-wrap:balance}
.live80-v2 .vc-brand{font-family:'Core Sans M','Asap',sans-serif;font-weight:800;letter-spacing:.05em;color:#fff}
/* --- Abschluss-CTA: das Ticket -------------------------------------------
   🔴 Vorgeschichte, damit es niemand zurueckdreht: Hier stand ein heller
   Kasten mit Ueberschrift und Knopf. Der Kunde hat ihn am 2026-08-05
   ausdruecklich verworfen ("LANGWEILIG!!!! ... nicht so einen blöden weißen
   kasten"). Die Flaeche ist jetzt selbst das Produkt – ein Ticket mit
   Abrissabschnitt.
   ⚠️ Kein heller Kasten mehr an dieser Stelle. */
.live80-v2 .ticket-sec{position:relative;overflow:hidden;padding-block:var(--s10)}
/* Zwei Scheinwerfer, die auf die Mitte zulaufen – dieselbe Bauart wie die
   Buehnenstrahler ueber dem Line-up, nur enger gestellt. */
.live80-v2 .tk-spots{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.live80-v2 .tk-spots i{position:absolute;top:-20%;width:34vw;height:140%;
  transform-origin:50% 0;mix-blend-mode:screen;opacity:.6;
  -webkit-mask-image:linear-gradient(to bottom,#000,transparent 80%);
          mask-image:linear-gradient(to bottom,#000,transparent 80%)}
.live80-v2 .tk-spots i:first-child{left:-6vw;
  background:linear-gradient(to bottom,rgba(255,217,61,.42),rgba(255,45,149,.12) 45%,transparent 76%);
  animation:sl-l 12s ease-in-out infinite alternate}
.live80-v2 .tk-spots i:last-child{right:-6vw;
  background:linear-gradient(to bottom,rgba(255,45,149,.45),rgba(38,224,255,.1) 45%,transparent 76%);
  animation:sl-r 15s ease-in-out infinite alternate}
.live80-v2 .ticket-sec>.wrap-narrow{position:relative;z-index:2}
/* Das Ticket selbst. Hauptteil + Abriss, dazwischen die Perforation. */
.live80-v2 .ticket{position:relative;display:grid;grid-template-columns:1fr 190px;
  border-radius:var(--r-lg);overflow:hidden;isolation:isolate;
  background:
    radial-gradient(120% 140% at 12% 0%,rgba(255,45,149,.34),transparent 62%),
    linear-gradient(150deg,#4b1a7c 0%,#2a0b49 52%,#3a1160 100%);
  border:2px solid rgba(255,45,149,.5);
  box-shadow:0 30px 80px rgba(var(--c-shadow),.65),
             0 0 40px rgba(255,45,149,.35),0 0 110px rgba(255,45,149,.16)}
/* 🔴 Die Perforation ist eine echte Aussparung, kein aufgemalter Strich:
   die beiden Halbkreise werden per mask aus dem Ticket HERAUSGESCHNITTEN.
   Ein aufgemalter Kreis muesste die Hintergrundfarbe treffen – die ist hier
   aber ein Verlauf und aendert sich mit der Scrollposition. */
.live80-v2 .ticket{
  --perf:190px;   /* Abstand der Perforation vom rechten Rand = Stubbreite */
  -webkit-mask-image:
    radial-gradient(20px 20px at calc(100% - var(--perf)) 0,transparent 19px,#000 20px),
    radial-gradient(20px 20px at calc(100% - var(--perf)) 100%,transparent 19px,#000 20px);
          mask-image:
    radial-gradient(20px 20px at calc(100% - var(--perf)) 0,transparent 19px,#000 20px),
    radial-gradient(20px 20px at calc(100% - var(--perf)) 100%,transparent 19px,#000 20px);
  -webkit-mask-composite:source-in; mask-composite:intersect}
.live80-v2 .tk-main{position:relative;z-index:2;display:grid;justify-items:center;gap:var(--s5);
  text-align:center;padding:var(--s9) var(--s6)}
.live80-v2 .tk-eyebrow{font-family:'Core Sans M','Asap',sans-serif;font-size:var(--fs-xs);
  letter-spacing:.42em;text-transform:uppercase;color:var(--c-gold);text-shadow:var(--glow-gold)}
.live80-v2 .tk-h{font-size:var(--fs-2xl);line-height:1.02}
.live80-v2 .tk-sub{color:var(--c-ink-2);max-width:46ch}
.live80-v2 .tk-btn{min-height:60px;font-size:var(--fs-sm)}
/* Abrissabschnitt, senkrecht gesetzt wie auf einem echten Ticket. */
.live80-v2 .tk-stub{position:relative;z-index:2;display:grid;align-content:center;justify-items:center;
  gap:var(--s3);padding:var(--s6) var(--s4);
  border-left:2px dashed rgba(255,255,255,.35);
  background:linear-gradient(180deg,rgba(255,255,255,.07),rgba(255,255,255,.02))}
/* 🔴 Diese Zeile ist an „KÖLN" ausgemessen — VIER Zeichen. Der Abriss bietet
   innen 158px; bei 26px und .12em Laufweite braucht „KÖLN" davon 81px.
   Jede abgeleitete Eventseite mit einem laengeren Ortsnamen braucht deshalb eine
   EIGENE Rampe in ihrem Kapitel-CSS, sonst wird der Name rechts abgeschnitten:
     KÖLN 81 · HAMBURG 148 · NORWEGEN 122* · OBERHAUSEN 124*   (*mit eigener Rampe)
   Belegt: „NORWEGEN" lief auf 175px (Checkliste 260), „OBERHAUSEN" auf 200px
   (Checkliste 274). ⚠️ Gefunden hat es beide Male der SCREENSHOT — die Sektion
   hatte jeweils die erwartete Hoehe. ⚠️ Und die Gegenrichtung merken: mehr
   Laufweite macht es breiter, nicht schmaler. */
.live80-v2 .tk-city{font-family:'Core Sans M','Asap',sans-serif;font-weight:800;font-size:26px;
  letter-spacing:.12em;color:#fff;text-shadow:0 0 16px rgba(255,45,149,.8)}
.live80-v2 .tk-date{font-family:'Core Sans M','Asap',sans-serif;font-weight:800;font-size:18px;
  letter-spacing:.04em;color:var(--c-gold);font-variant-numeric:tabular-nums}
/* Barcode aus einem Verlauf – kein Bild, keine Schrift, rein dekorativ. */
.live80-v2 .tk-code{width:118px;height:52px;
  background:repeating-linear-gradient(90deg,#fff 0 2px,transparent 2px 4px,
             #fff 4px 5px,transparent 5px 9px,#fff 9px 12px,transparent 12px 14px);
  opacity:.9}
.live80-v2 .tk-no{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--c-ink-3)}
/* 🔴 Neonroehre statt Gluehbirnenkette. Die Kette wurde am 2026-08-05
   verworfen ("eher Zirkus style als 80er") – laufende Birnen sind Jahrmarkt-
   und Theaterfassade, die 80er sind Neonroehre, Chrom und Gitterboden.
   Die Roehre ist ein Rahmen mit doppeltem Schein nach innen UND aussen; das
   unregelmaessige Anlaufen ist derselbe Flacker-Gedanke wie bei den Neonnamen
   der Startseite, nur ruhiger. Nur opacity, kein Filter. */
.live80-v2 .tk-tube{position:absolute;inset:9px;z-index:3;pointer-events:none;
  border:2px solid rgba(255,45,149,.9);border-radius:calc(var(--r-lg) - 8px);
  box-shadow:0 0 10px rgba(255,45,149,.85),0 0 26px rgba(255,45,149,.45),
             inset 0 0 12px rgba(255,45,149,.5),inset 0 0 30px rgba(255,45,149,.2);
  animation:tube 7s ease-in-out infinite}
@keyframes tube{
  0%,100%{opacity:1}
  49%{opacity:1} 50%{opacity:.55} 51.5%{opacity:1} 52.5%{opacity:.7} 53.5%{opacity:1}
}
/* Gitterboden im Fuss des Tickets – Fluchtpunkt-Optik der Zeit.
   Statisch, also kostenlos: zwei Verlaeufe, keine Animation. */
.live80-v2 .tk-grid{position:absolute;left:0;right:0;bottom:0;height:44%;z-index:0;pointer-events:none;
  background:
    repeating-linear-gradient(90deg,transparent 0 38px,rgba(38,224,255,.22) 38px 39px),
    repeating-linear-gradient(0deg,transparent 0 26px,rgba(255,45,149,.18) 26px 27px);
  -webkit-mask-image:linear-gradient(to top,#000,transparent 92%);
          mask-image:linear-gradient(to top,#000,transparent 92%);
  opacity:.75}
/* Hologramm-Streifen, der ueber das Ticket wandert. Nur translateX. */
.live80-v2 .tk-holo{position:absolute;top:0;bottom:0;left:0;width:34%;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.16) 45%,
             rgba(38,224,255,.14) 60%,transparent);
  transform:skewX(-16deg) translateX(-60%);
  animation:tk-holo 6.5s ease-in-out infinite}
@keyframes tk-holo{0%{transform:skewX(-16deg) translateX(-60%)}
                   55%,100%{transform:skewX(-16deg) translateX(330%)}}
@media (prefers-reduced-motion:reduce){.live80-v2 .tk-tube,.live80-v2 .tk-holo,.live80-v2 .tk-spots i{animation:none}}
/* ===========================================================================
   21. MOBILER HERO
   ---------------------------------------------------------------------------
   🔴 Kundenmeldung 2026-08-05: "gerade der hero stimmt mobil noch nicht".
   Gemessen bei 375x812 war die Ursache nicht der Text, sondern die Kulisse:
   .hamburg-skyline ist 150 % breit – am Desktop sind das 1900px, am Handy aber
   nur 563px, bei 3:2 also 375px hoch. Sie sass damit als schmaler Streifen
   ganz unten, zum groessten Teil unterhalb der Sichtkante. Vom Stadion war
   praktisch nichts zu sehen, der Hero wirkte leer.

   Am Handy muss die Kulisse deshalb DEUTLICH ueber die Bildschirmbreite
   hinausgehen: 300 % ergeben 1125px Breite und 750px Hoehe – der Ausschnitt
   zeigt die Stadionmitte gross statt das ganze Motiv winzig. Dass links und
   rechts etwas wegfaellt, ist hier richtig: es ist Kulisse, kein Inhalt.
   =========================================================================== */
@media (max-width:700px){/* Etwas flacher und oben knapper – 96svh plus 64px Polster liessen den
     Inhalt in der Mitte schwimmen, mit grosser Leere unter dem Header. */
.live80-v2 .hamburg-hero{min-height:min(88svh,720px);padding-block:var(--s5) var(--s8)}
.live80-v2 .hamburg-hero .hero-inner{gap:var(--s4)}
.live80-v2 .hamburg-skyline{width:300%;opacity:.42;
    /* Weniger weit ausgeblendet als am Desktop: bei dieser Groesse liegt der
       obere Rand ohnehin ausserhalb des Hero. */
    -webkit-mask-image:linear-gradient(to top,#000 0 52%,rgba(0,0,0,.6) 76%,transparent 96%);
            mask-image:linear-gradient(to top,#000 0 52%,rgba(0,0,0,.6) 76%,transparent 96%)}
/* Das Logo ist die Marke – 150px waren auf dem Handy zu zaghaft. */
.live80-v2 .hamburg-logo{width:min(58%,210px)}
/* 🔴 Der Chat-Knopf sitzt fest unten rechts und lag auf dem zweiten Button
     ("Line-up ansehen"). Die Knoepfe stehen deshalb nicht mehr ueber die volle
     Breite, sondern zentriert mit Abstand zum rechten Rand. */
.live80-v2 .hamburg-hero .hero-actions{width:100%;flex-direction:column;align-items:center;gap:var(--s3)}
.live80-v2 .hamburg-hero .hero-actions .btn{width:min(100%,300px)}
/* Luft nach unten, damit der Chat-Knopf nicht auf dem letzten Button liegt. */
.live80-v2 .hamburg-hero .hero-inner{padding-bottom:var(--s8)}}
/* Unter 780px steht der Abriss UNTER dem Hauptteil – nebeneinander bliebe fuer
   die Ueberschrift keine Breite. Perforation und Aussparungen drehen mit. */
@media (max-width:780px){.live80-v2 .ticket{grid-template-columns:1fr;--perf:150px;
    -webkit-mask-image:
      radial-gradient(20px 20px at 0 calc(100% - var(--perf)),transparent 19px,#000 20px),
      radial-gradient(20px 20px at 100% calc(100% - var(--perf)),transparent 19px,#000 20px);
            mask-image:
      radial-gradient(20px 20px at 0 calc(100% - var(--perf)),transparent 19px,#000 20px),
      radial-gradient(20px 20px at 100% calc(100% - var(--perf)),transparent 19px,#000 20px)}
.live80-v2 .tk-main{padding:var(--s8) var(--s5)}
/* ⚠️ KEINE feste Hoehe. Sie stand hier auf 150px, der Inhalt brauchte aber
     199px – mit align-content:center lief er nach OBEN aus dem Abriss heraus,
     "Admit One" stand dadurch oberhalb der Trennlinie (gemessen: 22px zu hoch).
     Die Hoehe kommt jetzt aus dem Inhalt, und die Perforation richtet sich
     danach (siehe --perf-Abgleich im Skript). */
.live80-v2 .tk-stub{border-left:0;border-top:2px dashed rgba(255,255,255,.35);
    grid-auto-flow:row;padding:var(--s5) var(--s4)}
.live80-v2 .tk-code{width:150px;height:40px}}
/* --- Lichteffekte ---------------------------------------------------------
   🔴 Alle drei arbeiten AUSSCHLIESSLICH mit transform und opacity. Kein
   animiertes blur(), keine Filter, kein background-attachment:fixed – genau
   diese drei waren die belegten Bremsklötze dieses Projekts (iPhone 15,3 s,
   siehe CLAUDE.md "Mobil-Performance" und "Desktop wurde langsam").
   Der weiche Schein kommt aus Verlaeufen und box-shadow, nicht aus Filtern. */
/* Kamerablitze im Stadion. Die <i> erzeugt das Skript mit Zufallspositionen. */
.live80-v2 .flashes{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.live80-v2 .flashes i{position:absolute;width:5px;height:5px;border-radius:50%;
  background:#fff;box-shadow:0 0 10px 3px rgba(255,255,255,.9),0 0 22px 8px rgba(255,220,255,.45);
  opacity:0;animation:flash 9s linear infinite}
/* Sehr kurzer Blitz, lange Pause – ein Dauerflackern saehe nach Defekt aus. */
@keyframes flash{
  0%,100%{opacity:0;transform:scale(.6)}
  1.2%{opacity:1;transform:scale(1)}
  3%{opacity:0;transform:scale(.7)}
  46%{opacity:0}
  47%{opacity:.85;transform:scale(.95)}
  49%{opacity:0}
}
/* Zwei Flutlichtkegel aus den oberen Ecken. */
.live80-v2 .floods{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.live80-v2 .floods .fl{position:absolute;top:-18%;width:44vw;height:135%;
  background:linear-gradient(to bottom,rgba(255,255,255,.16),rgba(255,45,149,.09) 45%,transparent 78%);
  -webkit-mask-image:linear-gradient(to bottom,#000,transparent 82%);
          mask-image:linear-gradient(to bottom,#000,transparent 82%);
  transform-origin:50% 0;mix-blend-mode:screen;opacity:.8}
.live80-v2 .floods .fl-l{left:-8vw;animation:flood-l 13s ease-in-out infinite alternate}
.live80-v2 .floods .fl-r{right:-8vw;animation:flood-r 16s ease-in-out infinite alternate}
@keyframes flood-l{from{transform:rotate(9deg)}to{transform:rotate(20deg)}}
@keyframes flood-r{from{transform:rotate(-20deg)}to{transform:rotate(-9deg)}}
/* Buehnenstrahler ueber dem Line-up – von LINKS und RECHTS, nicht von einer
   Traverse (Kundenvorgabe 28.07. auf der Startseite). */
.live80-v2 .lineup-sec{position:relative;overflow:hidden}
.live80-v2 .stagelights{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.live80-v2 .stagelights .sl{position:absolute;top:-14%;width:38vw;height:128%;
  transform-origin:50% 0;mix-blend-mode:screen;opacity:.75;
  -webkit-mask-image:linear-gradient(to bottom,#000,transparent 76%);
          mask-image:linear-gradient(to bottom,#000,transparent 76%)}
.live80-v2 .stagelights .sl-l{left:-10vw;
  background:linear-gradient(to bottom,rgba(255,45,149,.5),rgba(255,45,149,.14) 42%,transparent 74%);
  animation:sl-l 11s ease-in-out infinite alternate}
.live80-v2 .stagelights .sl-r{right:-10vw;
  background:linear-gradient(to bottom,rgba(38,224,255,.42),rgba(38,224,255,.12) 42%,transparent 74%);
  animation:sl-r 14s ease-in-out infinite alternate}
@keyframes sl-l{from{transform:rotate(12deg)}to{transform:rotate(26deg)}}
@keyframes sl-r{from{transform:rotate(-26deg)}to{transform:rotate(-12deg)}}
.live80-v2 .lineup-sec>.wrap{position:relative;z-index:2}
/* Suchscheinwerfer, der einmal quer durch den Hero faehrt und dann pausiert.
   ⚠️ Bewusst ein schraeger Verlaufsstreifen, der per translateX wandert –
   nicht per left/width, das waere ein Layout-Durchlauf je Bild. */
.live80-v2 .sweep{position:absolute;top:-20%;left:0;width:26vw;height:150%;z-index:1;
  pointer-events:none;mix-blend-mode:screen;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.15) 42%,
             rgba(255,120,220,.22) 55%,transparent);
  transform:skewX(-14deg) translateX(-40vw);
  animation:sweep 9s cubic-bezier(.5,0,.5,1) infinite}
@keyframes sweep{
  0%{transform:skewX(-14deg) translateX(-40vw)}
  38%,100%{transform:skewX(-14deg) translateX(135vw)}
}
/* Nur Bewegung abschalten – die Kegel bleiben als ruhiges Licht stehen,
   sonst wirkt der Hero ploetzlich leer. */
@media (prefers-reduced-motion:reduce){.live80-v2 .flashes i,.live80-v2 .floods .fl,.live80-v2 .stagelights .sl,.live80-v2 .sweep{animation:none}
.live80-v2 .flashes i{opacity:.5}
.live80-v2 .sweep{opacity:0}}
/* Auf dem Handy weniger gleichzeitige Ebenen – der Hero ist dort schmal, die
   Kegel ueberlagern sich sonst zu einem hellen Schleier ueber der Headline. */
@media (max-width:700px){.live80-v2 .floods .fl{width:70vw;opacity:.55}
.live80-v2 .stagelights .sl{width:64vw;opacity:.6}
.live80-v2 .sweep{display:none}}
/* ⚠️ Die Countdown-Uhr hat vier Einheiten mit je min-width:76px – zusammen mit
   den Abstaenden 340 px. Auf einem 320-px-Geraet stehen aber nur 272 px zur
   Verfuegung, die Uhr wurde am rechten Rand abgeschnitten (gemessen).
   Unterhalb 400 px teilen sich die vier Kaesten deshalb die vorhandene Breite.
   ⚠️ Dieselbe Stelle betrifft auch die Startseite – dort steht die Uhr im
   gemeinsamen Designsystem und ist NICHT mitgeaendert (waere ein Eingriff in
   eine abgenommene Seite). Als offener Punkt in der CLAUDE.md vermerkt. */
@media (max-width:400px){.live80-v2 .clock{gap:var(--s2);width:100%}
.live80-v2 .clock-unit{min-width:0;flex:1;padding:var(--s3) 4px}
.live80-v2 .clock-lbl{letter-spacing:.12em}}
/* ===========================================================================
   22. TIPPZIELE
   ---------------------------------------------------------------------------
   🔴 Bedingung ist das EINGABEGERAET, nicht die Breite: ein Tablet mit 900px
   wird genauso mit dem Finger bedient wie ein Handy. Mit `max-width:700px`
   allein blieben dort 26 Ziele unter 44px (gemessen bei 768 und 1024).
   =========================================================================== */
@media (hover:none),(max-width:1000px){/* Tippziele. Gemessen bei 375px: die Namen im Band "LIVE MIT" waren 26px
     hoch, die Karussellpunkte 26x10, die Fusszeilen-Links 18px – alle unter
     den 44px, die eine Fingerkuppe braucht. Vergroessert wird die FLAECHE,
     nicht die Optik: Schriftgroesse und Punktgroesse bleiben unveraendert.
     ⚠️ Dieselben drei Stellen betreffen auch die Startseite; sie stehen dort
     im gemeinsamen Designsystem und sind hier NICHT mitgeaendert (das waere
     ein Eingriff in eine abgenommene Seite). Steht als offener Punkt. */
.live80-v2 .names button{padding:9px .2em;min-height:44px}
/* 🔴 2026-08-07 UMGEZOGEN: Die Karussellpunkte standen hier — und damit NUR
     hier. Sie erbten dadurch nur nach unten (Hamburg, Cruise, Oberhausen leiten
     aus dieser Datei ab), waehrend die Startseite bei 10x10 blieb. Genau die
     Mechanik von Checkliste 274. Die Regel steht jetzt im gemeinsamen
     Designsystem (`startseite-redesign-v3.html`, direkt hinter `.car-dots`)
     und gilt fuer alle fuenf Seiten. Hier bewusst NICHT wiederholt: eine
     zweite Fassung wuerde die erste ueberschreiben und den Fehler neu anlegen.
     ⚠️ Dabei kam ein `border:0` dazu, das hier gefehlt hat — ohne den Reset trug
     die 22x44 grosse Flaeche den 1px-Rahmen der Grundregel weiter, und die
     Punktreihe sah aus wie eine Kette leerer Kaestchen. */
.live80-v2 .foot-legal a{display:inline-block;padding:12px 4px}}
/* --- Moderation --------------------------------------------------------------
   🔴 2026-08-07 aus `cruise-extra.css` HIERHER geholt. Sie lag nur im
   Cruise-Kapitel und erbte damit nur nach unten — als Koeln laut Plakat des
   Kunden ebenfalls eine Moderation bekam (Peter Illmann), waere sie dort
   ungestylt erschienen. Genau die Mechanik von Checkliste 274.
   Hier im gemeinsamen Eventkapitel gilt sie fuer Koeln, Hamburg, Cruise und
   Oberhausen.
   🔴🔴 KEIN `.live80-v2` VOR DIESE SELEKTOREN SCHREIBEN. Diese Datei ist die
   UNGESCOPTE Quelle — `scope-css-*.py` haengt den Scope selbst davor. Genau
   dieser Praefix stand hier vom 2026-08-07 bis zum selben Tag und erzeugte
   `.live80-v2 .live80-v2 .moderation`: ein Selektor, der NIE greift, weil die
   Klasse nur einmal am <body> haengt. Peter Illmanns Portraet lief dadurch auf
   Koeln, Cruise und Oberhausen von 74x74 auf 920x500 px auf — im Frontend UND
   im Mockup. → Checkliste 305

   ✅ 2026-08-07 bereinigt: Cruise und Oberhausen trugen sie in ihrem eigenen
   Kapitel ein zweites Mal mit zeichengleichen Werten. Beide Dubletten sind
   entfernt — DIES HIER IST JETZT DIE EINZIGE STELLE. Wer die Moderation
   aendert, aendert sie hier, und alle vier Eventseiten ziehen mit. */
.live80-v2 .moderation{
  display: flex; align-items: center; gap: var(--s5);
  justify-content: center;
  margin: var(--s7) auto 0;
  width: fit-content;
  max-width: 100%;
  padding: var(--s4) var(--s6) var(--s4) var(--s4);
  border-radius: var(--r-pill);
  background: rgba(var(--c-shadow-deep), .72);
  border: 1px solid rgba(255, 217, 61, .34);
  box-shadow: 0 16px 40px rgba(var(--c-shadow), .45);
}
.live80-v2 .mod-portrait{
  flex: none;
  width: 74px; height: 74px;
  border-radius: 50%;
  overflow: hidden;
  border: 3px solid rgba(255, 217, 61, .85);
  background: #0a0420;
  box-shadow: var(--glow-gold);
}
.live80-v2 .mod-portrait img{
  width: 100%; height: auto; display: block;
  transform: scale(1.62) translateY(13%);
}
.live80-v2 .mod-text{ display: grid; gap: 2px; text-align: left; }
.live80-v2 .mod-label{
  font-family: 'Core Sans M', 'Asap', sans-serif;
  font-size: var(--fs-xs); letter-spacing: .3em; text-transform: uppercase;
  color: var(--c-gold); text-shadow: var(--glow-gold);
}
.live80-v2 .mod-name{
  font-family: 'Core Sans M', 'Asap', sans-serif;
  font-size: var(--fs-lg); font-weight: 800; letter-spacing: .03em;
  color: #fff; line-height: 1.1;
}
@media (max-width:700px){.live80-v2 .moderation{
    flex-direction: column; text-align: center;
    border-radius: var(--r-lg);
    padding: var(--s5) var(--s5) var(--s6);
  }
.live80-v2 .mod-text{ text-align: center; justify-items: center; }}

/* ---- WordPress-Bruecke HAMBURG (nicht aus dem Mockup, siehe scope-css-hamburg.py) ---- */

/* (a) `core/image` schiebt eine <figure> zwischen Container und <img>.
   Bei diesen dreien zielen die Mockup-Regeln auf das <img> INNERHALB eines
   absolut positionierten Containers — die Figur dazwischen wuerde die
   Groessenkette unterbrechen. `display:contents` loest sie auf. */
.live80-v2 .hamburg-skyline figure.wp-block-image,
.live80-v2 .venue-illu figure.wp-block-image{display:contents}

.live80-v2 .hamburg-logo img{width:100%;height:auto;display:block}

/* (b) Die Knoepfe. `.wp-block-button.btn` ist in der Basis geregelt; hier nur
   die Container, die es im Mockup nicht gab. */
.live80-v2 .hero-actions.wp-block-buttons{
  display:flex;gap:var(--s4);flex-wrap:wrap;justify-content:center}
.live80-v2 .wp-block-buttons.tk-cta,
.live80-v2 .wp-block-buttons.outro-cta{display:contents}

/* (c) Inline-`style=""` aus dem Mockup, jetzt als Klasse.
   ⚠️ SPEZIFITAET: als blosse Klasse verlieren diese Groessen gegen
   `.sec-head .display` (0,2,0) — deshalb hier mit derselben Tiefe. */
.live80-v2 .lineup-sec .sec-head .display.lineup-h,
.live80-v2 .faq-sec .sec-head .display.faq-h{font-size:var(--fs-2xl)}
.live80-v2 .lineup-sec .sec-head .lead.lineup-lead,
.live80-v2 .faq-sec .sec-head .lead.faq-lead{font-size:var(--fs-md)}
.live80-v2 .names-sec .eyebrow{text-align:center}

/* „Volkspark<strong>STADION</strong>" — ein Inline-`style` macht den Block
   ungueltig. `<strong>` ist ein registriertes Inline-Format. */
.live80-v2 .hamburg-venue strong{font-weight:inherit;color:#fff}

/* 🔴 KEIN Abstands-Reset auf die Ueberschriften — siehe die ausfuehrliche
   Begruendung in scope-css-koeln.py (Checkliste 199). Ein Reset
   „vorsichtshalber" schlaegt den gewollten negativen Abstand aus `.chrome`. */

/* Der Hero ist ein Grid mit `gap`; die Absaetze duerfen keine eigenen Abstaende
   mitbringen. Im Mockup hatte `.hero-inner > *` das ueber den Reset. */
.live80-v2 .hamburg-hero .hero-inner > p{margin:0}

/* ⚠️ Die Ueberschrift der Stadion-Sektion: die Rampe aus dem Koeln-Kapitel ist
   an „RHEINENERGIESTADION" ausgemessen (19 Zeichen, ein Wort). „VOLKSPARK-
   STADION" ist kuerzer (16) und passt damit erst recht — nachgemessen bei
   375 px, kein Ueberlauf. Keine eigene Regel noetig. */

/* ---------- Teil 3: nur Hamburg (Anreise, Partybus) ---------- */
/* ==========================================================================
   HAMBURG — Kapitel-CSS des neuen Looks
   --------------------------------------------------------------------------
   ERGAENZT `live80-v2.css` (Designsystem) und wird NUR auf Seiten mit
   `_live80_v2_seite = hamburg` geladen. Alles hier ist unter `.live80-v2`
   gescopt; die Tokens (--c-*, --fs-*, --s*, --r-*) kommen aus der Basis.

   WAS HIER NEU IST — und warum es das in Koeln nicht gibt
   Die Live-Seite Hamburg traegt drei Bereiche, fuer die das Redesign bisher
   keine Form hatte: Anreise mit OEPNV, Anreise mit dem Auto und den Partybus.
   Das sind zusammen 7 Abschnitte mit Shuttle-Linien, Uhrzeiten und
   Parkplatz-Oeffnungszeiten — also genau die Angaben, nach denen Besucher
   zuerst suchen. Koeln sagt dazu bewusst nichts, weil die dortige Live-Seite
   nichts hergab.

   🔴 BEWUSST KEIN AUTOMATISCHES PARSEN VON LINIENBEZEICHNUNGEN.
   Ein erster Entwurf wollte "S1", "S3" und "Linie 386" per Regex zu
   Neon-Badges machen. Das sieht besser aus, ist aber eine Falle: sobald der
   Kunde im Editor "S1 bis Othmarschen" umformuliert, verschwindet das Badge
   lautlos — und niemand weiss, warum. Die Listenpunkte bleiben deshalb
   schlichter Text in `core/list-item`; die Wirkung macht die Typografie.
   ========================================================================== */

/* --- Anreise-Sektion ------------------------------------------------------ */
.live80-v2 .anreise-sec { position: relative; }

.live80-v2 .anreise-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: var(--s6);
  margin-top: var(--s8);
  align-items: start;
}

/* Die Karte greift den Panel-Stil von `.venue-copy` auf: dunkle Flaeche,
   Zierlinie oben als Pink-Cyan-Verlauf. Damit steht die Anreise sichtbar in
   derselben Familie wie der Textblock der Stadion-Sektion. */
.live80-v2 .anreise-card {
  position: relative;
  padding: var(--s7) clamp(20px, 3vw, 34px) var(--s7);
  background: var(--c-card);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  box-shadow: 0 18px 44px rgba(var(--c-shadow), .45);
}
.live80-v2 .anreise-card::before {
  content: "";
  position: absolute; left: clamp(20px, 3vw, 34px); right: clamp(20px, 3vw, 34px); top: -1px;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--c-pink), var(--c-cyan), transparent);
}

/* Icon im Neonring — dieselbe Sprache wie die Act-Badges: runder Rahmen,
   Farbe traegt das Leuchten, nicht die Flaeche. */
.live80-v2 .anreise-ico {
  width: 62px; height: 62px;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid currentColor;
  margin-bottom: var(--s5);
}
.live80-v2 .anreise-ico svg { width: 30px; height: 30px; display: block; }
/* ⚠️ Der Icon-MCP liefert `fill="currentColor"` AUF den Pfaden, obwohl die
   Gruppe `fill="none"` traegt — bei Outline-Icons werden die Formen dadurch
   ausgefuellt und wirken wie Kleckse. Hier zur Sicherheit noch einmal hart
   zurueckgesetzt, falls das Markup einmal ungefiltert eingespielt wird. */
.live80-v2 .anreise-ico svg path,
.live80-v2 .anreise-ico svg rect,
.live80-v2 .anreise-ico svg circle { fill: none !important; }

/* Zwei Karten, zwei Farben — wie auf der Live-Seite, damit der Wiedererkennungs-
   wert erhalten bleibt: OEPNV cyan, Auto pink. */
.live80-v2 .anreise-card.is-opnv .anreise-ico { color: var(--c-cyan); box-shadow: var(--glow-cyan); }
.live80-v2 .anreise-card.is-auto .anreise-ico { color: var(--c-pink); box-shadow: var(--glow-pink); }
.live80-v2 .anreise-card.is-opnv .anreise-sub { color: var(--c-cyan); }
.live80-v2 .anreise-card.is-auto .anreise-sub { color: var(--c-pink-soft); }
.live80-v2 .anreise-card.is-opnv .anreise-list li::marker { color: var(--c-cyan); }
.live80-v2 .anreise-card.is-auto .anreise-list li::marker { color: var(--c-pink); }

.live80-v2 .anreise-h {
  margin: 0 0 var(--s4);
  font-family: 'Core Sans M', 'Asap', sans-serif;
  font-size: var(--fs-lg); font-weight: 800;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--c-ink);
}
.live80-v2 .anreise-card > p {
  margin: 0 0 var(--s5);
  font-size: var(--fs-sm); line-height: 1.7;
  color: var(--c-ink-2); text-wrap: pretty;
}

/* Ein Abschnitt = Zwischenueberschrift + Liste oder Absatz. */
.live80-v2 .anreise-block + .anreise-block { margin-top: var(--s6); }
.live80-v2 .anreise-sub {
  margin: 0 0 var(--s3);
  font-family: 'Core Sans M', 'Asap', sans-serif;
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
/* 🔴 Kein Dekostrich vor der Zwischenueberschrift — Hub-Regel, gilt fuer alle
   Eyebrows und Kicker. Die Wirkung kommt aus Versalien und Laufweite. */

.live80-v2 .anreise-list {
  margin: 0; padding-left: 1.15em;
  list-style: disc;
}
.live80-v2 .anreise-list li {
  margin: 0 0 var(--s2);
  font-size: var(--fs-sm); line-height: 1.65;
  color: var(--c-ink-2);
}
.live80-v2 .anreise-list li:last-child { margin-bottom: 0; }
.live80-v2 .anreise-block > p {
  margin: 0; font-size: var(--fs-sm); line-height: 1.7; color: var(--c-ink-2);
  text-wrap: pretty;
}
.live80-v2 .anreise-block > p + p { margin-top: var(--s3); }
/* ⚠️ Ein Absatz NACH einer Liste braucht denselben Abstand — sonst klebt er an
   der letzten Zeile und liest sich wie ein weiterer Listenpunkt. Auf der
   Auto-Karte betraf das „Zusaetzlich wurden rund 200 Parkplaetze …"; im
   Screenshot lief es mit der Zeile darueber zusammen. */
.live80-v2 .anreise-list + p { margin-top: var(--s4); }

/* --- Partybus -------------------------------------------------------------
   🔴 „die sektion mit dem partybus ist ja zum einschlafen … bitte mehr action
   und nicht nur so ein winziges bus icon" (User, 2026-08-06). Zutreffend: ein
   62-px-Icon, sieben Zeilen zentrierter Fliesstext, vier graue Kaesten, und der
   Knopf hing links, waehrend alles andere zentriert stand.

   Jetzt bekommt der Partybus eine eigene Buehne: Neon-Highway mit laufender
   Mittellinie, Tempostreifen und ein grosser Bus, der darauf faehrt.

   🔴 ALLES nur ueber `transform` und `opacity`. Kein animiertes `blur()`, keine
   Filter, kein `background-attachment:fixed` — das sind die drei belegten
   Bremskloetze dieses Projekts (iPhone 15,3 s → 1,0 s, siehe CLAUDE.md
   „Mobil-Performance"). Der weiche Schein kommt aus Verlaeufen und
   `box-shadow`, nicht aus Filtern.

   Volle Breite unter den beiden Karten: es ist ein Angebot eines Partners,
   keine dritte Anreiseart — die optische Trennung macht das lesbar.
   -------------------------------------------------------------------------- */
.live80-v2 .partybus-card {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  margin-top: var(--s8);
  padding: 0 clamp(20px, 4vw, 56px) var(--s8);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255, 217, 61, .16), transparent 58%),
    linear-gradient(160deg, rgba(75, 26, 124, .92), rgba(42, 11, 73, .95));
  border: 1px solid rgba(255, 217, 61, .34);
  border-radius: var(--r-lg);
  box-shadow: 0 22px 54px rgba(var(--c-shadow), .5), 0 0 48px rgba(255, 217, 61, .14);
  text-align: center;
}
/* Zierlinie oben in Gold statt Pink-Cyan — der Partybus ist ein Fremdangebot
   und darf sich von den beiden Anreise-Karten absetzen. */
.live80-v2 .partybus-card::before {
  content: "";
  position: absolute; left: 0; right: 0; top: -1px; height: 2px; z-index: 3;
  background: linear-gradient(90deg, transparent, var(--c-gold), var(--c-pink), transparent);
  box-shadow: 0 0 16px rgba(255, 217, 61, .5);
}

/* ---- Die Buehne: Highway + Bus ------------------------------------------ */
.live80-v2 .pb-stage {
  position: relative;
  height: clamp(150px, 17vw, 230px);
  margin-inline: calc(clamp(20px, 4vw, 56px) * -1);
  margin-bottom: var(--s5);
  overflow: hidden;
}

/* Die Fahrbahn liegt schraeg im Raum — dieselbe Fluchtpunkt-Sprache wie der
   Gitterboden im Hero, nur als schmales Band. */
.live80-v2 .pb-road {
  position: absolute; inset: auto 0 0; height: 46%;
  background:
    linear-gradient(180deg, rgba(255, 217, 61, .00), rgba(255, 217, 61, .10)),
    repeating-linear-gradient(90deg,
      rgba(38, 224, 255, .22) 0 1px, transparent 1px 64px),
    linear-gradient(180deg, rgba(24, 5, 54, .0), rgba(24, 5, 54, .75));
  border-top: 2px solid rgba(255, 217, 61, .55);
  box-shadow: 0 -8px 34px rgba(255, 217, 61, .22);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}
/* Die Mittellinie laeuft — das ist die eigentliche Bewegung. `translateX` auf
   einem sich wiederholenden Verlauf, keine Positionsanimation. */
.live80-v2 .pb-dashes {
  position: absolute; left: -20%; right: -20%; bottom: 9%;
  height: 6px; border-radius: 3px;
  background: repeating-linear-gradient(90deg,
    rgba(255, 255, 255, .9) 0 46px, transparent 46px 106px);
  box-shadow: 0 0 14px rgba(255, 255, 255, .5);
  opacity: .75;
  animation: pb-dash 1.1s linear infinite;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 18%, #000 82%, transparent);
}
@keyframes pb-dash { to { transform: translateX(-106px); } }

/* Tempostreifen hinter dem Bus. Bewusst nur drei und mit langer Pause — ein
   Dauerflackern saehe nach Defekt aus (gleiche Ueberlegung wie bei den
   Kamerablitzen im Hero). */
.live80-v2 .pb-streaks { position: absolute; inset: 0; }
.live80-v2 .pb-streaks i {
  position: absolute; left: 50%; height: 3px; border-radius: 3px;
  background: linear-gradient(90deg, transparent, var(--c-cyan), transparent);
  opacity: 0;
  animation: pb-streak 2.6s cubic-bezier(.4, 0, .3, 1) infinite;
}
.live80-v2 .pb-streaks i:nth-child(1) { top: 34%; width: 190px; animation-delay: 0s; }
.live80-v2 .pb-streaks i:nth-child(2) { top: 46%; width: 130px; animation-delay: .45s; }
.live80-v2 .pb-streaks i:nth-child(3) { top: 58%; width: 220px; animation-delay: .9s; }
@keyframes pb-streak {
  0%   { opacity: 0;  transform: translateX(60px)  scaleX(.3); }
  12%  { opacity: .85; }
  55%  { opacity: 0;  transform: translateX(-420px) scaleX(1); }
  100% { opacity: 0;  transform: translateX(-420px) scaleX(1); }
}

/* 🔴 Der Bus ist jetzt das Motiv der Sektion, nicht mehr eine Randnotiz:
   62 px im Ring -> bis zu 168 px frei auf der Fahrbahn. Das Icon kommt
   weiterhin aus dem better-icons-MCP (Collection `lucide`, Projektvorgabe) —
   es wird nur gross gesetzt und leuchtet, nicht nachgezeichnet. */
.live80-v2 .pb-bus {
  position: absolute; left: 50%; bottom: 15%;
  width: clamp(96px, 11vw, 168px); height: clamp(96px, 11vw, 168px);
  translate: -50% 0;
  display: grid; place-items: center;
  color: var(--c-gold);
  animation: pb-bob 2.4s ease-in-out infinite alternate;
}
.live80-v2 .pb-bus svg {
  width: 100%; height: 100%; display: block;
  stroke-width: 1.6;
  filter: drop-shadow(0 0 10px rgba(255, 217, 61, .85))
          drop-shadow(0 0 30px rgba(255, 138, 26, .5));
}
/* Wie bei `.anreise-ico`: der MCP legt `fill="currentColor"` auf die Pfade,
   obwohl die Gruppe `fill="none"` traegt — bei einem Outline-Icon wird der Bus
   dadurch zum Klecks. */
.live80-v2 .pb-bus svg path,
.live80-v2 .pb-bus svg rect,
.live80-v2 .pb-bus svg circle { fill: none !important; }
/* ⚠️ `translate` und `transform` addieren sich (→ Checkliste 52): die
   Zentrierung laeuft ueber `translate`, die Keyframe fasst nur `transform` an.
   Zusammen in einer Eigenschaft waere der Bus um 100 % verschoben. */
@keyframes pb-bob { from { transform: translateY(0); } to { transform: translateY(-9px); } }

/* Lichtschein unter dem Bus — ein Verlauf, kein Filter. */
.live80-v2 .pb-bus::after {
  content: "";
  position: absolute; left: 50%; bottom: -14%; translate: -50% 0;
  width: 130%; height: 34%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(255, 217, 61, .5), transparent 70%);
  z-index: -1;
}

/* ---- Text ---------------------------------------------------------------- */
.live80-v2 .pb-eyebrow { color: var(--c-gold); text-shadow: var(--glow-gold); }
.live80-v2 .partybus-h {
  margin: var(--s3) 0 var(--s4);
  font-size: var(--fs-2xl);
  line-height: 1.04;
  text-wrap: balance;
}
/* Der Anreisser traegt die Frage und das Angebot und laeuft groesser; der Rest
   folgt kleiner. Wortlaut unveraendert — geaendert ist nur die Auszeichnung. */
.live80-v2 .pb-lead {
  max-width: 780px; margin: 0 auto var(--s4);
  font-size: var(--fs-lg); line-height: 1.5; color: var(--c-ink);
  text-wrap: balance;
}
.live80-v2 .partybus-text {
  max-width: 760px; margin: 0 auto var(--s7);
  font-size: var(--fs-md); line-height: 1.75; color: var(--c-ink-2);
  text-wrap: pretty;
}

/* ---- Die vier Vorteile --------------------------------------------------- */
.live80-v2 .pb-vorteile {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--s5);
  margin-bottom: var(--s7);
  text-align: left;
  counter-reset: pbv;
}
.live80-v2 .pb-vorteil {
  position: relative;
  overflow: hidden;
  counter-increment: pbv;
  padding: var(--s6) var(--s5) var(--s5);
  background: linear-gradient(180deg, rgba(255, 217, 61, .07), rgba(24, 5, 54, .5));
  border: 1px solid rgba(255, 217, 61, .28);
  border-radius: var(--r-md);
  transition: transform .28s ease, box-shadow .28s ease, border-color .28s ease;
}
/* Geisterziffer im Hintergrund. Reine Deko ueber `counter` — kein zusaetzlicher
   Block, nichts, was der Kunde pflegen muesste, und beim Duplizieren einer
   Kachel im Editor zaehlt sie von selbst weiter. */
.live80-v2 .pb-vorteil::after {
  content: counter(pbv, decimal-leading-zero);
  position: absolute; right: 10px; bottom: 4px;
  font-family: 'Core Sans M', 'Asap', sans-serif;
  font-size: 72px; font-weight: 800; line-height: .78;
  color: rgba(255, 217, 61, .11);
  pointer-events: none;
  /* ⚠️ VOLLSTAENDIG sichtbar, nicht angeschnitten. Ein erster Entwurf liess sie
     ueber die Kante laufen (`bottom:-22px`) — zusammen mit dem `overflow:hidden`
     der Kachel wurden die Ziffern waagerecht mittendurch geschnitten und lasen
     sich wie ein Darstellungsfehler, nicht wie Absicht. */
}
/* 🔴 Die Icons liegen als data-URI im CSS, NICHT als Block im Seiteninhalt.
   Vier weitere `core/html`-Bausteine mitten in den Kacheln waeren genau die
   Code-Kaesten, die dieses Projekt aus den Act-Karten herausgehalten hat
   (→ Checkliste 186). Sie sind Deko und haengen an der POSITION der Kachel;
   wer die Reihenfolge im Editor aendert, aendert damit auch die Symbole.
   Quelle: better-icons-MCP, Collection `lucide` (Projektvorgabe) — map-pin,
   armchair, repeat, party-popper. ⚠️ Das `fill="currentColor"` der Pfade ist
   beim Uebernehmen entfernt worden, sonst sind es ausgefuellte Kleckse. */
.live80-v2 .pb-vorteil::before {
  content: "";
  display: block; width: 34px; height: 34px; margin-bottom: var(--s4);
  background-repeat: no-repeat; background-size: contain;
  filter: drop-shadow(0 0 8px rgba(255, 217, 61, .55));
}
.live80-v2 .pb-vorteil:nth-child(1)::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffd93d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}
.live80-v2 .pb-vorteil:nth-child(2)::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffd93d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 9V6a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v3'/%3E%3Cpath d='M3 16a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-5a2 2 0 0 0-4 0v1.5a.5.5 0 0 1-.5.5h-9a.5.5 0 0 1-.5-.5V11a2 2 0 0 0-4 0zm2 2v2m14-2v2'/%3E%3C/svg%3E");
}
.live80-v2 .pb-vorteil:nth-child(3)::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffd93d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m17 2 4 4-4 4'/%3E%3Cpath d='M3 11v-1a4 4 0 0 1 4-4h14M7 22l-4-4 4-4'/%3E%3Cpath d='M21 13v1a4 4 0 0 1-4 4H3'/%3E%3C/svg%3E");
}
.live80-v2 .pb-vorteil:nth-child(4)::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffd93d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5.8 11.3 2 22l10.7-3.79'/%3E%3Cpath d='M4 3h.01M22 8h.01M15 2h.01M22 20h.01'/%3E%3Cpath d='M22 2l-2.24.75a2.9 2.9 0 0 0-1.96 3.12c.1.86-.57 1.63-1.45 1.63h-.38c-.86 0-1.6.6-1.76 1.44L14 10'/%3E%3Cpath d='M22 13l-.82-.33c-.86-.34-1.82.2-1.98 1.11c-.11.7-.72 1.22-1.43 1.22H17'/%3E%3Cpath d='M11 2l.33.82c.34.86-.2 1.82-1.11 1.98c-.7.1-1.22.72-1.22 1.43V7'/%3E%3Cpath d='M11 13c1.93 1.93 2.83 4.17 2 5s-3.07-.07-5-2s-2.83-4.17-2-5s3.07.07 5 2'/%3E%3C/svg%3E");
}
/* ⚠️ `hover:hover` — auf Touch bleibt der Zustand sonst nach dem Antippen
   haengen und die Kachel sieht dauerhaft „aktiv" aus. */
@media (hover: hover) {
  .live80-v2 .pb-vorteil:hover {
    transform: translateY(-4px);
    border-color: rgba(255, 217, 61, .6);
    box-shadow: 0 14px 34px rgba(var(--c-shadow), .5), 0 0 26px rgba(255, 217, 61, .3);
  }
}
.live80-v2 .pb-vt {
  margin: 0 0 var(--s2);
  font-family: 'Core Sans M', 'Asap', sans-serif;
  font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--c-gold);
  text-shadow: 0 0 12px rgba(255, 217, 61, .45);
}
.live80-v2 .pb-vorteil p {
  margin: 0; font-size: var(--fs-sm); line-height: 1.6; color: var(--c-ink-2);
  position: relative; z-index: 1;
}

/* ---- Knopf --------------------------------------------------------------- */
/* 🔴 HIER SASS „der button haengt links": `core/buttons` ist ein Flex-Container,
   und ohne eigene Regel steht sein Inhalt am Anfang der Achse — waehrend alles
   andere in der Karte zentriert ist. `text-align:center` des Elternteils
   erreicht ein Flex-Kind nicht. Gemessen: 57 px Abstand links gegen 957 px
   rechts. Dieselbe Regel wie bei `.hero-actions`, nur fuer diesen Container. */
.live80-v2 .pb-cta.wp-block-buttons {
  display: flex; justify-content: center; flex-wrap: wrap; gap: var(--s4);
}
.live80-v2 .wp-block-button.pb-btn { min-height: 60px; font-size: var(--fs-sm); }
.live80-v2 .wp-block-button.pb-btn > .wp-block-button__link { padding-inline: var(--s8); }

/* Beruhigung: Bewegung aus, Buehne bleibt stehen — dieselbe Linie wie bei den
   Lichteffekten des Hero (dort „nur Bewegung abschalten, die Kegel bleiben"). */
@media (prefers-reduced-motion: reduce) {
  .live80-v2 .pb-dashes { animation: none; }
  .live80-v2 .pb-streaks i { animation: none; opacity: .35; transform: none; }
  .live80-v2 .pb-bus { animation: none; }
  .live80-v2 .pb-vorteil { transition: none; }
}

/* --- Mobil ---------------------------------------------------------------- */
/* Die Rampen der Basis erledigen die Abstaende. Hier nur, was die Anordnung
   betrifft — und die Innenpolster, damit der Text am Rand nicht klebt. */
@media (max-width: 700px) {
  .live80-v2 .anreise-grid { grid-template-columns: 1fr; }
  .live80-v2 .anreise-card { padding-inline: var(--s5); }
  .live80-v2 .partybus-card { padding-inline: var(--s5); }
  .live80-v2 .pb-stage { margin-inline: calc(var(--s5) * -1); height: 132px; }
  /* Weniger gleichzeitige Ebenen auf schmalem Schirm — dieselbe Ueberlegung
     wie bei den Flutlichtkegeln des Hero (dort `@media (max-width:700px)`). */
  .live80-v2 .pb-streaks i:nth-child(3) { display: none; }
  .live80-v2 .pb-vorteile { grid-template-columns: 1fr; }
  .live80-v2 .pb-vorteil::after { font-size: 58px; }
  .live80-v2 .anreise-ico { width: 54px; height: 54px; }
  .live80-v2 .anreise-ico svg { width: 26px; height: 26px; }
}

/* --- WordPress-Bruecke ----------------------------------------------------
   Dieselben drei Fallen wie bei Koeln (→ Checkliste 165–168):
   a) Der Block-Gap trifft jedes Kind eines Flow-Layouts.
   b) `core/group` erzeugt einen zusaetzlichen Wrapper um jede Karte.
   c) `core/list` bringt eigene Abstaende mit.
   Alles in `:where()`, damit die Regeln SCHWAECHER bleiben als die
   Designregeln darueber — genau der Fehler aus Checkliste 199. */
.live80-v2 :where(.anreise-grid, .anreise-card, .partybus-card, .pb-vorteile) > * {
  margin-block-start: 0;
}
.live80-v2 :where(.anreise-list) { padding-inline-start: 1.15em; }
.live80-v2 :where(.pb-vorteile) > .wp-block-group { margin: 0; }

/* --- Ticket-Abriss: „HAMBURG" -------------------------------------------
   🔴 Die Basisregel `.tk-city` ist an „KÖLN" ausgemessen (4 Zeichen, 26px,
   .12em Laufweite). „HAMBURG" hat 7 und kam damit auf 148px Textbreite —
   bei 158px Innenbreite blieben 10px Luft. Abgeschnitten war es noch nicht,
   aber es ist der knappste Fall der ganzen Reihe: ein Zeichen mehr, eine
   andere Schriftauslieferung oder ein spaeter geaenderter Innenabstand, und
   das „G" faellt weg — genau wie bei „NORWEGEN" (Checkliste 260) und
   „OBERHAUSEN" (Checkliste 274), die beide sichtbar abgeschnitten waren.
   Werte wie bei der Cruise, damit die drei langen Namen gleich aussehen.
   ⚠️ Gegenrichtung merken: MEHR Laufweite macht es breiter. Der erste Anlauf
   bei der Cruise hat den Fehler damit verschlimmert.
   ⚠️ Nur ab ca. 1000px sichtbar — mobil stapelt der Abriss unter den
   Hauptteil, dort passt der Name ohnehin. */
.live80-v2 .ticket-sec .tk-stub .tk-city {
  font-size: clamp(17px, 1.05vw, 20px);
  letter-spacing: .06em;
}
