/**
 * gast-design.css – Event-Design für die Gäste-Seite (Arbeitspaket B2).
 *
 * Funktionsweise: gast.js setzt pro Event ein paar "rohe" Design-Tokens
 * (--g-…) als Inline-Styles auf <body>, sobald guest-info ein `design`-Feld
 * liefert (siehe gast.js, applyGuestDesign()). Diese Datei übersetzt die
 * --g-…-Tokens auf dieselben CSS-Variablen, die style.css für die
 * Gäste-Klassen (.guest-hero, .btn, .card, …) ohnehin schon verwendet
 * (--bg/--card/--text/--accent/--radius-sm …) – dadurch färbt sich die
 * GESAMTE Gäste-Seite (Buttons, Karten, Badges, Melde-Dialog) über EINE
 * Stelle um, ohne dass style.css angefasst werden muss.
 *
 * Sicherheitsnetz: jeder --g-…-Fallback unten entspricht exakt dem heutigen
 * Eukalyptus-Wert aus style.css. Setzt gast.js NICHTS (weil eine ältere,
 * noch nicht neu deployte guest-info-Function kein `design`-Feld liefert –
 * siehe Kommentar in gast.js), sehen alle Werte hier genauso aus wie ohne
 * diese Datei. Die Seite bleibt also auch ohne Function-Deploy unverändert.
 */

@font-face {
  font-family: "Cormorant Garamond";
  src: url("../fonts/designer/CormorantGaramond.ttf") format("truetype");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* ---------- Token-Übersetzung: --g-… → die von style.css genutzten Tokens ---------- */
body.guest-body {
  --bg: var(--g-bg, #f2f6f2);
  --card: var(--g-card, #ffffff);
  --text: var(--g-text, #2f3a38);
  --text-muted: var(--g-text-muted, #5f6d69);
  --accent: var(--g-accent, #4f7060);
  --accent-dark: var(--g-accent-dark, #3d5a4c);
  --line: var(--g-line, rgba(47, 58, 56, 0.12));
  font-family: var(--g-font-body, "Poppins", "Segoe UI", Arial, sans-serif);
}

/* Buttons bekommen eine EIGENE Radius-Variable statt --radius-sm global zu
   überschreiben: --radius-sm/-md/-lg werden auch für Karten, Dropzone & Co.
   gebraucht, die bei "Buttons 999px" (Template Mitternacht) nicht plötzlich
   pillenförmig werden sollen. */
body.guest-body .btn {
  border-radius: var(--g-radius-btn, 8px);
}

/* Primärbutton: FLACHE, reine Akzentfarbe (keine Verlaufsstufen). style.css
   färbt den Button global mit einem 3-Stufen-Verlauf, dessen Startpunkt ein
   fest verdrahtetes Grün ist – das ignorierte die gewählte Akzentfarbe. Auf
   der Gäste-Seite übersteuern wir das bewusst: der Button ist exakt die vom
   Veranstalter gewählte Farbe (ruhiger, professioneller, ehrlich zur Wahl).
   Textfarbe berechnet gast.js per Kontrast-Prüfung gegen genau diese Farbe. */
body.guest-body .btn--primary {
  background: var(--accent);
  color: var(--g-btn-text, #ffffff);
  /* Sanfter, farbneutraler Tiefen-Schatten statt Verlauf – gibt dem flachen
     Button Halt, ohne einen zweiten Farbton einzuführen. */
  box-shadow: 0 10px 24px -12px rgba(0, 0, 0, 0.45);
}
body.guest-body .btn--primary:hover {
  /* Dezente Abdunklung derselben Farbe (gast.js: Akzent −18 %), kein Fremdton. */
  background: var(--accent-dark);
  box-shadow: 0 12px 26px -12px rgba(0, 0, 0, 0.5);
}

/* Überschriften bekommen die Template-Schrift (z. B. Cormorant Garamond bei
   "klassik"); ohne gesetztes --g-font-head bleibt es die Body-Schrift. */
body.guest-body .guest-hero__title,
body.guest-body .guest-gallery-title,
body.guest-body .report-dialog__title {
  font-family: var(--g-font-head, inherit);
}

/* ---------- Neue Hero-Elemente (Profilfoto, eigener Datumstext) ----------
   Beide Elemente existieren als <img>/<p> bereits in gast.html, aber `hidden`
   – gast.js blendet sie nur ein, wenn guest-info tatsächlich ein Foto bzw.
   einen Datumstext liefert. Kein Effekt auf den heutigen Look. */
body.guest-body .guest-hero__photo {
  display: block;
  width: 84px;
  height: 84px;
  margin: 0 auto 14px;
  border-radius: 50%;
  object-fit: cover;
  border: 3px solid var(--card);
  box-shadow: 0 0 0 1px var(--line), 0 6px 18px rgba(0, 0, 0, 0.12);
}

body.guest-body .guest-hero__date {
  margin: -4px 0 12px;
  font-size: 13.5px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

/* ---------- Dunkler Modus (Template "mitternacht" bzw. jede sehr dunkle
   Veranstalter-Hintergrundfarbe – siehe gast.js, isDarkColor()) ----------
   gast.js setzt data-g-scheme="dark" NUR, wenn die tatsächlich wirksame
   Hintergrundfarbe dunkel ist (Template-Default oder Übersteuerung). Die
   meisten Gäste-Klassen in style.css nutzen bereits --bg/--card/--text/
   --line, die oben umdefiniert sind und automatisch mitziehen. Ein paar
   Stellen sind dort bewusst FEST verdrahtet (Toast, Fehlertext, Dropzone-
   Overlay, Galerie-Platzhalter) und würden auf dunklem Grund unlesbar bzw.
   falsch aussehen – die werden hier gezielt nachgeschärft. Alles unter
   diesem Selektor greift nur mit gesetztem data-g-scheme="dark", NIE beim
   heutigen Standarddesign (Regressionsschutz). */
body.guest-body[data-g-scheme="dark"] {
  color-scheme: dark;
}

/* Toast: style.css nutzt background: var(--text) – das ist im Hellmodus ein
   dunkler Chip (passt), würde im Dunkelmodus aber HELL (var(--text) ist dann
   die helle Schriftfarbe) mit weißer Schrift kollidieren. Fest verdrahtet,
   unabhängig von --text, damit der Toast in beiden Schemata funktioniert. */
body.guest-body[data-g-scheme="dark"] .toast {
  background: #12181a;
  color: #f3efe6;
}

/* Fehlertexte (Consent-Pflicht, Melde-Formular, fehlgeschlagener Upload):
   #93433c ist auf hellem Karton gut lesbar, auf dunklem Karton zu dunkel. */
body.guest-body[data-g-scheme="dark"] .guest-consent__error,
body.guest-body[data-g-scheme="dark"] .report-dialog__error,
body.guest-body[data-g-scheme="dark"] .guest-queue__item--error .guest-queue__status {
  color: #e8a79c;
}

body.guest-body[data-g-scheme="dark"] .guest-queue__item--error {
  border-color: rgba(232, 167, 156, 0.45);
}

body.guest-body[data-g-scheme="dark"] .guest-queue__item--error .progress-bar__fill {
  background: #e8a79c;
}

/* Dropzone-Overlay (rgba(255,255,255,.6)) und Galerie-Platzhalter (var(--band),
   ein festes helles Salbeigrün) wären auf dunklem Grund ein heller Fleck. */
body.guest-body[data-g-scheme="dark"] .guest-dropzone {
  background: rgba(255, 255, 255, 0.04);
}

body.guest-body[data-g-scheme="dark"] .guest-dropzone:hover,
body.guest-body[data-g-scheme="dark"] .guest-dropzone--active {
  background: rgba(255, 255, 255, 0.08);
}

body.guest-body[data-g-scheme="dark"] .guest-gallery-cell {
  background: rgba(255, 255, 255, 0.06);
}

/* --- Galerie-Politur (Fable-Galerie-Audit #14): klickbar, flüssiger, mobil dichter --- */
.guest-gallery-cell {
  cursor: pointer;
  /* Offscreen-Kacheln aus Render/Speicher halten -> auch tausende Bilder flüssig */
  content-visibility: auto;
  contain-intrinsic-size: 120px;
}
.guest-gallery-cell:focus-visible {
  outline: 2px solid var(--g-accent, #4f7060);
  outline-offset: 2px;
}
/* sanftes Einblenden statt hartem Poppen */
.guest-gallery-cell__img { opacity: 0; transition: opacity 0.28s ease; }
.guest-gallery-cell__img.is-loaded { opacity: 1; }
/* Video: Poster + Play-Symbol im Grid (kein <video>) */
.guest-gallery-cell__poster { opacity: 0.9; }
.guest-gallery-cell__play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  pointer-events: none;
  z-index: 2; /* über dem Lesbarkeits-Verlauf der Kachel (style.css, ::after) */
}
.guest-gallery-cell__play svg {
  box-sizing: border-box;
  width: 36px;
  height: 36px;
  padding: 8px;
  background: rgba(0, 0, 0, 0.42);
  border-radius: 999px;
}
/* Mobil dichter (Kamerarolle-Look), Desktop luftiger */
@media (max-width: 640px) {
  .guest-gallery-grid { grid-template-columns: repeat(3, 1fr); gap: 5px; }
}
@media (min-width: 641px) {
  .guest-gallery-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .guest-gallery-cell__img { transition: none; opacity: 1; }
}

/* "wird optimiert"-Hinweis auf Video-Kacheln, solange der Worker transcodiert.
   Seit dem Kachel-Umbau 25.09. oben links statt unten links – unten links
   steht jetzt die Uploader-Zeile „Foto von <Name>" (style.css). */
.guest-gallery-cell__badge {
  position: absolute;
  left: 4px;
  top: 4px;
  z-index: 2;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 10px;
  line-height: 1;
  padding: 3px 6px;
  border-radius: var(--r-m, 14px); /* Token-Radius, wirkt auf der Chip-Höhe wie eine Pille */
  pointer-events: none;
}

/* =====================================================================
   Gäste-Layouts (Etappe 2+3, 25.09.26): drei wählbare Looks über
   design.layout aus guest-info. gast.js setzt data-g-layout am <body>
   ("standard" | "hero" | "editorial").

   REGRESSIONSSCHUTZ (oberste Regel): Für [data-g-layout="standard"] und
   für Events ganz OHNE Attribut existiert hier bewusst KEINE einzige
   Regel – Bestandsevents rendern byte-genau wie heute. Alles Folgende
   greift ausschließlich unter data-g-layout="hero" bzw. "editorial".
   Die neuen Elemente (Eyebrow, Einleitungstext, Foto-Fläche) sind ohne
   JS-Zutun hidden; nur der Einleitungstext hat eine layout-unabhängige
   Grundform (Standard-Look laut freigegebenem Entwurf gast-standard).
   ===================================================================== */

/* ---------- Einleitungstext (design.welcome_text, alle Layouts) ----------
   Nur sichtbar, wenn gast.js Text setzt (sonst hidden -> heutiger Look). */
body.guest-body .guest-hero__welcome {
  margin: 0 auto 20px;
  max-width: 420px;
  font-family: var(--g-font-head, "Fraunces", Georgia, serif);
  font-size: 17px;
  line-height: 1.5;
  font-weight: 400;
  color: var(--text);
}

/* Eyebrow-Grundform (gast.js zeigt sie nur in hero/editorial) */
body.guest-body .guest-hero__eyebrow {
  margin: 0 0 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

/* Foto-Schleier (editorial): ohne Layout-Attribut nie sichtbar */
body.guest-body .guest-hero__veil {
  display: none;
}

/* ---------- Gemeinsames für hero + editorial ---------- */

/* Absolutes Bezugssystem für die überlagernde Navigation (unter dem
   Demo-Banner, nicht am Viewport – sonst läge die Nav im Demo-Modus
   über dem Banner). */
body.guest-body[data-g-layout="hero"] .guest-page,
body.guest-body[data-g-layout="editorial"] .guest-page {
  position: relative;
}

body.guest-body[data-g-layout="hero"] .topnav,
body.guest-body[data-g-layout="editorial"] .topnav {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 6;
  background: transparent;
  border-bottom: none;
}

/* Hero-Inhalte über die Foto-Fläche legen */
body.guest-body[data-g-layout="hero"] .guest-hero > *,
body.guest-body[data-g-layout="editorial"] .guest-hero > * {
  position: relative;
  z-index: 2;
}

/* Event-Name als große Serifen-Zeile (der Charakter beider Layouts) */
body.guest-body[data-g-layout="hero"] .guest-hero__event,
body.guest-body[data-g-layout="editorial"] .guest-hero__event {
  font-family: var(--g-font-head, "Fraunces", Georgia, serif);
  font-size: 44px;
  line-height: 1.06;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* Rundes Mini-Foto übernehmen die neuen Heros nicht (das große Foto bzw. der
   Blend ersetzt es) – im Standard bleibt es. */
body.guest-body[data-g-layout="hero"] .guest-hero__photo,
body.guest-body[data-g-layout="editorial"] .guest-hero__photo {
  display: none;
}

/* Lorbeer-Deko (Strich + kleines Mittelsymbol) in ALLEN Layouts entfernt
   (Sebi 26.09.: wirkt zu sehr nach KI) – auch im Standard. */
body.guest-body .guest-hero__laurel {
  display: none;
}

/* "Deine Fotos vom Fest" bleibt als Überschrift für Screenreader erhalten,
   verschwindet aber visuell (der Event-Name trägt den Hero). */
body.guest-body[data-g-layout="hero"] .guest-hero__title,
body.guest-body[data-g-layout="editorial"] .guest-hero__title {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Eigener Einleitungstext ersetzt in den Foto-Layouts den Standardtext
   (beide zusammen wären doppelt); ohne welcome_text bleibt der
   Standardtext als Willkommenszeile stehen. */
body.guest-body[data-g-layout="hero"] .guest-hero__welcome:not([hidden]) ~ .guest-hero__text,
body.guest-body[data-g-layout="editorial"] .guest-hero__welcome:not([hidden]) ~ .guest-hero__text {
  display: none;
}

/* Galerie-Titel im Serifen-Ton der Entwürfe */
body.guest-body[data-g-layout="hero"] .guest-gallery-title,
body.guest-body[data-g-layout="editorial"] .guest-gallery-title {
  font-family: var(--g-font-head, "Fraunces", Georgia, serif);
  font-size: 24px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* ---------- Layout "hero": Vollflächen-Brautpaarfoto + Scrim ---------- */

body.guest-body[data-g-layout="hero"] .topnav .brand__logo {
  filter: brightness(0) invert(1);
  opacity: 0.95;
}
body.guest-body[data-g-layout="hero"] .topnav .brand__title { color: #fff; }
body.guest-body[data-g-layout="hero"] .topnav .brand__sub { color: rgba(255, 255, 255, 0.85); }
/* Der Event-Name steht groß im Hero selbst – oben rechts wäre er doppelt. */
body.guest-body[data-g-layout="hero"] .guest-eventname { display: none; }

body.guest-body[data-g-layout="hero"] .guest-hero {
  position: relative;
  /* Voll-Breite aus der zentrierten 640px-Spalte heraus (html hat bereits
     overflow-x: hidden, ein Desktop-Scrollbalken erzeugt also keinen
     Querscroll). */
  margin: 0 calc(50% - 50vw) 10px;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 110px 22px calc(30px + env(safe-area-inset-bottom));
  text-align: center;
  color: #fff;
  overflow: hidden;
  /* Ruhiger Grund, falls das Foto (noch) lädt */
  background: linear-gradient(168deg, var(--g-accent-dark, #3d5a4c) 0%, #17201d 110%);
}

body.guest-body[data-g-layout="hero"] .guest-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
body.guest-body[data-g-layout="hero"] .guest-hero__bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 30%;
}
/* Scrim wie im freigegebenen Entwurf: oben leicht (Nav lesbar), unten satt –
   Eyebrow/Name sitzen auf jeder Foto-Art ruhig, die Bildmitte bleibt frei. */
body.guest-body[data-g-layout="hero"] .guest-hero__bg:not(.guest-hero__bg--fallback)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(20, 26, 24, 0.42) 0%,
    rgba(20, 26, 24, 0.06) 20%,
    rgba(20, 26, 24, 0.08) 36%,
    rgba(20, 26, 24, 0.45) 55%,
    rgba(20, 26, 24, 0.72) 74%,
    rgba(20, 26, 24, 0.86) 100%
  );
}
/* Ohne Brautpaar-Foto: ruhiger Akzent-Verlauf statt leerer Fläche */
body.guest-body[data-g-layout="hero"] .guest-hero__bg--fallback {
  background: linear-gradient(168deg, var(--g-accent, #4f7060) 0%, #232e2a 96%);
}
body.guest-body[data-g-layout="hero"] .guest-hero__bg--fallback .guest-hero__bg-img {
  display: none;
}

body.guest-body[data-g-layout="hero"] .guest-hero__eyebrow {
  color: rgba(255, 255, 255, 0.92);
  letter-spacing: 0.32em;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.35);
}
body.guest-body[data-g-layout="hero"] .guest-hero__event {
  color: #fff;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.25);
}
body.guest-body[data-g-layout="hero"] .guest-hero__date {
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
}
body.guest-body[data-g-layout="hero"] .guest-hero__welcome,
body.guest-body[data-g-layout="hero"] .guest-hero__text {
  margin: 0 auto 24px;
  max-width: 340px;
  font-family: inherit;
  font-size: 15px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.92);
}

body.guest-body[data-g-layout="hero"] .guest-hero__actions {
  max-width: 400px;
}
/* Hauptknopf auf dem Foto: dieselbe flache Akzentfarbe wie überall (folgt der
   Kundenwahl), nur mit kräftigerem Schatten, damit er sich klar vom Foto
   abhebt. Textfarbe per Kontrast (gast.js), Nebenknopf bleibt Glas-Pille. */
body.guest-body[data-g-layout="hero"] .guest-hero__actions .btn--primary {
  background: var(--accent);
  color: var(--g-btn-text, #ffffff);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.38);
}
body.guest-body[data-g-layout="hero"] .guest-hero__actions .btn--primary:hover {
  background: var(--accent-dark);
}
body.guest-body[data-g-layout="hero"] .guest-hero__actions .btn--outline {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.35);
  color: #fff;
  font-weight: 600;
  padding: 13px 22px;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
body.guest-body[data-g-layout="hero"] .guest-hero__actions .btn--outline:hover {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  text-decoration: none;
}
body.guest-body[data-g-layout="hero"] .guest-private-note {
  color: rgba(255, 255, 255, 0.75);
}

/* ---------- Layout "editorial": Foto läuft weich in die Seitenfarbe ---------- */

body.guest-body[data-g-layout="editorial"] .guest-hero {
  position: relative;
  margin: 0 calc(50% - 50vw) 6px;
  padding: 252px max(22px, calc(50vw - 300px)) 40px;
  text-align: left;
  overflow: hidden;
}

/* Foto-Fläche mit Verlaufs-Maske: das Bild endet nie an einer harten Kante,
   sondern läuft in die (Design-)Hintergrundfarbe der Seite aus. */
body.guest-body[data-g-layout="editorial"] .guest-hero__bg {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 400px;
  z-index: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 97%);
  mask-image: linear-gradient(to bottom, #000 55%, transparent 97%);
}
body.guest-body[data-g-layout="editorial"] .guest-hero__bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 20%;
}
/* Sanfter Schleier nur oben, damit die (helle) Navigation auf jedem Foto
   lesbar bleibt – nur wenn wirklich ein Foto da ist. */
body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .guest-hero__bg::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 130px;
  z-index: 1;
  background: linear-gradient(to bottom, rgba(20, 26, 24, 0.4), rgba(20, 26, 24, 0));
  pointer-events: none;
}
/* Ohne Foto: ruhiger Akzent-Verlauf, der über dieselbe Maske ausläuft */
body.guest-body[data-g-layout="editorial"] .guest-hero__bg--fallback {
  background: linear-gradient(to bottom, var(--g-accent, #4f7060), transparent 96%);
  opacity: 0.3;
}
body.guest-body[data-g-layout="editorial"] .guest-hero__bg--fallback .guest-hero__bg-img {
  display: none;
}

/* Creme-Schleier über dem Textbereich: Eyebrow + Name stehen auf ruhiger
   Fläche, der weiche Foto-Übergang bleibt darüber sichtbar. */
body.guest-body[data-g-layout="editorial"] .guest-hero__veil {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 400px;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 45%, var(--bg, #f2f6f2) 86%);
  background: linear-gradient(
    to bottom,
    transparent 45%,
    color-mix(in srgb, var(--bg, #f2f6f2) 55%, transparent) 64%,
    var(--bg, #f2f6f2) 86%
  );
}

/* Navigation: hell über dem Foto (mobil), sonst dunkel wie gewohnt */
body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .topnav .brand__logo {
  filter: brightness(0) invert(1);
  opacity: 0.95;
}
body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .topnav .brand__title { color: #fff; }
body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .topnav .brand__sub { color: rgba(255, 255, 255, 0.85); }
/* Der Event-Name steht groß im Hero – oben rechts wäre er doppelt. */
body.guest-body[data-g-layout="editorial"] .guest-eventname { display: none; }

body.guest-body[data-g-layout="editorial"] .guest-hero__eyebrow {
  color: var(--accent);
}
body.guest-body[data-g-layout="editorial"] .guest-hero__event {
  margin: 0 0 12px;
  color: var(--text);
  letter-spacing: -0.015em;
}
body.guest-body[data-g-layout="editorial"] .guest-hero__date {
  margin: 0 0 16px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
}
body.guest-body[data-g-layout="editorial"] .guest-hero__welcome,
body.guest-body[data-g-layout="editorial"] .guest-hero__text {
  margin: 0 0 26px;
  max-width: 380px;
  font-family: var(--g-font-head, "Fraunces", Georgia, serif);
  font-size: 18px;
  line-height: 1.5;
  color: var(--text);
}
body.guest-body[data-g-layout="editorial"] .guest-hero__actions {
  margin: 0 0 14px;
  max-width: 420px;
}
body.guest-body[data-g-layout="editorial"] .guest-hero__actions .btn--outline {
  border-color: var(--line);
  color: var(--text);
  font-weight: 600;
  padding: 13px 22px;
}
body.guest-body[data-g-layout="editorial"] .guest-hero__actions .btn--outline:hover {
  border-color: var(--accent);
  color: var(--accent-dark);
  text-decoration: none;
}
body.guest-body[data-g-layout="editorial"] .guest-private-note {
  justify-content: flex-start;
}

/* Editorial am Desktop: Text links auf ruhiger Fläche, Foto rechts, linke
   Fotokante weich ausgeblendet (Entwurf gast-editorial, ab 900px). */
@media (min-width: 900px) {
  body.guest-body[data-g-layout="editorial"] .guest-hero {
    min-height: 620px;
    padding: 150px 40px 72px max(40px, calc(50vw - 520px));
  }
  body.guest-body[data-g-layout="editorial"] .guest-hero__bg {
    left: 40%;
    height: auto;
    bottom: 0;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 38%);
    mask-image: linear-gradient(to right, transparent 0, #000 38%);
  }
  body.guest-body[data-g-layout="editorial"] .guest-hero__bg-img {
    object-position: 50% 22%;
  }
  body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .guest-hero__bg::before {
    display: none; /* Nav steht links auf ruhiger Fläche, kein Scrim nötig */
  }
  body.guest-body[data-g-layout="editorial"] .guest-hero__veil {
    height: auto;
    inset: 0;
    /* Unterkante des Fotos läuft ebenfalls weich aus + linke Flanke deckt
       den Textbereich; Fallback ohne color-mix: nur die Unterkante. */
    background: linear-gradient(to top, var(--bg, #f2f6f2) 0, rgba(0, 0, 0, 0) 18%);
    background:
      linear-gradient(to top, var(--bg, #f2f6f2) 0, transparent 18%),
      linear-gradient(
        to right,
        color-mix(in srgb, var(--bg, #f2f6f2) 100%, transparent) 34%,
        color-mix(in srgb, var(--bg, #f2f6f2) 60%, transparent) 52%,
        transparent 70%
      );
  }
  /* Navigation zurück auf den dunklen Standard (Foto liegt rechts) */
  body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .topnav .brand__logo {
    filter: none;
    opacity: 1;
  }
  body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .topnav .brand__title { color: var(--text); }
  body.guest-body[data-g-layout="editorial"][data-g-hero-photo="on"] .topnav .brand__sub { color: var(--accent); }
  body.guest-body[data-g-layout="editorial"] .guest-hero__event {
    font-size: 58px;
  }
  body.guest-body[data-g-layout="editorial"] .guest-hero__actions {
    flex-direction: row;
    max-width: none;
  }
  /* btn--block (mobil sinnvoll) darf in der Desktop-Reihe nicht auf volle
     Hero-Breite gehen – sonst läuft "Fotos hochladen" quer übers Foto. */
  body.guest-body[data-g-layout="editorial"] .guest-hero__actions .btn {
    flex: 0 0 auto;
    width: auto;
    padding-left: 26px;
    padding-right: 26px;
  }
  /* Navigation auf dieselbe 1040px-Spalte ausrichten wie der Hero-Inhalt */
  body.guest-body[data-g-layout="editorial"] .topnav .guest-container {
    max-width: 1040px;
  }
}

/* ---------- Bento-Galerie (nur hero/editorial) ----------
   Aspektbewusstes Mosaik statt gleichförmigem Raster: gast.js vergibt je
   Kachel --lead/--wide/--tall aus den echten Bildmaßen (plus ruhige
   Rhythmus-Anker); dense füllt Lücken. Chips (Herz/melden/Name), Verlauf,
   Lightbox-Reihenfolge (data-index) und content-visibility bleiben exakt
   wie im Standard-Raster – nur Spalten/Zeilen ändern sich. */

body.guest-body[data-g-layout="hero"] .guest-gallery-grid,
body.guest-body[data-g-layout="editorial"] .guest-gallery-grid {
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 84px;
  grid-auto-flow: row dense;
  gap: 6px;
}
body.guest-body[data-g-layout="hero"] .guest-gallery-cell,
body.guest-body[data-g-layout="editorial"] .guest-gallery-cell {
  aspect-ratio: auto;
  grid-row: span 2;
  border-radius: var(--r-m, 14px);
  /* contain-intrinsic-size (120px, oben) bleibt: bei festen Grid-Zeilen
     bestimmt ohnehin das Raster die Kachelgröße, nicht der Inhalt. */
}
body.guest-body[data-g-layout="hero"] .guest-gallery-cell--tall,
body.guest-body[data-g-layout="editorial"] .guest-gallery-cell--tall {
  grid-row: span 3;
}
body.guest-body[data-g-layout="hero"] .guest-gallery-cell--wide,
body.guest-body[data-g-layout="editorial"] .guest-gallery-cell--wide {
  grid-column: span 2;
}
body.guest-body[data-g-layout="hero"] .guest-gallery-cell--lead,
body.guest-body[data-g-layout="editorial"] .guest-gallery-cell--lead {
  grid-column: span 2;
  grid-row: span 3;
}
@media (min-width: 700px) {
  body.guest-body[data-g-layout="hero"] .guest-gallery-grid,
  body.guest-body[data-g-layout="editorial"] .guest-gallery-grid {
    grid-template-columns: repeat(4, 1fr);
    grid-auto-rows: 96px;
    gap: 8px;
  }
}

/* "+ mehr"-Kachel (Overlay auf der letzten Kachel, solange es weitere
   Seiten gibt): gleiche Glas-Optik wie im Entwurf, echtes Touch-Ziel. */
body.guest-body .guest-bento-more {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: none;
  padding: 0;
  cursor: pointer;
  color: #fff;
  background: rgba(31, 38, 36, 0.55);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  font-family: inherit;
}
body.guest-body .guest-bento-more strong {
  font-family: var(--g-font-head, "Fraunces", Georgia, serif);
  font-size: 26px;
  font-weight: 500;
  line-height: 1.1;
}
body.guest-body .guest-bento-more span {
  font-size: 11px;
  opacity: 0.85;
}
body.guest-body .guest-bento-more:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: -3px;
}

/* --- Live-Vorschau im Dashboard-iPhone-Rahmen (nur preview=1) ---
   Echte Handys schieben den Seiteninhalt über die Statusleiste/Safe-Area unter
   das Dynamic Island; im iframe gibt es das nicht, deshalb würde der Rahmen-Notch
   den Kopf verdecken. Nur im Vorschau-Modus (body.guest-preview) beginnt der
   Nav-Inhalt darum ~44px tiefer. Gilt für alle drei Layouts; echte Gäste sind
   davon nie betroffen. */
body.guest-body.guest-preview .guest-topnav.topnav__inner {
  height: auto;
  min-height: 84px;
  padding-top: 44px;
}

/* ============================================================
   Layout "signature" (Snap Signature, 27.09.2026)
   Vellum-Karte über fixiertem Kundenfoto: das Foto steht fest,
   NUR die fast blickdichte Creme-Karte scrollt darüber (Referenz-
   Mock von Sebi, per Pixel-Vermessung + Sonnet-Diff nachgebaut).
   Alles strikt unter [data-g-layout="signature"] – kein Einfluss
   auf standard/hero/editorial.
   ============================================================ */

/* Foto: fixierter Vollflächen-Hintergrund, SCHARF (kein Scrim/Mask) */
body.guest-body[data-g-layout="signature"] { background: var(--bg); }
body.guest-body[data-g-layout="signature"] .guest-hero__bg {
  display: block;
  position: fixed;
  inset: 0;
  /* -2: unter dem Vellum-::before (-1) und unter ALLEN (auch unpositionierten)
     Karteninhalten – fixe Kinder malen sonst über den Container-Hintergrund. */
  z-index: -2;
  pointer-events: none;
}
body.guest-body[data-g-layout="signature"] .guest-hero__bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 30%;
  display: block;
}
body.guest-body[data-g-layout="signature"] .guest-hero__bg--fallback {
  background: linear-gradient(160deg, color-mix(in srgb, var(--accent) 26%, #ffffff) 0%, var(--bg) 70%);
}
body.guest-body[data-g-layout="signature"] .guest-hero__bg--fallback .guest-hero__bg-img { display: none; }
body.guest-body[data-g-layout="signature"] .guest-hero__veil { display: none; }

/* Nav schwebt über dem Foto (Marke bleibt lesbar, Event-Name steckt in der Karte) */
body.guest-body[data-g-layout="signature"] .topnav {
  position: absolute;
  inset: 0 0 auto;
  background: transparent;
  box-shadow: none;
  border: 0;
  z-index: 2;
}
body.guest-body[data-g-layout="signature"] .guest-eventname { display: none; }

/* Die Vellum-Karte = der komplette Seiteninhalt. 22px Foto-Rand seitlich,
   Start ~92px unter der Oberkante, warmes fast blickdichtes Creme. */
body.guest-body[data-g-layout="signature"] main.guest-container {
  position: relative;
  max-width: 430px;
  margin: 92px 22px 24px;
  padding: 50px 18px 18px;
  /* Die sichtbare Karte lebt im ::before (z -1): so liegt sie ÜBER dem
     fixierten Foto (-2), aber UNTER allen Inhalten – ein background auf dem
     Container selbst läge unter dem fixen Foto-Kind (Painting-Order). */
  background: transparent;
}
body.guest-body[data-g-layout="signature"] main.guest-container::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: 26px;
  /* Karte = die vom Veranstalter gewählte HINTERGRUNDFARBE als Vellum
     (Sebi 27.09.: Farbwahl muss auch hier wirken). color-mix macht sie
     leicht transluzent; Fallback davor = volle Farbe (alte Browser). */
  background: var(--bg, #fdfbf5);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 0.45 0 0 0 0 0.43 0 0 0 0 0.38 0 0 0 0.03 0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E"),
    color-mix(in srgb, var(--bg, #fdfbf5) 90%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: 0 30px 60px -28px rgba(40, 50, 44, 0.5);
}
@media (min-width: 480px) {
  body.guest-body[data-g-layout="signature"] main.guest-container { margin-inline: auto; }
}
/* Karten-Inhalte folgen den berechneten Design-Tokens (gast.js wählt
   Text-/Linienfarben passend zur gewählten Hintergrundfarbe, auch dunkel). */
body.guest-body[data-g-layout="signature"] main.guest-container {
  --card: color-mix(in srgb, var(--g-text, #2f3a38) 6%, transparent);
  color: var(--text);
}

/* Wachssiegel halb auf der Kartenkante (Hero beginnt nach 50px Karten-Padding
   → -97px = 47px über der Kante) */
body.guest-body[data-g-layout="signature"] .g-sig-seal {
  display: block;
  position: absolute;
  top: -45px;
  left: 50%;
  transform: translateX(-50%);
  width: 96px;
  height: 90px;
  filter: drop-shadow(0 8px 14px rgba(40, 50, 44, 0.38));
  z-index: 3;
}
body.guest-body[data-g-layout="signature"] .g-sig-seal canvas {
  width: 100%;
  height: 100%;
  display: block;
  transform: rotate(-3deg);
}
body.guest-body[data-g-layout="signature"] .g-sig-seal__mono {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  font-size: 21px;
  color: #f6efe3;
  text-shadow: 0 1px 2px rgba(30, 40, 34, 0.55);
  transform: translateY(-3px);
}
body.guest-body[data-g-layout="signature"] .g-sig-seal__mono svg {
  width: 8px;
  height: 8px;
  margin-top: 2px;
}

/* Hero: zentrierte Karten-Ordnung; Standard-Titel/Deko/Profilfoto raus */
body.guest-body[data-g-layout="signature"] .guest-hero {
  position: static;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 0;
}
body.guest-body[data-g-layout="signature"] .guest-hero__title,
body.guest-body[data-g-layout="signature"] .guest-hero__laurel,
body.guest-body[data-g-layout="signature"] .guest-hero__photo,
body.guest-body[data-g-layout="signature"] .guest-hero__event { display: none; }
body.guest-body[data-g-layout="signature"] .guest-hero__eyebrow { order: 1; }
body.guest-body[data-g-layout="signature"] .g-sig-name { order: 2; }
body.guest-body[data-g-layout="signature"] #heroDate { order: 3; }
body.guest-body[data-g-layout="signature"] #heroAlbum { order: 4; }
body.guest-body[data-g-layout="signature"] .g-sig-heart { order: 5; }
body.guest-body[data-g-layout="signature"] .guest-hero__welcome { order: 6; }
body.guest-body[data-g-layout="signature"] .guest-hero__text { order: 7; }
body.guest-body[data-g-layout="signature"] .guest-hero__actions { order: 8; }
body.guest-body[data-g-layout="signature"] .guest-private-note { order: 9; }

/* Eyebrow mit Flankenlinien */
body.guest-body[data-g-layout="signature"] .guest-hero__eyebrow {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: 10px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-muted);
}
body.guest-body[data-g-layout="signature"] .guest-hero__eyebrow::before,
body.guest-body[data-g-layout="signature"] .guest-hero__eyebrow::after {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--line);
}

/* Namens-Lockup: Serifen zweizeilig, Kalligrafie-& sichtbar davor */
body.guest-body[data-g-layout="signature"] .g-sig-name {
  display: block;
  position: relative;
  margin: 12px 0 0;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 500;
  font-size: 46px;
  line-height: 1.18;
  color: var(--text);
}
body.guest-body[data-g-layout="signature"] .g-sig-name .g-sig-name__amp {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -54%);
  /* Klar lesbares Serifen-& (Cormorant) statt der historischen
     Pinyon-Ligatur, die niemand als "&" erkennt (Sebi, 27.09. abends). */
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 500;
  font-style: italic;
  font-size: 88px;
  line-height: 1;
  color: var(--accent);
  opacity: 0.6;
  pointer-events: none;
  z-index: 1;
}
/* Name ohne "&": normale einzeilige Größe */
body.guest-body[data-g-layout="signature"] .g-sig-name--single { font-size: 34px; line-height: 1.2; }

body.guest-body[data-g-layout="signature"] #heroDate {
  margin: 6px 0 0;
  font-size: 11.5px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--accent-dark);
}
body.guest-body[data-g-layout="signature"] #heroAlbum { margin: 4px 0 0; font-size: 12px; color: var(--text-muted); }
body.guest-body[data-g-layout="signature"] .g-sig-heart { display: block; margin: 8px 0 10px; color: var(--accent); }

body.guest-body[data-g-layout="signature"] .guest-hero__welcome,
body.guest-body[data-g-layout="signature"] .guest-hero__text {
  margin: 0 0 4px;
  max-width: 302px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-muted);
}
/* Eigener Einleitungstext ersetzt den Standardtext (gleiches Muster wie editorial) */
body.guest-body[data-g-layout="signature"] .guest-hero__welcome:not([hidden]) ~ .guest-hero__text { display: none; }

/* Buttons: Serifen-Pille in Akzentfarbe */
body.guest-body[data-g-layout="signature"] .guest-hero__actions { width: 100%; max-width: 316px; margin: 16px 0 0; display: grid; gap: 9px; }
body.guest-body[data-g-layout="signature"] .btn {
  border-radius: 999px;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  font-size: 18px;
  padding: 13px 18px;
}
body.guest-body[data-g-layout="signature"] .btn--outline { background: color-mix(in srgb, var(--bg, #fdfbf5) 55%, transparent); }
body.guest-body[data-g-layout="signature"] .guest-private-note { margin: 11px 0 0; font-size: 12px; }

/* Vertrauens-Badges: schlanke Caps-Zeile statt Karte */
body.guest-body[data-g-layout="signature"] .guest-badges {
  background: transparent;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
  margin-top: 16px;
  padding: 12px 0 0;
  display: flex;
  justify-content: center;
  gap: 6px 16px;
  flex-wrap: wrap;
}
body.guest-body[data-g-layout="signature"] .guest-badge { display: flex; align-items: center; gap: 6px; }
body.guest-body[data-g-layout="signature"] .guest-badge svg { width: 13px; height: 13px; color: var(--accent); }
body.guest-body[data-g-layout="signature"] .guest-badge__title {
  margin: 0;
  font-size: 9.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-muted);
}

/* Innen-Karten (Upload, Galerie …) weich auf dem Vellum */
body.guest-body[data-g-layout="signature"] main.guest-container .card:not(.guest-badges) {
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: none;
}
body.guest-body[data-g-layout="signature"] .guest-badge { flex: 0 0 auto; }
body.guest-body[data-g-layout="signature"] .btn--outline { color: var(--text); }

/* Signature: Footer (außerhalb der Karte) lesbar auf dem Foto – eigene kleine
   Vellum-Pille statt nackter Text auf dem Hintergrundbild. */
body.guest-body[data-g-layout="signature"] .guest-footer {
  position: relative;
  max-width: 430px;
  margin: 0 22px 20px;
  padding: 14px 16px;
  border-radius: 18px;
  background: color-mix(in srgb, var(--bg, #fdfbf5) 82%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid color-mix(in srgb, #ffffff 55%, transparent);
  color: var(--text-muted);
}
@media (min-width: 480px) {
  body.guest-body[data-g-layout="signature"] .guest-footer { margin-inline: auto; }
}

/* Live-Vorschau im iPhone-Rahmen: dort schiebt .guest-preview die Nav ~44px
   tiefer (Safe-Area-Ersatz) – die Signature-Karte rückt entsprechend nach
   unten, sonst läge die Marke auf der Kartenkante. Echte Gäste: unverändert. */
body.guest-body.guest-preview[data-g-layout="signature"] main.guest-container {
  margin-top: 150px;
}

/* ---------- Snap Signature · Desktop (Sebis Laptop-Mockup 27.09.) ----------
   Breite Karte statt Handy-Spalte, Name EINZEILIG mit Serifen-& in Akzent,
   Buttons nebeneinander. Handy-Look bleibt exakt wie abgenommen. */
@media (min-width: 900px) {
  body.guest-body[data-g-layout="signature"] main.guest-container {
    max-width: 880px;
    margin-top: 110px;
    padding: 58px 48px 26px;
  }
  body.guest-body[data-g-layout="signature"] .guest-footer { max-width: 880px; }
  /* Namens-Lockup: eine Zeile, & als ruhiges Serifen-Zeichen in Akzentfarbe */
  body.guest-body[data-g-layout="signature"] .g-sig-name {
    font-size: 64px;
    line-height: 1.1;
  }
  body.guest-body[data-g-layout="signature"] .g-sig-name br { display: none; }
  body.guest-body[data-g-layout="signature"] .g-sig-name .g-sig-name__amp {
    position: static;
    transform: none;
    font-family: "Cormorant Garamond", Georgia, serif;
    font-weight: 400;
    font-size: 0.92em;
    opacity: 1;
    color: var(--accent);
    padding: 0 14px;
  }
  body.guest-body[data-g-layout="signature"] .guest-hero__welcome,
  body.guest-body[data-g-layout="signature"] .guest-hero__text {
    max-width: 560px;
    font-size: 15px;
  }
  /* Buttons nebeneinander, zentriert */
  body.guest-body[data-g-layout="signature"] .guest-hero__actions {
    max-width: none;
    grid-template-columns: repeat(2, 250px);
    justify-content: center;
    gap: 14px;
  }
  /* Eyebrow-/Badge-Flankenlinien etwas länger, wie im Mockup */
  body.guest-body[data-g-layout="signature"] .guest-hero__eyebrow::before,
  body.guest-body[data-g-layout="signature"] .guest-hero__eyebrow::after { width: 120px; }
}

/* Signature auf DUNKLER Kartenfarbe: Datum/&/Herz einen Tick heller
   (accent-dark wäre auf Schwarz zu dunkel). */
body.guest-body[data-g-layout="signature"][data-g-scheme="dark"] #heroDate,
body.guest-body[data-g-layout="signature"][data-g-scheme="dark"] .g-sig-heart {
  color: var(--accent);
  filter: brightness(1.35);
}
body.guest-body[data-g-layout="signature"][data-g-scheme="dark"] .g-sig-name .g-sig-name__amp {
  filter: brightness(1.4);
}

/* ============================================================
   Tab-Bar-Umbau, Gäste-Seite (Etappe 2, 28.09.2026)
   Views statt One-Pager (body[data-g-view] + [hidden] auf den
   data-g-page-Sektionen, gast.js setGuestView/viewFromHash), schwebende
   Pillen-Tab-Bar (mobil) bzw. zentrierte Leiste unter dem Inhalt (Desktop),
   Upload-Bereich als aufschiebbares Bottom-Sheet. Additiv: greift für ALLE
   vier Layouts gleich, keine Regel hier hängt an data-g-layout.
   ============================================================ */

/* --- Views: sanfter Fade beim Wechsel, reduced-motion-sicher ---
   WICHTIG: KEIN "both"/forwards-Fill. Ein forwards-füllender Opacity-Fade
   hält in Chromium dauerhaft einen Stacking-Context auf der Section – der
   das fixierte Signature-Titelfoto (position:fixed, z-index:-2) ÜBER die
   Vellum-Creme (main::before, z-index:-1) hob → Foto schlug durch, Text
   unlesbar (28.09.2026 gefunden). Ohne Fill endet der Fade auf der
   natürlichen Ruhe-Deckkraft 1, der Stacking-Context fällt weg. */
body.guest-body [data-g-page] {
  animation: g-view-fade 0.22s ease;
}
@keyframes g-view-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  body.guest-body [data-g-page] { animation: none; }
}

/* Platz für die schwebende Tab-Bar reservieren, sonst verdeckt sie die
   letzte Zeile von Aufgaben-Karte/Galerie/Fußzeile. Nur mobil (Desktop-Leiste
   liegt weiter unten im normalen Fluss, kein Fixed-Overlay, siehe unten). */
@media (max-width: 760px) {
  body.guest-body { padding-bottom: calc(94px + env(safe-area-inset-bottom)); }
}

/* --- Tab-Bar: schwebende Pille (mobil) --- */
body.guest-body .g-tabbar {
  position: fixed;
  left: 50%;
  bottom: calc(14px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  width: min(420px, calc(100% - 28px));
  z-index: 55; /* unter Melde-Dialog (60)/Toast (100)/Lightbox (1000) */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  padding: 7px 10px;
  border-radius: 999px;
  background: var(--card, #fff);
  border: 1px solid var(--line);
  box-shadow: 0 18px 40px -16px rgba(20, 26, 24, 0.4), 0 2px 10px rgba(20, 26, 24, 0.08);
}
body.guest-body .g-tabbar__btn {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 600;
  padding: 6px 4px;
  border-radius: 999px;
  cursor: pointer;
}
body.guest-body .g-tabbar__btn[aria-current="page"] {
  color: var(--accent-dark, var(--accent));
}
body.guest-body .g-tabbar__ic {
  position: relative;
  display: inline-flex;
  line-height: 0;
  margin-bottom: 1px;
}
body.guest-body .g-tabbar__label {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.guest-body .g-tabbar__badge {
  position: absolute;
  top: -6px;
  right: -11px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--g-btn-text, #fff);
  font-size: 9.5px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  white-space: nowrap;
}

/* Mittiger ＋-FAB: erhöht über die Pille, Creme-Ring (= var(--card), passt
   sich damit Hell-/Dunkelschema automatisch an, genau wie die Pille selbst). */
body.guest-body .g-tabbar__fab {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  margin-top: -30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 5px solid var(--card, #fff);
  background: var(--accent);
  color: var(--g-btn-text, #fff);
  box-shadow: 0 12px 26px -8px rgba(20, 26, 24, 0.5);
  cursor: pointer;
}
body.guest-body .g-tabbar__fab:hover { background: var(--accent-dark); }
body.guest-body .g-tabbar__fab:focus-visible,
body.guest-body .g-tabbar__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Einmalige Puls-Animation beim Erstbesuch (gast.js maybePulseFab, reduced-
   motion-sicher: dort wird die Klasse gar nicht erst gesetzt). */
@keyframes g-fab-pulse {
  0%, 100% { box-shadow: 0 12px 26px -8px rgba(20, 26, 24, 0.5), 0 0 0 0 color-mix(in srgb, var(--accent) 55%, transparent); }
  50% { box-shadow: 0 12px 26px -8px rgba(20, 26, 24, 0.5), 0 0 0 12px color-mix(in srgb, var(--accent) 0%, transparent); }
}
body.guest-body .g-tabbar__fab.g-fab--pulse {
  animation: g-fab-pulse 1.5s ease-out 2;
}

/* delivery-only: kein ＋-FAB (kein Upload) – Start/Galerie bleiben, mittig verteilt. */
body.guest-body.g-no-fab .g-tabbar__fab { display: none; }
body.guest-body.g-no-fab .g-tabbar { justify-content: space-evenly; gap: 20px; }

/* Signature-Layout: die Bar liegt über der Vellum-Karte (::before, z:-1) –
   sie ist ein Geschwister von main.guest-container mit z-index:55, das
   reicht ohne weitere Regel (main hat keine eigene Stacking-Isolation). */

/* --- Desktop: keine schwebende Pille, sondern eine zentrierte Leiste
   UNTER dem Inhalt (normaler Fluss statt Fixed-Overlay über der Karte). --- */
@media (min-width: 761px) {
  body.guest-body .g-tabbar {
    position: static;
    left: auto;
    bottom: auto;
    transform: none;
    width: min(420px, 100%);
    margin: 28px auto 40px;
  }
}

/* --- Upload-Bottom-Sheet --- */
body.guest-body .g-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 57;
  background: rgba(20, 26, 24, 0.42);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
body.guest-body.g-sheet-open .g-sheet-backdrop {
  opacity: 1;
  pointer-events: auto;
}

body.guest-body #uploadSection.g-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 58;
  max-height: min(86vh, 720px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--card, #fff);
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -20px 50px -20px rgba(20, 26, 24, 0.5);
  padding: 8px 18px calc(18px + env(safe-area-inset-bottom));
  margin: 0; /* überschreibt keine .card-Regel, #uploadSection ist keine .card */
  transform: translateY(100%);
  visibility: hidden;
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1), visibility 0s linear 0.28s;
}
body.guest-body.g-sheet-open #uploadSection.g-sheet {
  transform: translateY(0);
  visibility: visible;
  transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1), visibility 0s linear 0s;
}
@media (prefers-reduced-motion: reduce) {
  body.guest-body #uploadSection.g-sheet,
  body.guest-body .g-sheet-backdrop {
    transition: none;
  }
}

body.guest-body .g-sheet__bar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 26px;
  margin: 0 0 4px;
  cursor: grab;
  touch-action: none; /* Ziehen tracken, ohne dass die Seite darunter scrollt */
}
body.guest-body .g-sheet__handle {
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: var(--line);
}
body.guest-body .g-sheet__close {
  position: absolute;
  top: -3px;
  right: -6px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
body.guest-body .g-sheet__close:hover { background: var(--band); color: var(--text); }
body.guest-body .g-sheet__close:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Desktop: Sheet als zentriertes, allseitig gerundetes Panel statt
   randständigem Bottom-Sheet – Drag&Drop im Dropzone-Feld bleibt unverändert
   erhalten (gleiche IDs/Listener, nur die Hülle ändert sich). */
@media (min-width: 761px) {
  body.guest-body #uploadSection.g-sheet {
    left: 50%;
    right: auto;
    bottom: 24px;
    transform: translate(-50%, 130%);
    width: min(480px, calc(100% - 48px));
    max-height: min(80vh, 640px);
    border-radius: 22px;
  }
  body.guest-body.g-sheet-open #uploadSection.g-sheet {
    transform: translate(-50%, 0);
  }
}

/* Nav-Rückkehr in der Galerie-Ansicht (hero/editorial), bewusst GANZ am
   Dateiende: die weiße/absolute Nav-Optik weiter oben ist an
   [data-g-hero-photo="on"] gebunden (bleibt "on", auch wenn die Start-Sektion
   mit dem Foto gerade hidden ist) – bei gleicher Selektor-Spezifität
   entscheidet die Reihenfolge im Stylesheet, darum steht die Umkehr hier
   zuletzt. In der Galerie-Ansicht ist die Start-Sektion (inkl. Foto/Scrim)
   komplett hidden – ohne diese Regel stünde die weiße Marke unlesbar auf dem
   hellen Seitengrund über dem Galerie-Titel. Der Event-Name (sonst dauerhaft
   im Hero, hier nirgends sichtbar) erscheint dafür wieder rechts wie im
   Standard-Layout. */
body.guest-body[data-g-layout="hero"][data-g-view="galerie"] .topnav,
body.guest-body[data-g-layout="editorial"][data-g-view="galerie"] .topnav {
  position: static;
  background: var(--card, #fff);
  border-bottom: 1px solid var(--line);
}
body.guest-body[data-g-layout="hero"][data-g-view="galerie"] .topnav .brand__logo,
body.guest-body[data-g-layout="editorial"][data-g-view="galerie"] .topnav .brand__logo {
  filter: none;
  opacity: 1;
}
body.guest-body[data-g-layout="hero"][data-g-view="galerie"] .topnav .brand__title,
body.guest-body[data-g-layout="editorial"][data-g-view="galerie"] .topnav .brand__title {
  color: var(--text);
}
body.guest-body[data-g-layout="hero"][data-g-view="galerie"] .topnav .brand__sub,
body.guest-body[data-g-layout="editorial"][data-g-view="galerie"] .topnav .brand__sub {
  color: var(--accent);
}
body.guest-body[data-g-layout="hero"][data-g-view="galerie"] .guest-eventname,
body.guest-body[data-g-layout="editorial"][data-g-view="galerie"] .guest-eventname {
  display: block;
}

/* Dashboard-Live-Vorschau (?preview=1, iframe im Design-Tab): geprüft per
   Playwright, dass eine per CSS transform:scale() verkleinerte Tab-Bar
   (position:fixed) im iframe teils GAR NICHT gemalt wird (Compositing-
   Eigenheit skalierter iframes, kein Bug unserer Regeln). Statt einer u. U.
   halb/nicht sichtbaren Bar zeigt die Vorschau darum bewusst NUR die
   Start-Ansicht ohne Bar (genau der in der Aufgabenstellung vorgesehene
   Rückfallweg) – der eigentliche Vorschau-Zweck (Layout/Farben zeigen)
   bleibt so garantiert erhalten. Echte Gäste (ohne preview=1) unberührt. */
body.guest-body.guest-preview .g-sheet-backdrop,
body.guest-body.guest-preview #uploadSection.g-sheet {
  display: none;
}
/* Tab-Bar in der Vorschau ZEIGEN (die Aktionen leben seit dem Umbau dort),
   fixed wie im Echtbetrieb – sitzt am unteren Telefon-Rand. */
