/*
  MAGIC MIRROR — Design Tokens & Glow-Utilities
  Siehe DESIGN_SYSTEM.md für Hintergrund & Verwendungsregeln.

  Einbindung im <head>, NACH dem Google-Fonts-Link:
  <link rel="stylesheet" href="design/tokens.css">
*/

:root {
  /* ---------- Basis / Bühne ---------- */
  --bg-void: #08070c;
  --bg-surface: #120f1c;
  --bg-surface-2: #1c1730;

  /* ---------- Gold (Luxus-Layer) ---------- */
  --gold: #e8c468;
  --gold-bright: #ffe29a;
  --gold-deep: #a9812e;

  /* ---------- Neon (Energie-Layer) ---------- */
  --neon-pink: #ff3fc0;
  --neon-violet: #9d4eff;
  --neon-cyan: #2fe6ff;
  --neon-yellow: #f5ff6b;
  --neon-green: #39ff14;
  --neon-blue: #3d8bff;
  /* 2026-08-02, Nutzerwunsch: Card-Icons im Hero (site.css .hero-float-icon) bekommen je ein
     eigenes, zum Motiv passendes SVG-Icon in einer eigenen Akzentfarbe statt eines einzelnen
     Emoji-Unicode-Zeichens (siehe DESIGN_SYSTEM.md fuer die volle Herleitung). Rot war bisher
     nirgends in der Palette vertreten, "Momente" (Herz) braucht es als bewusst warmen
     Farbtupfer. */
  --neon-red: #ff4d5e;

  /* ---------- Text ---------- */
  --text-primary: #f6f1e7;
  --text-muted: #b4aac2;

  /* ---------- Typografie ---------- */
  /* 2026-07-02: Playfair Display + Tangerine ersetzt (zu verschnoerkelt), siehe
     DESIGN_SYSTEM.md Abschnitt 3 fuer die Begruendung. */
  --font-display: "Outfit", "Helvetica Neue", sans-serif;
  --font-body: "Montserrat", "Helvetica Neue", sans-serif;
  --font-accent: "Unbounded", sans-serif;
  /* 2026-07-11: nur fuer H1/H2, siehe assets/fonts/fonts.css fuer die Begruendung/Abgrenzung
     zu --font-display (Logo/Buttons/kleinere Headlines bleiben bei Outfit). Nach zwei
     verworfenen Versuchen (Old Standard TT, Gelasio) jetzt Frank Ruhl Libre. */
  --font-heading: "Frank Ruhl Libre", "Georgia", serif;

  /* 2026-07-11: formales Ueberschriften-Groessenkonzept, Nutzerfeedback "H2 H3 Groessen sind
     zu unterschiedlich". --text-h3 fuer eigenstaendige Unter-Abschnittstitel (z. B. "Direkt aus
     dem Drucker"), --text-card-title fuer die vielen kleinen Grid-/Card-Ueberschriften (Ablauf,
     Warum-Foto-Bergander, Pakete, Zusatzleistungen, Garantie), die vorher uneinheitlich
     zwischen 1rem und 1.2rem hart codiert waren. */
  /* 2026-07-11: H1 auf "Eine Fotobox wie keine andere." gekuerzt (kein zweiter Satzteil mehr),
     wieder naeher an die urspruengliche Groesse hoch (war zwischenzeitlich fuer eine laengere
     Zweizeiler-Variante verkleinert worden). Da aktuell nur der Hero ein H1 hat, wirkt sich das
     nirgendwo sonst aus. */
  --text-h1: clamp(2.4rem, 5.2vw, 4rem);
  --text-h2: clamp(1.9rem, 3.4vw, 2.8rem);
  --text-h3: clamp(1.3rem, 2.2vw, 1.6rem);
  --text-card-title: 1.05rem;

  /* ---------- Radien / Timing ---------- */
  --radius-lg: 20px;
  --radius-md: 14px;
  --ease-glow: cubic-bezier(0.4, 0, 0.2, 1);

  /* ---------- Layout ---------- */
  /* 2026-07-04: feste Hoehe statt intrinsisch, damit #hero per calc() zuverlaessig
     Header + Hero-Foto zusammen auf exakt 100vh bringen kann, siehe site.css. */
  --header-h: 4.5rem;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* =======================================================
   BASIS
   ======================================================= */

body {
  background: var(--bg-void);
  color: var(--text-primary);
  font-family: var(--font-body);
  accent-color: var(--gold);
  caret-color: var(--gold);
}

/* =======================================================
   AMBIENT LIVING BACKGROUND (2026-07-03)
   Ein einziger fixer Hintergrund ueber der ganzen Seite statt einzelner statischer
   Section-Washes, driftet langsam, Farben verschmelzen per mix-blend-mode ueber dem
   fast schwarzen Grund. Section-Hintergruende in site.css haben ihre eigene deckende
   Grundfarbe deshalb verloren, hier scheint das jetzt durch. Referenz: "Moving Gradient
   Background"-Beispiel des Nutzers.
   ======================================================= */

.ambient-bg {
  position: fixed;
  inset: 0;
  z-index: -10;
  overflow: hidden;
  background: var(--bg-void);
  pointer-events: none;
}

/* 2026-08-02: .ambient-bg .blob (drei grosse, verschwommene, animierte Farbverlauf-Kreise)
   komplett entfernt. Nutzerfeedback: liess sich in der Mobile-Version die Seite "irgendwie
   verschieben", per Puppeteer bestaetigt (echter horizontaler Overflow, documentElement.
   scrollWidth 396px bei 390px Viewport, die .blob-Spans mit ihrer riesigen Groesse (62vmax)
   und teils negativen Offsets waren die groessten Ausreisser). Nutzer fand den Effekt
   ausserdem "nicht mehr passend". .scrim und .cursor-glow (kein animierter Farbverlauf,
   nicht am Bug beteiligt) bleiben erhalten. Zugehoerige @keyframes ambient-drift und die
   reduced-motion-Ausnahme fuer .blob sind mit entfernt (totes CSS statt liegen zu lassen). */
.ambient-bg .scrim {
  position: absolute;
  inset: 0;
  background: rgba(8, 7, 12, 0.34);
}

/* 2026-08-11: .cursor-glow (mausfolgender Farbverlauf ueber der ganzen Seite) ersatzlos
   entfernt. Nutzerentscheidung: "ich habe das selbst mal gewuenscht, aber es passt nicht mehr
   zum Design." Der Effekt kam aus Welle 2 (damals als .spotlight nur in Hero/Pakete/Galerie,
   danach global hierher gezogen). Mit entfernt: das <span> in index.html und der
   pointermove-Listener in site.js, damit kein toter Code zurueckbleibt.
   .scrim bleibt: das ist eine statische Abdunklung ohne Mausbezug.
   Die zugehoerige prefers-reduced-motion-Ausnahme ist damit ebenfalls entfallen, sie hat nur
   .cursor-glow ausgeblendet und waere sonst eine Regel ohne Ziel gewesen. */

.font-display { font-family: var(--font-display); font-weight: 800; letter-spacing: -0.01em; }

/* 2026-07-11: Nutzerfeedback "aktuelle H1 und H2 gefallen mir nicht, sehen zu unsauber aus".
   Ueberschreibt --font-display gezielt nur fuer H1/H2 (hoehere Selektor-Spezifitaet durch den
   Element-Teil), Logo/Buttons/sonstige .font-display-Elemente bleiben bei Outfit. Alle H1/H2
   im Projekt tragen bereits die .font-display-Klasse, kein zusaetzliches Markup noetig.
   font-size hier (statt nur in .section-title) behebt einen Bug: zwei H2 ohne
   .section-title-Klasse ("Berühren Sie den Spiegel.", "Ihr Ansprechpartner an der
   Ostseekueste", beide bewusst linksbuendig neben einem Bild statt zentriert) fielen bisher auf
   die unformatierte Browser-Standardgroesse zurueck. Jetzt bekommen ALLE H2 dieselbe Groesse,
   .section-title fuegt nur noch Zentrierung/Abstand als Zusatz-Modifier hinzu, siehe site.css. */
h1.font-display {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: normal;
  font-size: var(--text-h1);
}

h2.font-display {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: normal;
  font-size: var(--text-h2);
}

/* 2026-08-11: Nutzerfeedback "Direkt aus dem Drucker hat noch nicht unsere DESIGN H2". Der
   Gold-Look (Kontur, Verlaufsfuellung, Sweep) kommt aus .h2-gold-word (site.css), die Spans
   dafuer setzt splitIntoGoldWords (site.js) jetzt auch fuer h3.font-display. Damit die Wirkung
   stimmt, braucht die Ueberschrift dieselbe Schriftfamilie wie H1/H2: ohne diese Regel fiele sie
   ueber .font-display auf Outfit zurueck und saehe trotz Gold anders aus als alle anderen
   Ueberschriften.
   2026-08-11, direkt danach korrigiert: die Groesse war zunaechst bei --text-h3 belassen worden
   (siehe die Token-Notiz weiter oben, die "Direkt aus dem Drucker" woertlich als H3-Beispiel
   nennt). Nutzerentscheidung dagegen: "beachte bitte einheitliche H2 Groessen, Direkt aus dem
   Drucker ist deutlich kleiner, bitte anpassen an die Groesse von BERUEHREN SIE DEN SPIEGEL."
   Gemessen war der Unterschied deutlich: 25.6px gegen 44.8px bei 1440px Fensterbreite. Diese
   Regel nutzt deshalb bewusst --text-h2, obwohl der Selektor h3 heisst: das Element bleibt aus
   Dokumentstruktur-Sicht eine H3 (es steht unter der Section-H2 "Beruehren Sie den Spiegel"),
   traegt optisch aber die volle H2-Stufe.
   Dabei aufgefallen und mit erledigt: `.print-showcase h3 { font-size: var(--text-h3) }` in
   site.css haette diese Regel geschlagen und die Aenderung wirkungslos gemacht. Beide Selektoren
   haben die identische Spezifitaet (je eine Klasse plus ein Element), bei Gleichstand entscheidet
   die Quelltext-Reihenfolge, und site.css wird nach tokens.css geladen. Die Regel dort ist
   deshalb ersatzlos entfallen. --text-h3 bleibt als Token erhalten, wird aktuell aber von keiner
   Ueberschrift mehr verwendet. */
h3.font-display {
  font-family: var(--font-heading);
  font-weight: 700;
  letter-spacing: normal;
  font-size: var(--text-h2);
}
.font-accent  { font-family: var(--font-accent); font-weight: 800; letter-spacing: 0.04em; }

/* =======================================================
   ICON-SET (2026-07-04)
   Handgezeichnete Linien-Icons statt Buchstaben/Roemischer-Zahlen/Unicode-Symbolen als
   Platzhalter, im "Neon-Line-Art-Stil" (siehe DESIGN_SYSTEM.md Footer-Abschnitt, jetzt
   sitewide ausgeweitet). Sprite mit allen <symbol>-Definitionen liegt einmal in index.html,
   Einsatz per <svg class="icon"><use href="#icon-name"/></svg>. stroke="currentColor", erbt
   also automatisch die Textfarbe/den Glow des umgebenden Elements.
   ======================================================= */

.icon {
  width: 1.5rem;
  height: 1.5rem;
  display: block;
  flex-shrink: 0;
}

/* =======================================================
   TEXT-GLOW
   ======================================================= */

.glow-gold {
  color: var(--gold-bright);
  text-shadow:
    0 0 8px rgba(232, 196, 104, 0.65),
    0 0 24px rgba(232, 196, 104, 0.45),
    0 0 60px rgba(232, 196, 104, 0.25);
}

.glow-neon {
  color: #fff;
  text-shadow:
    0 0 6px var(--neon-pink),
    0 0 18px var(--neon-pink),
    0 0 40px var(--neon-violet);
}

.glow-cyan {
  color: #fff;
  text-shadow:
    0 0 6px var(--neon-cyan),
    0 0 18px var(--neon-cyan),
    0 0 40px var(--neon-violet);
}

/* =======================================================
   MIRROR FRAME — wiederkehrendes Rahmen-/Card-Motiv
   ======================================================= */

/* 2026-07-02: Default-Zustand von Gold auf Neon umgestellt (siehe DESIGN_SYSTEM.md,
   Richtungswechsel-Hinweis). Neon ist jetzt in Ruhe schon sichtbar, Hover intensiviert nur. */
.mirror-frame {
  position: relative;
  isolation: isolate;
  background: var(--bg-surface);
  border: 1.5px solid var(--neon-pink);
  border-radius: var(--radius-lg);
  box-shadow:
    0 0 14px rgba(255, 63, 192, 0.5),
    0 0 42px rgba(47, 230, 255, 0.28),
    inset 0 0 20px rgba(157, 78, 255, 0.1);
  transition: box-shadow 0.4s var(--ease-glow), border-color 0.4s var(--ease-glow);
}

.mirror-frame:hover {
  border-color: var(--neon-cyan);
  box-shadow:
    0 0 18px rgba(47, 230, 255, 0.65),
    0 0 56px rgba(255, 63, 192, 0.4),
    inset 0 0 26px rgba(47, 230, 255, 0.15);
}

/* Rahmen mit rotierendem Farbverlauf (Gold/Pink/Cyan, dauerhaft in Bewegung).
   Technik gefunden auf coding2go.com/border-animation, auf Markenfarben umgestellt.
   Braucht @property-Unterstuetzung (alle aktuellen Browser ab 2024/2025).
   Fuer eher zurueckhaltende, edle Wirkung: 6 Sekunden pro Umlauf statt schnellerer Demo-Werte.
   Hinweis: das Pseudo-Element braucht content-box-Groessenberechnung (Browser-Standard), damit
   das padding den sichtbaren Ring erzeugt. Falls irgendwo global box-sizing: border-box auf
   *, *::before, *::after gesetzt wird, muss dieser Selektor davon ausgenommen werden. */
@property --mirror-angle {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

.mirror-frame--shift::before,
.mirror-frame--shift::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  width: 100%;
  height: 100%;
  padding: 3px;
  border-radius: inherit;
  box-sizing: content-box;
  background-image: conic-gradient(
    from var(--mirror-angle),
    var(--neon-pink),
    var(--neon-violet),
    var(--neon-cyan),
    var(--gold),
    var(--neon-pink)
  );
  z-index: -1;
  animation: mirror-frame-spin 6s linear infinite;
}

.mirror-frame--shift::after {
  /* 2026-07-03: 1.25rem Blur hat auf kleineren Karten (z.B. Pakete, Anlaesse) die ganze
     Flaeche durch das halbtransparente .glass-panel geflutet statt nur einen Ring zu zeigen.
     Deutlich enger, damit es ueberall nach Rand-Glow aussieht statt nach Farbklecks. */
  filter: blur(0.2rem);
  opacity: 0.3;
  padding: 0;
}

@keyframes mirror-frame-spin {
  from { --mirror-angle: 0deg; }
  to   { --mirror-angle: 360deg; }
}

/* =======================================================
   RING FRAME (2026-07-02)
   Leichte Alternative zu .mirror-frame fuer Elemente, die NUR den rotierenden
   Regenbogen-Rahmen (.mirror-frame--shift) brauchen, ohne den statischen Glow-Schatten
   obendrauf. Verhindert das "zu viele Rahmen"-Problem, ::before/::after brauchen ein
   echtes Element (kein <img>), deshalb als Wrapper-Div um Bilder verwenden.
   ======================================================= */

.ring-frame {
  position: relative;
  border-radius: var(--radius-lg);
  transition: transform 0.3s var(--ease-glow);
}

/* 2026-07-03: Anlaesse-Karten und Premium-Paket hatten VOR dieser Regel zwei unabhaengige
   Hover-Transforms (aeusserer ring-frame UND inneres glass-panel bewegten sich beide),
   dadurch schob sich das innere Panel sichtbar vom Ring weg. :has() sorgt dafuer, dass NUR
   Ring-Frames mit einem Glass-Panel drin (nicht z. B. das Portraitfoto bei #ueber-mich) den
   Hebe-Effekt bekommen, und das innere Panel bewegt sich dann nicht mehr zusaetzlich fuer
   sich, nur der Glow/Rand aus .glass-panel:hover bleibt. */
.ring-frame:has(.glass-panel):hover {
  transform: translateY(-6px);
}

.ring-frame:hover .glass-panel {
  transform: none;
}

/* =======================================================
   GLASS PANEL
   ======================================================= */

.glass-panel {
  position: relative;
  background: rgba(28, 23, 48, 0.45);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  border: 1px solid rgba(157, 78, 255, 0.5);
  border-radius: var(--radius-lg);
  box-shadow: 0 0 16px rgba(157, 78, 255, 0.12);
  transition:
    border-color 0.35s var(--ease-glow),
    box-shadow 0.35s var(--ease-glow),
    transform 0.35s var(--ease-glow);
}

/* 2026-07-02: Neon-Steigerung bleibt bei Interaktion (Hover), damit der Ruhezustand nicht
   wieder in den "ueberall glueht was"-Fehler zurueckfaellt. Der Rand selbst ist aber jetzt
   auch in Ruhe klar farbig sichtbar (Referenz: "Glass-Karten mit farbigem Rand"). */
.glass-panel:hover {
  border-color: var(--neon-pink);
  box-shadow:
    0 0 22px rgba(255, 63, 192, 0.4),
    0 0 50px rgba(47, 230, 255, 0.22);
  transform: translateY(-4px);
}

/* =======================================================
   HINTERGRUND-WASH (Neon-Brick-Wall-Referenz)
   ======================================================= */

.section-neon-bg {
  background:
    radial-gradient(circle at 20% 20%, rgba(255, 63, 192, 0.18), transparent 45%),
    radial-gradient(circle at 80% 30%, rgba(47, 230, 255, 0.14), transparent 40%),
    radial-gradient(circle at 50% 90%, rgba(157, 78, 255, 0.16), transparent 50%),
    var(--bg-void);
}

/* 2026-07-04: Der fruehere Cursor-Spotlight war hier auf einzelne Sections beschraenkt
   (.spotlight, Hero/Pakete/Galerie), danach global als .ambient-bg .cursor-glow.
   2026-08-11: beides existiert nicht mehr, der mausfolgende Verlauf ist auf Nutzerwunsch
   komplett entfernt, siehe Kommentar im Abschnitt AMBIENT LIVING BACKGROUND oben. */

/* =======================================================
   BUTTON — CTA mit Glow Pulse + Mirror Sweep
   ======================================================= */

.btn-glow {
  position: relative;
  overflow: hidden;
  display: inline-block;
  padding: 16px 40px;
  border-radius: 999px;
  border: 1.5px solid var(--neon-pink);
  background: linear-gradient(135deg, rgba(255, 63, 192, 0.22), rgba(47, 230, 255, 0.14));
  color: var(--text-primary);
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: 0.03em;
  cursor: pointer;
  animation: glow-pulse 2.8s ease-in-out infinite;
  transition: transform 0.3s var(--ease-glow);
}

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

.btn-glow::before {
  /* Mirror Sweep */
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 40%;
  height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: skewX(-15deg);
  transition: left 0.6s ease;
}

.btn-glow:hover::before {
  left: 130%;
}

@keyframes glow-pulse {
  0%, 100% {
    box-shadow: 0 0 10px rgba(255, 63, 192, 0.4), 0 0 22px rgba(47, 230, 255, 0.18);
  }
  50% {
    box-shadow: 0 0 28px rgba(47, 230, 255, 0.85), 0 0 64px rgba(255, 63, 192, 0.55);
  }
}

/* =======================================================
   TOUCH RIPPLE (2026-07-02)
   JS erzeugt bei Klick auf .btn-glow ein .ripple-Element an der Klickposition,
   siehe assets/js/site.js. Referenz an "Beruehre den Spiegel".
   ======================================================= */

.ripple {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 63, 192, 0.55), transparent 70%);
  transform: translate(-50%, -50%) scale(0);
  pointer-events: none;
  animation: ripple-out 0.7s ease-out forwards;
}

@keyframes ripple-out {
  to {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}

/* =======================================================
   NEON-FUNKEN-BURST (Welle 2)
   JS erzeugt bei Klick auf .btn-hero-cta mehrere .confetti-Partikel an der Klickposition,
   siehe assets/js/site.js. Bewusst nur auf dem Haupt-CTA, nicht auf jedem Button.
   ======================================================= */

/* 2026-08-02, /grill-me-Nachbesserung: Nutzerfeedback "Konfetti sieht nicht professionell aus,
   dafuer gibt es eine bestimmte Technik". Die eigene DOM/CSS-Partikelloesung, die hier vorher
   stand (Span-Elemente mit --tx/--ty/--rot-Custom-Properties, spaeter 3D-Taumel-Nachbesserung
   per `rotate`+`perspective`), wurde komplett durch die Bibliothek canvas-confetti ersetzt
   (identifiziert als die auf der Referenzseite verwendete Technik: echte Canvas-Partikelphysik
   statt CSS-Transforms). Siehe assets/js/vendor/canvas-confetti.js (lokal vendored) und
   assets/js/site.js (spawnConfettiBurst/spawnConfettiRain/spawnConfettiCannon). Die Bibliothek
   verwaltet ihr eigenes <canvas>-Element vollstaendig selbst, braucht kein eigenes CSS mehr
   hier. */

@media (prefers-reduced-motion: reduce) {
  .ripple {
    display: none;
  }
}

/* =======================================================
   BLITZKANONE: Screen-Flash + Konfetti-Regen (2026-07-04)
   Nach dem Klick auf den Haupt-CTA: mehr Konfetti aus dem Burst oben, dazu kurze
   vollflaechige Blitze (simulieren eine Kamerablitz-Salve), bevor zum Anker gescrollt
   wird. Am Ziel-Anker faellt zusaetzlich Konfetti-Regen ueber das ganze Fenster.
   Siehe assets/js/site.js fuer die Ablauf-Steuerung.
   ======================================================= */

.screen-flash {
  position: fixed;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
  /* 2026-08-02, Nachbesserung: stand bisher UNTER .pb-overlay (z-index:10000), deshalb musste
     die Photobox-Sequenz das Overlay vor jedem Blitz kurz schliessen (sonst waere der Blitz
     dahinter verdeckt gewesen). Jetzt darueber, Blitze sind direkt ueber dem offenen Overlay
     sichtbar, kein Schliessen/Wiederoeffnen mehr noetig (site.js runPhotoboothSequence). */
  z-index: 10002;
  animation: screen-flash-pop 0.28s ease-out;
}

@keyframes screen-flash-pop {
  0% { opacity: 0; }
  30% { opacity: 0.88; }
  100% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .screen-flash {
    display: none;
  }
}

/* =======================================================
   STAUBWOLKE (2026-08-02, /grill-me, mehrfach nachgebessert, zuletzt auf canvas-confetti
   umgestellt)
   Nutzerwunsch: Jetzt/Mieten sollen beim Einrasten eine kleine "Staubwolke" abgeben. Erste
   Versuche mit einer eigenen DOM/CSS-Partikelloesung (.dust-mote/.gold-puff-mote) blieben trotz
   mehrfacher, per Puppeteer verifizierter Nachbesserungen (Klassenname-Kollision behoben,
   Kontrast/Groesse deutlich erhoeht) beim Nutzer unsichtbar, obwohl programmatisch kein Bug
   mehr nachweisbar war. Letzter, sicherster Schritt: komplett auf canvas-confetti umgestellt
   (dieselbe Rendering-Technik wie die Konfetti-Kanone, die nachweislich sichtbar ist), kein
   eigenes CSS mehr noetig, siehe spawnDustPuff in assets/js/site.js.
   ======================================================= */

/* =======================================================
   KAMERA-BLITZ (2026-07-03) — am 2026-08-12 entfernt
   Der Blitz lag als weisse Overlay-Flaeche (.camera-flash) ueber dem Produktbild in #spiegel und
   wurde per Klick ausgeloest. Mit dem Produktbild (Nutzerwunsch: "bitte loesche dies") ist auch
   sein einziger Einsatzort weggefallen, deshalb sind .camera-flash, .is-flashing, die Keyframes
   camera-flash-pop und die reduced-motion-Ausnahme hier ersatzlos entfernt, statt als
   Primitive ohne Verwendung stehen zu bleiben. Wiederherstellbar ueber die Git-Historie.
   ======================================================= */

/* =======================================================
   SPARKLE FIELD — kleine schwebende Funken im Hintergrund
   Markup: <span class="sparkle" style="--x:12%; --y:30%; --delay:0.4s"></span>
   ======================================================= */

.sparkle-field {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}

.sparkle {
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--gold-bright);
  box-shadow: 0 0 8px 3px currentColor;
  color: var(--gold-bright);
  animation: sparkle-flicker 3.5s ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}

@keyframes sparkle-flicker {
  0%, 100% { opacity: 0; transform: scale(0.6); }
  50% { opacity: 1; transform: scale(1.2); }
}

/* =======================================================
   DUST FIELD (2026-07-11): feine, langsam umherschwebende Staubpartikel
   Nutzerwunsch: die goldenen Staub-/Bokeh-Partikel, die im Foto selbst zu sehen sind
   (frau-am-spiegel-breitformat.webp), auch als eigenstaendige Animation in der Section,
   ueber die gesamte Breite verteilt. Anders als .sparkle-field (flackert nur an fester
   Position) driften diese Partikel langsam und unregelmaessig, wie echter Staub im
   Streiflicht. Reduced-Motion-Guard analog zu .firefly-field/.sparkle-field in site.js.
   ======================================================= */

.dust-field {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}

/* 2026-07-11, dritte Nachbesserung: Nutzerwunsch "muessen aussehen, als waeren sie unscharf im
   Hintergrund, wie ein feines Lens-Bokeh". Echter CSS-`filter: blur()` statt nur box-shadow-
   Glow, Staerke (--blur) skaliert proportional zur Partikelgroesse in site.js, groessere
   Partikel = staerker unscharf, genau wie bei echtem Kamera-Bokeh (grosse Kreise = staerker
   ausserhalb der Schaerfeebene). box-shadow deutlich reduziert, der Blur-Filter uebernimmt
   jetzt den Grossteil der weichen Wirkung. */
.dust-mote {
  position: absolute;
  left: var(--x, 50%);
  top: var(--y, 50%);
  width: var(--size, 2px);
  height: var(--size, 2px);
  border-radius: 50%;
  background: var(--gold-bright);
  box-shadow: 0 0 2px 0.5px currentColor;
  filter: blur(var(--blur, 1px));
  color: var(--gold-bright);
  opacity: 0;
  animation: dust-drift var(--dust-duration, 22s) ease-in-out infinite;
  animation-delay: var(--delay, 0s);
}

@keyframes dust-drift {
  0%   { transform: translate(0, 0); opacity: 0; }
  10%  { opacity: var(--dust-opacity, 0.7); }
  50%  { transform: translate(var(--dx, 40px), var(--dy, -30px)); opacity: var(--dust-opacity, 0.7); }
  90%  { opacity: 0; }
  100% { transform: translate(calc(var(--dx, 40px) * 1.6), calc(var(--dy, -30px) * 1.6)); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .dust-field {
    display: none;
  }
}

/* =======================================================
   SCROLL REVEAL (mit JS-Klasse .is-visible toggeln, z.B. IntersectionObserver)
   ======================================================= */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  filter: drop-shadow(0 0 0 transparent);
  transition:
    opacity 0.8s var(--ease-glow),
    transform 0.8s var(--ease-glow),
    filter 0.8s var(--ease-glow);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
  filter: drop-shadow(0 0 18px rgba(232, 196, 104, 0.25));
}

/* =======================================================
   NEON FLICKER — einmaliger Neonröhren-Start-Effekt fürs Hero-Logo
   Klasse beim Laden auf das Element setzen, danach entfernen/belassen
   ======================================================= */

@keyframes neon-flicker-in {
  0%   { opacity: 0; }
  10%  { opacity: 1; }
  12%  { opacity: 0.3; }
  20%  { opacity: 1; }
  22%  { opacity: 0.4; }
  30%  { opacity: 1; }
  100% { opacity: 1; }
}

.neon-flicker-in {
  animation: neon-flicker-in 1.6s ease-out both;
}

/* =======================================================
   SPIEGEL-GALERIE (2026-07-11, vormals GALERIE-GRID)
   2026-07-11: Aufraeum-Runde, Nutzerwunsch. Die drei Event-Fotos sind aus #galerie in die
   rechte Spalte von #spiegel gewandert (Tausch gegen den Text "Berühren Sie den Spiegel.",
   der jetzt in #galerie sitzt, siehe .spiegel-copy). Kein Full-Bleed-Breakout mehr noetig,
   die Bilder fuellen hier einfach ihre normale Grid-Spalte in #spiegel .wrap.
   Bildstil (feste Hoehe, object-fit:cover, Hover-Zoom) unveraendert aus der alten
   .gallery-grid uebernommen.
   ======================================================= */
/* 2026-08-11: aus der gestapelten Spalte ist ein durchlaufendes Band am unteren Rand von
   #spiegel geworden (Nutzerwunsch "die bitte auch wieder in eine durchlaufende Slideshow
   wandeln, diese soll aber unten ablaufen"). Aufbau wie beim Druck-Laufband: .spiegel-marquee
   (site.css) ist das Sichtfenster, dieses Element das Band darin.
   Abstand bewusst per margin-right auf den Bildern statt per gap auf dem Flex-Container. Der
   Unterschied ist hier entscheidend: bei `gap` liegt zwischen N Bildern nur N-1 Mal Abstand, das
   letzte Bild hat rechts keinen. Der Versatz fuer eine nahtlose Schleife waere dadurch nicht
   mehr exakt ein Viertel der Bandbreite, sondern muesste um einen Bruchteil des Abstands
   korrigiert werden (beim Druck-Laufband genau deshalb `calc(-50% - 1rem)`). Mit margin-right
   traegt JEDES Bild seinen eigenen Abstand, ein Satz ist damit exakt ein Viertel des Bandes und
   translateX(-25%) ist ohne Korrekturterm nahtlos.
   max-width: none hebt die globale `img { max-width: 100% }`-Regel auf: in einem Container mit
   `width: max-content` haette sie die Bilder gegen eine Breite gedeckelt, die sie selbst erst
   bestimmen. */
.spiegel-gallery {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  width: max-content;
  animation: spiegel-marquee 44s linear infinite;
}

.spiegel-gallery img {
  display: block;
  width: auto;
  max-width: none;
  height: clamp(140px, 18vw, 220px);
  margin-right: 1.2rem;
  object-fit: cover;
  border-radius: var(--radius-md);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
  transition: transform 0.4s var(--ease-glow), filter 0.4s var(--ease-glow);
}

/* Vier Kopien im Markup, ein Satz ist also genau ein Viertel der Bandbreite. Nach dem Versatz um
   diesen einen Satz steht Kopie 2 exakt dort, wo Kopie 1 stand, der Ruecksprung auf Null ist
   dadurch unsichtbar. */
@keyframes spiegel-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-25%); }
}

@media (prefers-reduced-motion: reduce) {
  .spiegel-gallery {
    animation: none;
    width: auto;
    justify-content: center;
    flex-wrap: wrap;
  }

  /* Ohne Bewegung waeren die Kopien schlicht jedes Foto viermal. */
  .spiegel-gallery img[aria-hidden="true"] {
    display: none;
  }
}

.spiegel-gallery img:hover {
  transform: scale(1.02);
  filter: saturate(1.2) brightness(1.06);
}

/* =======================================================
   ACCORDION (Fund aus 10-pro-tips, 2026-07-02)
   Fuer die FAQ-Sektion. Animiert Hoehe rein per CSS (grid-template-rows Trick),
   .is-open Klasse per JS auf .accordion-item toggeln.
   ======================================================= */

.accordion-item {
  display: grid;
  grid-template-rows: auto 0fr;
  transition: grid-template-rows 0.35s var(--ease-glow);
}

.accordion-item.is-open {
  grid-template-rows: auto 1fr;
}

.accordion-item > * {
  min-height: 0;
}

.accordion-body {
  overflow: hidden;
}

/* =======================================================
   RIBBON BADGE aus HTML-Attribut (Fund aus 10-pro-tips, 2026-07-02)
   Markup: <div class="paket-card" data-badge="Beliebteste Wahl">...</div>
   Kein zusaetzliches Badge-Markup pro Karte noetig.
   ======================================================= */

[data-badge] {
  position: relative;
}

/* 2026-07-04: schwebt jetzt komplett ueber der Karte statt auf dem Rahmen zu sitzen,
   dazu ein sanfter Glow-Pulse statt eines starren Randes. */
[data-badge]::before {
  content: attr(data-badge);
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% -100%;
  margin-top: -0.3rem;
  padding: 0.45em 1.5em;
  border-radius: 999px;
  background: rgba(28, 23, 48, 0.55);
  backdrop-filter: blur(12px) saturate(130%);
  -webkit-backdrop-filter: blur(12px) saturate(130%);
  border: 1px solid var(--gold);
  color: var(--gold-bright);
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 0 0 rgba(232, 196, 104, 0.5), 0 6px 16px rgba(0, 0, 0, 0.4);
  animation: badge-float-glow 3s ease-in-out infinite;
  z-index: 3;
}

@keyframes badge-float-glow {
  0%, 100% {
    transform: translateY(0);
    box-shadow: 0 0 10px rgba(232, 196, 104, 0.35), 0 6px 16px rgba(0, 0, 0, 0.4);
  }
  50% {
    transform: translateY(-4px);
    box-shadow: 0 0 20px rgba(232, 196, 104, 0.65), 0 10px 20px rgba(0, 0, 0, 0.4);
  }
}

@media (prefers-reduced-motion: reduce) {
  [data-badge]::before {
    animation: none;
  }
}

/* =======================================================
   PHOTOBOX-SIMULATION (2026-07-06)
   Klick auf die "Touch-Funktion"-Karte im Hero startet eine simulierte
   Fotobox-Aufnahme: Blitz-Salve, Vollbild-Overlay mit Countdown, erneuter Blitz,
   Dankes-Screen mit Slogan, beim Schliessen Regen statt Konfetti, Abschieds-Toast.
   Komplett JS-generiert, siehe assets/js/site.js. Kein echtes Popup-Fenster (damit
   Popup-Blocker nicht greifen koennen), sondern ein fixiertes Overlay im hoechsten
   z-index der Seite.
   ======================================================= */

/* 2026-08-02, Nutzerwunsch: "Da wo der Countdown kommt, haette ich gerne ein Hintergrundbild"
   (Gold-Backdrop-Foto, per tools/convert-image.js aus dem Upload-Ordner konvertiert, siehe
   assets/img/REGISTRY.md).
   2026-08-02, Nachbesserung: (1) "Der dunkle Verlauf macht den Backdrop kaputt" - komplett
   entfernt, Text-Lesbarkeit kommt jetzt ausschliesslich ueber staerkere Text-Schatten (siehe
   .pb-heading/.pb-countdown-digit unten), das Foto bleibt dadurch in voller Farbe/Helligkeit
   sichtbar. (2) "Nach dem Countdown geht der Backdrop weg, die Website wird kurz wieder
   angezeigt, das muss nicht sein" - Root Cause war eine bewusste Zwischen-Schliessung des
   Overlays (assets/js/site.js runPhotoboothSequence: das Overlay wurde vor dem Blitz kurz
   geschlossen, damit ein WEISSER Blitz auf dem vorher WEISSEN Grund ueberhaupt sichtbar war).
   Seit das Overlay ein Foto statt eines weissen Hintergrunds zeigt, ist dieser Kniff nicht mehr
   noetig, das Overlay bleibt jetzt durchgehend offen (siehe dortiger Kommentar). (3) "Genauso
   der Dankes-Screen, dort kann auch das Backdrop zu sehen sein" - die Foto-Regel gilt jetzt
   unconditional fuer .pb-overlay selbst (vorher nur per :has() auf die Countdown-Phase
   beschraenkt), beide Phasen zeigen jetzt denselben Hintergrund. */
/* 2026-08-02, Bugfix (bei der Verifikation entdeckt): der vergroesserte Dankes-Screen (Foto-
   Carousel + ausgelagerter Slogan/Buttons, siehe .pb-phase--thanks weiter unten) passt auf
   kurzen Viewports (getestet bei 720px Hoehe) nicht mehr komplett hinein, Ueberschrift UND
   Buttons wurden oben/unten abgeschnitten, ohne jede Moeglichkeit zu scrollen. overflow-y:auto
   erlaubt Scrollen, sobald der Inhalt nicht passt. "align-items: safe center" (statt nur
   "center") verhindert dabei zusaetzlich, dass der ANFANG des Inhalts abgeschnitten bleibt: bei
   reinem "center" wird ueberlaufender Inhalt von Flexbox gleichmaessig ueber beide Kanten hinaus
   zentriert, "safe" faellt in diesem Fall automatisch auf Start-Ausrichtung zurueck, der Inhalt
   bleibt von oben an vollstaendig erreichbar. */
.pb-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: safe center;
  justify-content: center;
  overflow-y: auto;
  background: url("../assets/img/photobooth-gold-backdrop.webp") center / cover no-repeat;
  color: #fff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s var(--ease-glow);
}

.pb-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}

.pb-overlay[hidden] {
  display: none;
}

.pb-phase {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  max-width: 46rem;
  /* 2026-08-02: vertikales Padding ergaenzt, damit bei erzwungenem Scrollen (.pb-overlay
     overflow-y:auto, siehe dort) oben/unten etwas Luft bleibt statt die Kanten des Bildschirms
     zu beruehren. */
  padding: 2rem 1.5rem;
  text-align: center;
}

.pb-phase[hidden] {
  display: none;
}

/* 2026-08-02, Nutzerwunsch: "Rechts in der Endcard haette ich gerne Platz fuer ein Foto (echte
   Fotostreifen-Prints aus dem Drucker), wie ein Carousel wie bei Instagram, mit Punkten unten
   drunter." Der Dankes-Screen (.pb-phase--thanks) bekommt dafuer eine eigene Zwei-Spalten-
   Struktur (Text links, Carousel rechts), gestapelt statt nebeneinander auf schmalen Viewports.
   .pb-phase selbst (max-width:46rem, zentriert) bleibt fuer die Countdown-Phase unveraendert.
   2026-08-02, Bugfix (Nutzerfeedback "das Foto ist viel zu klein, liegt es an der
   Gesamtbreite vom Container?"): ja, per Puppeteer nachgemessen, exakt das war die Ursache.
   .pb-thanks-text hatte eine feste max-width:30rem (480px), .pb-phase (geerbt von der
   Countdown-Phase) selbst deckelte die gesamte Zeile zusaetzlich auf max-width:46rem (736px),
   dem Carousel blieben dadurch nur ca. 126px Restbreite. .pb-phase--thanks bekommt jetzt eine
   eigene, deutlich groessere max-width, .pb-thanks-text eine kleinere (der Fliesstext braucht
   die 480px nicht, seit "Jetzt Fotobox Mieten" + Buttons herausgeloest sind, siehe unten). */
.pb-phase--thanks {
  width: 85%;
  /* 2026-08-02, Nutzerfeedback "das ist die Desktop-Ansicht, viel Platzverschwendung, alles
     unnoetig gequetscht" (getestet auf einem 2236px breiten Monitor): der vorherige Deckel bei
     76rem (1216px) war gegen ein ca. 1440px breites Testfenster kalibriert, auf einem deutlich
     breiteren Monitor blieb der Inhalt dadurch klein und mittig, drumherum viel ungenutzte
     Flaeche. Deutlich angehoben. */
  max-width: 100rem;
  /* 2026-08-02, Nutzerwunsch "Bild VH100, es darf kein Scroll entstehen": .pb-phase (Basisregel)
     bringt 2rem vertikales Padding mit, das oben auf die 100vh der Bildkarte draufaddiert und so
     zuverlaessig Scroll erzwungen hat. Nur hier auf 0 gesetzt, damit die Karte exakt in die
     Overlay-Hoehe passt (die selbst per inset:0 exakt dem Viewport entspricht). */
  padding-top: 0;
  padding-bottom: 0;
}

.pb-thanks-layout {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 2.5rem);
  width: 100%;
}

.pb-thanks-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 2.5rem);
}

@media (min-width: 760px) {
  .pb-thanks-layout {
    flex-direction: row;
    /* 2026-08-02, Nutzerwunsch: "Jetzt Fotobox Mieten und die 2 Buttons bitte in die linke
       Spalte, unterhalb des Textes." Slogan+Buttons sind jetzt Teil von .pb-thanks-text.
       2026-08-02: seit die Bildkarte ihre eigene feste Groesse hat statt sich per
       align-items:stretch an die Texthoehe anzupassen (siehe .pb-strip-track, jetzt ein
       Faecher aus mehreren Karten statt einem einzelnen grossflaechigen Bild), sorgt center
       fuer eine ruhigere gemeinsame Mitte statt oben buendig zu stehen. */
    align-items: center;
    /* 2026-08-02, Nutzerfeedback "Da ist so viel Platz dazwischen, alles deutlich groesser
       machen, dann hat es eine bessere Wirkung": space-between schob Text und Faecher an die
       gegenueberliegenden Raender, bei der jetzt deutlich groesseren Kartenfaeche (siehe
       .pb-strip-track) wirkte die Luecke dazwischen wie ein Layout-Unfall statt gestaltete
       Ruhe. Fester, grosszuegiger Abstand statt maximaler Spreizung, beide Elemente ruecken als
       bewusst komponierte Gruppe zusammen. */
    justify-content: center;
    /* 2026-08-02, Nutzerfeedback (2236px breiter Monitor): Obergrenze war gegen ein ~1440px
       breites Testfenster kalibriert, auf breiteren Monitoren blieb der Abstand kleiner als
       vorgesehen. */
    gap: clamp(3rem, 8vw, 11rem);
  }

  .pb-thanks-text {
    align-items: flex-start;
    text-align: left;
    max-width: 38rem;
    justify-content: center;
  }

  /* 2026-08-02: .pb-heading/.pb-slogan sind auch (in unveraenderter Groesse) die Countdown-
     Phase-Ueberschrift bzw. die urspruengliche volle-Breite-Slogan-Zeile, deren Schriftgroessen
     fuer den breiten 68rem-Container gedacht waren, in der schmaleren Spalte hier eigens
     angepasst.
     2026-08-02, Nutzerfeedback "Text ist so mickrig zu lesen, koennte deutlich groesser sein",
     danach "alles deutlich groesser machen": mehrfach spuerbar angehoben, zuletzt nochmal auf
     einem 2236px breiten Monitor nachgemessen (Obergrenzen waren gegen ein ~1440px breites
     Testfenster kalibriert und liefen dort schon voll aus). */
  .pb-thanks-text .pb-heading {
    font-size: clamp(1.5rem, 2.4vw, 2.3rem);
    line-height: 1.45;
    max-width: none;
  }

  .pb-thanks-text .pb-slogan {
    font-size: clamp(1.9rem, 3vw, 3.2rem);
    justify-content: flex-start;
    /* 2026-08-02, Nutzerfeedback: "Wenn JETZT FOTOBOX MIETEN schon in 2 Zeilen umbricht, dann
       zumindest nicht so einen grossen Abstand." gap setzt bei einem mehrzeiligen Flex-Container
       Zeilen- UND Wortabstand gleichermassen, column-gap/row-gap getrennt haelt den Wortabstand
       (column-gap) wie gehabt, engt aber gezielt nur den Abstand zwischen den Zeilen ein. */
    column-gap: 0.5em;
    row-gap: 0.05em;
  }
}

/* 2026-08-02, Nutzerwunsch: "Jetzt Fotobox Mieten sowie die 2 Buttons muessen aus der Section
   mit den 2 Containern raus, damit sich der Inhalt wieder zentriert darstellt." Slogan und
   Buttons sind jetzt direkte Kinder von .pb-phase--thanks (nicht mehr Teil von
   .pb-thanks-text), erben dadurch automatisch die zentrierte, volle-Breite-Darstellung der
   Basis-Regel .pb-phase, statt in der schmalen linken Text-Spalte gefangen zu sein. */

/* 2026-08-02: Farbe kommt jetzt per Vererbung von .pb-overlay (color:#fff, gilt seit der
   Nachbesserung fuer beide Phasen gleichermassen). Ohne den (entfernten) dunklen Verlauf
   braucht die Schrift einen kraeftigeren eigenen Schatten fuer Lesbarkeit auf dem hellen,
   funkelnden Foto: ein enger, harter Schatten fuer die Kontur plus ein weicherer, weiter
   reichender fuer die generelle Abhebung vom Untergrund. */
.pb-heading {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.4rem, 3.2vw, 2.4rem);
  max-width: 34ch;
  margin: 0;
  line-height: 1.25;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85), 0 4px 22px rgba(0, 0, 0, 0.6);
  /* 2026-08-02, Feinschliff ("Layout geil machen"): kleiner Auftakt-Moment statt dass der ganze
     Dankes-Screen einfach schlagartig steht. Da .pb-phase[hidden] auf display:none schaltet,
     startet diese Animation bei jedem Oeffnen zuverlaessig neu (Browser-Standardverhalten fuer
     Animationen auf zuvor nicht gerenderten Elementen), keine JS-Klassen-Steuerung noetig. */
  animation: pb-reveal-up 0.85s var(--ease-glow) both;
}

/* 2026-08-02, Nutzerwunsch: "'Das war ein Joke' bitte einmal groesser schreiben und nur mit
   Outline. Danach weiter im Text ohne Umbruch." display:block laesst die Zeile optisch wie eine
   eigene kleine Ueberschrift wirken, ohne dass der restliche Fliesstext danach ein manuelles
   <br> braucht, er flieszt einfach normal weiter (siehe Markup in site.js). Farbe/Kontur nutzt
   denselben -webkit-text-stroke-Ansatz wie FOTOBOX (site.css), bewusst als eigene, einfachere
   Regel (ohne den dortigen animierten Glanz-Sweep, der fuer dieses kleine UI-Element zu viel
   waere), Basis-Fuellung als sicherer Fallback fuer Browser ohne text-stroke-Support. */
.pb-heading-lead {
  display: block;
  /* 2026-08-02, Nutzerfeedback "alles deutlich groesser machen", zuletzt nochmal auf einem
     2236px breiten Monitor nachgemessen (Obergrenze lief dort schon voll aus). */
  font-size: clamp(2.1rem, 6.4vw, 4.6rem);
  line-height: 1.05;
  margin-bottom: 0.2em;
  color: var(--gold-bright);
}

@supports (-webkit-text-stroke: 1px black) or (text-stroke: 1px black) {
  .pb-heading-lead {
    color: transparent;
    -webkit-text-stroke: 2px var(--gold-bright);
    text-stroke: 2px var(--gold-bright);
  }
}

.pb-countdown-number {
  height: clamp(6rem, 20vw, 14rem);
  display: flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}

.pb-countdown-digit {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(6rem, 20vw, 14rem);
  line-height: 1;
  /* 2026-08-02, Nutzerwunsch "Hintergrundbild fuer den Countdown": Ziffern nur hier verwendet
     (keine Wiederverwendung anderswo), Farbe deshalb direkt von var(--bg-void) (dunkel, war fuer
     den bisherigen weissen Hintergrund gedacht) auf Gold umgestellt, passend zum neuen
     Foto-Hintergrund. */
  color: var(--gold-bright);
  display: inline-block;
  /* 2026-08-02, Nachbesserung: seit der dunkle Verlauf ueber dem Foto entfernt wurde (Nutzer-
     feedback "macht den Backdrop kaputt"), braucht die Ziffer eine eigene Kontur fuer
     Lesbarkeit. filter:drop-shadow() statt text-shadow, da text-shadow bereits vom Keyframe
     (der eigentliche Gold-Glow-Puls) animiert wird, beide Properties ueberschneiden sich sonst. */
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.7));
  animation: pb-countdown-pop 900ms cubic-bezier(0.22, 0.9, 0.32, 1) forwards;
  will-change: transform, opacity;
}

@keyframes pb-countdown-pop {
  0%   { opacity: 0; transform: scale(0.4); text-shadow: 0 0 0 rgba(232, 196, 104, 0); }
  22%  { opacity: 1; transform: scale(1.08); text-shadow: 0 0 40px rgba(232, 196, 104, 0.5); }
  34%  { transform: scale(1); }
  68%  { opacity: 1; transform: scale(1); text-shadow: 0 0 0 rgba(232, 196, 104, 0); }
  100% { opacity: 0; transform: scale(1.5); text-shadow: 0 0 60px rgba(232, 196, 104, 0.85); }
}

.pb-slogan {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.6rem, 4.5vw, 3rem);
  letter-spacing: 0.03em;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5em;
  margin: 0;
  /* 2026-08-02, Nachbesserung: derselbe Kontur-Schatten wie .pb-heading, ohne den (entfernten)
     dunklen Verlauf braeuchten die Slogan-Woerter sonst zu viel Kontrast vom Betrachter selbst
     erraten. */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85), 0 4px 22px rgba(0, 0, 0, 0.6);
}

/* 2026-08-02, Nachbesserung: --gold-deep (ein gedecktes Dunkelgold) verschwand auf dem
   funkelnden Gold-Foto-Hintergrund fast unsichtbar, auf --gold-bright gewechselt (deutlich
   heller/kontrastreicher als der Bild-Untergrund).
   2026-08-02, Feinschliff ("Layout geil machen"): jedes Wort poppt einzeln nacheinander ein
   statt dass der ganze Slogan auf einmal steht, passend zur bereits gestaffelten Bewegungssprache
   der Seite (z. B. Ablauf-Icons, Hero-Cards). */
.pb-word {
  display: inline-block;
  /* 2026-08-02, Nutzerfeedback "davon sehe ich nichts": Dauer angehoben, Staffel-Abstand
     zwischen den Woertern von 0.12s auf 0.22s vergroessert, damit "eins nach dem anderen"
     tatsaechlich als solches wahrnehmbar ist statt in unter einer halben Sekunde vorbei zu sein. */
  animation: pb-reveal-up 0.75s var(--ease-glow) both;
}

.pb-word--jetzt {
  color: var(--gold-bright);
  animation-delay: 0.3s;
}

.pb-word--fotobox {
  color: var(--neon-pink);
  animation-delay: 0.52s;
}

.pb-word--mieten {
  color: var(--neon-violet);
  animation-delay: 0.74s;
}

/* 2026-08-02, Nutzerfeedback "davon sehe ich nichts": per Puppeteer nachgemessen (Opacity/
   Transform in 100ms-Schritten abgetastet), die Animation lief technisch korrekt (0 zu 1 Opazitaet,
   sauber gestaffelt), war aber zu dezent (nur 16px Versatz) und startete direkt im Anschluss an
   die 3er-Blitz-Salve (runFlashVolley in site.js), deren Nachleuchten die kurze, kleine Bewegung
   optisch verschluckt hat. Versatz und Dauer spuerbar vergroessert. */
@keyframes pb-reveal-up {
  from {
    opacity: 0;
    transform: translateY(34px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 2026-08-02, Nutzerwunsch: Fotostreifen-Carousel ("wie bei Instagram, mit Punkten unten
   drunter, um an das naechste zu kommen") im Dankes-Screen. Hoehe statt Breite als
   Steuergroesse, weil die Karten portraet-hoch sind (Fotostreifen-Seitenverhaeltnis ca. 1:3),
   aspect-ratio leitet die passende Breite automatisch ab, damit die Karte auf jeder
   Viewport-Hoehe eine sinnvolle Groesse behaelt. Struktur/Bild-Liste siehe
   setupStripCarousel()/pbStripImages in assets/js/site.js. */
.pb-strip-carousel {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

/* 2026-08-02, Nutzerwunsch: "Geil waere es gewesen, wenn die Bilder sich aufgefaechert
   haetten. So ist das total oede." Ersetzt das bisherige Ein-Bild-plus-Punkte-Carousel
   komplett: .pb-strip-track ist jetzt nur noch der Dreh-/Ankerpunkt (unten mittig,
   overflow:visible), alle Streifen liegen gleichzeitig darauf, jeder mit eigener Rotation und
   Verschiebung, wie eine aufgefaecherte Hand Sofortbilder. Feste Kartengroesse statt
   aspect-ratio auf dem Track selbst, weil jetzt jede Karte (.pb-strip-slide) ihre eigene
   Groesse braucht statt eine gemeinsame Flaeche zu teilen. */
/* 2026-08-02, Nutzerfeedback "alles deutlich groesser machen": Kartengroesse spuerbar
   angehoben (Faktor ca. 1.25). */
/* 2026-08-02, Nutzerfeedback (2236px breiter Monitor): Obergrenzen waren gegen ein ~1440px
   breites Testfenster kalibriert, dort schon voll ausgereizt, auf breiteren/hoeheren Monitoren
   blieb die Karte klein statt mitzuwachsen. Deutlich angehoben. */
.pb-strip-track {
  position: relative;
  width: clamp(220px, 27vw, 440px);
  height: clamp(380px, 54vh, 740px);
  overflow: visible;
}

@media (max-width: 759px) {
  .pb-strip-track {
    width: clamp(170px, 52vw, 240px);
    height: clamp(270px, 38vh, 360px);
  }
}

/* Rezeptur (Rahmen/Glow) 1:1 von ".print-card" (site.css, Galerie "Direkt aus dem Drucker")
   uebernommen, DESIGN_SYSTEM.md Abschnitt 4: dieselbe "echter Druck"-Optik, die sich anderswo
   auf der Seite schon bewaehrt hat, statt etwas Neues zu erfinden. */
.pb-strip-slide {
  position: absolute;
  left: 50%;
  bottom: 0;
  height: 100%;
  width: auto;
  aspect-ratio: 1 / 3;
  object-fit: cover;
  border-radius: var(--radius-lg);
  border: 1.5px solid var(--neon-pink);
  box-shadow:
    0 0 14px rgba(255, 63, 192, 0.5),
    0 0 42px rgba(47, 230, 255, 0.28),
    0 18px 44px rgba(0, 0, 0, 0.55);
  cursor: pointer;
  transform-origin: bottom center;
  opacity: 0;
  /* 2026-08-02, Nutzerfeedback "davon sehe ich nichts": Dauer angehoben, siehe .pb-word oben
     fuer dieselbe Begruendung. */
  animation: pb-fan-in 0.8s var(--ease-glow) both;
  transition: transform 0.45s var(--ease-glow), box-shadow 0.35s var(--ease-glow),
    border-color 0.35s var(--ease-glow), z-index 0s;
}

@keyframes pb-fan-in {
  to {
    opacity: 1;
  }
}

/* Faecher-Positionen: 4 Karten (siehe pbStripImages, assets/js/site.js), Rotation waechst nach
   aussen, aufsteigender z-index von links nach rechts, damit jede Karte die vorherige leicht
   ueberlappt statt umgekehrt (natuerlicherer Fächer-Blick).
   2026-08-02, Bugfix (bei der Verifikation entdeckt): getBoundingClientRect() einer rotierten
   Karte ist die achsenparallele Bounding-Box, bei einer hohen schmalen Karte (aspect-ratio 1:3)
   deutlich breiter als die eigentliche Kartenbreite (bei 14deg Rotation ca. +130px auf jeder
   Seite bei der aktuellen Kartenhoehe). Das liess die aeusseren Karten trotz rechnerisch
   ausreichendem Abstand sichtbar in die Textspalte hineinragen. Rotation von 14/5deg auf
   9/3deg reduziert, Versatz leicht zurueckgenommen, das haelt den Faecher trotzdem klar
   erkennbar, ohne die Bounding-Box so stark aufzublasen. */
.pb-strip-slide:nth-child(1) { transform: translateX(calc(-50% - 128px)) rotate(-9deg); z-index: 1; animation-delay: 0.25s; }
.pb-strip-slide:nth-child(2) { transform: translateX(calc(-50% - 43px)) rotate(-3deg); z-index: 2; animation-delay: 0.45s; }
.pb-strip-slide:nth-child(3) { transform: translateX(calc(-50% + 43px)) rotate(3deg); z-index: 3; animation-delay: 0.65s; }
.pb-strip-slide:nth-child(4) { transform: translateX(calc(-50% + 128px)) rotate(9deg); z-index: 4; animation-delay: 0.85s; }

@media (max-width: 759px) {
  .pb-strip-slide:nth-child(1) { transform: translateX(calc(-50% - 60px)) rotate(-9deg); }
  .pb-strip-slide:nth-child(2) { transform: translateX(calc(-50% - 20px)) rotate(-3deg); }
  .pb-strip-slide:nth-child(3) { transform: translateX(calc(-50% + 20px)) rotate(3deg); }
  .pb-strip-slide:nth-child(4) { transform: translateX(calc(-50% + 60px)) rotate(9deg); }

  .pb-strip-slide:nth-child(1):hover { transform: translateX(calc(-50% - 60px)) rotate(-9deg) translateY(-8px) scale(1.03); }
  .pb-strip-slide:nth-child(2):hover { transform: translateX(calc(-50% - 20px)) rotate(-3deg) translateY(-8px) scale(1.03); }
  .pb-strip-slide:nth-child(3):hover { transform: translateX(calc(-50% + 20px)) rotate(3deg) translateY(-8px) scale(1.03); }
  .pb-strip-slide:nth-child(4):hover { transform: translateX(calc(-50% + 60px)) rotate(9deg) translateY(-8px) scale(1.03); }
}

/* 2026-08-02, Nutzerfeedback: "Man neigt dazu, der Card mit der Maus zu folgen, dadurch draengt
   sich eine andere Card in den Mittelpunkt, das ist nicht gut geloest." Root Cause: :hover holte
   die Karte bisher per z-index:10 + Geraderichten voll in den Vordergrund, dadurch ueberdeckte
   sie beim Voruebergleiten der Maus kurzzeitig ihre Nachbarn, die dann ihrerseits :hover
   ausloesten, sobald die Maus (jetzt ueber der frisch nach vorn gesprungenen Karte) die
   Ueberlappungszone wechselte, ein sich selbst verstaerkendes Hin-und-Her. Fix: :hover bleibt
   jetzt bewusst dezent (nur ein kleines Anheben in der eigenen Schraeglage, kein Geraderichten,
   kein z-index-Sprung), veraendert also nicht mehr, welche Karte gerade obenauf liegt. Die volle
   "nach vorn, gerade, gross"-Bewegung (siehe .is-front) bleibt exklusiv dem bewussten Klick
   vorbehalten (siehe assets/js/site.js setupStripCarousel), nicht mehr einem blossen
   Vorbeigleiten der Maus. */
.pb-strip-slide:nth-child(1):hover { transform: translateX(calc(-50% - 128px)) rotate(-9deg) translateY(-10px) scale(1.03); }
.pb-strip-slide:nth-child(2):hover { transform: translateX(calc(-50% - 43px)) rotate(-3deg) translateY(-10px) scale(1.03); }
.pb-strip-slide:nth-child(3):hover { transform: translateX(calc(-50% + 43px)) rotate(3deg) translateY(-10px) scale(1.03); }
.pb-strip-slide:nth-child(4):hover { transform: translateX(calc(-50% + 128px)) rotate(9deg) translateY(-10px) scale(1.03); }

.pb-strip-slide.is-front {
  transform: translateX(-50%) translateY(-16px) rotate(0deg) scale(1.1);
  z-index: 10;
  border-color: var(--neon-cyan);
  box-shadow:
    0 0 18px rgba(47, 230, 255, 0.6),
    0 0 54px rgba(255, 63, 192, 0.35),
    0 24px 54px rgba(0, 0, 0, 0.6);
}

@media (prefers-reduced-motion: reduce) {
  .pb-strip-slide {
    animation: none;
    opacity: 1;
    transition: none;
  }
}

/* 2026-08-02, Feinschliff: die Buttons hatten bisher gar keine eigene Layout-Regel (nur
   Browser-Standardfluss der <a>/<button>-Kindelemente), Abstand kam zufaellig vom umgebenden
   Inline-Fluss statt bewusst gesetzt zu sein. Eigenes gap + Reveal als letzter Schritt der
   gestaffelten Eroeffnung (siehe .pb-heading/.pb-word weiter oben). */
.pb-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
  animation: pb-reveal-up 0.85s var(--ease-glow) both;
  animation-delay: 0.95s;
}

/* 2026-08-02, Nutzerfeedback "alles deutlich groesser machen": .btn-glow ist eine globale
   Seiten-Komponente (site-weite CTA-Buttons), hier bewusst nur innerhalb von .pb-actions
   vergroessert statt die globale Regel anzufassen. */
.pb-actions .btn-glow,
.pb-actions .pb-dismiss {
  padding: 18px 40px;
  font-size: 1.15rem;
}

.pb-dismiss {
  padding: 14px 32px;
  border-radius: 999px;
  border: 1.5px solid #fff;
  background: rgba(0, 0, 0, 0.25);
  color: #fff;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.3s var(--ease-glow), color 0.3s var(--ease-glow);
}

.pb-dismiss:hover {
  background: #fff;
  color: var(--bg-void);
}

.pb-dismiss:focus-visible {
  outline: 2px solid var(--neon-violet);
  outline-offset: 3px;
}

.pb-toast {
  position: fixed;
  left: 50%;
  bottom: clamp(1.5rem, 5vw, 3rem);
  z-index: 10001;
  padding: 0.9rem 1.6rem;
  border-radius: 999px;
  background: rgba(28, 23, 48, 0.92);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  border: 1px solid rgba(157, 78, 255, 0.5);
  color: var(--text-primary);
  font-size: 0.95rem;
  pointer-events: none;
  animation: pb-toast-in-out 4s ease forwards;
}

@keyframes pb-toast-in-out {
  0%   { opacity: 0; transform: translateX(-50%) translateY(12px); }
  8%   { opacity: 1; transform: translateX(-50%) translateY(0); }
  85%  { opacity: 1; transform: translateX(-50%) translateY(0); }
  100% { opacity: 0; transform: translateX(-50%) translateY(8px); }
}

@media (prefers-reduced-motion: reduce) {
  .pb-overlay,
  .pb-countdown-digit,
  .pb-toast {
    display: none;
  }
}
