/* ============================================================================
   GSv2 Design-Layer — DIE EINE CSS fuer ALLE Produkte (gsv2_core.assets).
   Ein <link> pro Seite:  <link rel="stylesheet" href="/gsv2-assets/css/gsv2.css">
   Produkt-CSS layert danach NUR Extras. Sektionen unten in Kaskaden-Reihenfolge:
   Tokens -> Base (body-Fundament) -> Buttons -> Effekte -> Layout (Navbar/Footer)
   -> Legal (Rechtstexte, gerendert von gsv2_core.legal).
   ============================================================================ */


/* ==================== tokens ==================== */
/* ===========================================================================
   GSv2 Design Tokens — DIE kanonische Quelle fürs Aussehen ALLER Produkte.
   Werte gespiegelt aus dem etablierten Kiksi-Branding (schwarz + soft-blue),
   damit Shop/kiksi/discover konsistent sind. Projekte ziehen das via
   gsv2_core.assets.mount_assets(app) und referenzieren /gsv2-assets/css/tokens.css.
   Projekt-spezifische Overrides layern lokal drüber — NIE hier hardcoden.
   =========================================================================== */
:root {
  /* Backgrounds */
  --gsv2-bg:            #000000;
  --gsv2-bg-2:          #0a0a0a;
  --gsv2-bg-3:          #141414;
  --gsv2-surface:       #0f0f0f;

  /* Accent — EINE Stellschraube. Alles andere leitet sich via color-mix() ab.
     Pro Produkt / pro Herkunft gesetzt (theme.js, Chamäleon — siehe farbschema.txt).
     Hier nur der Default-Fallback; theme.js überschreibt --gsv2-accent zur Laufzeit. */
  --gsv2-accent:        #c2cad8;   /* Direkt-Default = luminöses Silber (NICHT grau) — der farblose GSv2-Kern; theme.js chamäleont auf Produktfarbe */
  --gsv2-accent-hover:  color-mix(in srgb, var(--gsv2-accent), white 28%);
  --gsv2-accent-2:      color-mix(in srgb, var(--gsv2-accent), black 16%);
  --gsv2-accent-glow:   color-mix(in srgb, var(--gsv2-accent), transparent 75%);

  /* Text */
  --gsv2-text:          #ffffff;
  --gsv2-text-muted:    #a8a8a8;
  --gsv2-text-dim:      #8a8a8a;

  /* Lines / Surfaces */
  --gsv2-border:        rgba(255, 255, 255, 0.08);
  --gsv2-border-strong: rgba(255, 255, 255, 0.16);

  /* Signature-Gradient (Headlines, Border-Beams, Primary-CTA) — aus Accent abgeleitet */
  --gsv2-gradient:      linear-gradient(135deg, var(--gsv2-accent) 0%, var(--gsv2-accent-hover) 100%);

  /* Status-Farben (Badges, Danger-Buttons, Warnhinweise) — bewusst NICHT vom
     Akzent abgeleitet: rot/gelb/grün müssen in jedem Produkt-Theme rot/gelb/grün sein */
  --gsv2-danger:        #e5484d;
  --gsv2-warning:       #f0b429;
  --gsv2-success:       #46a758;

  /* Radius / Motion / Font */
  --gsv2-radius:        16px;
  --gsv2-radius-sm:     9px;
  --gsv2-ease:          cubic-bezier(0.4, 0, 0.2, 1);
  /* Geist — distinktiv-modern (Dev-Tool-/Vercel-Liga), NICHT Inter/Roboto/system */
  --gsv2-font:          'Geist', 'Geist Sans', ui-sans-serif, sans-serif;
}

/* ===========================================================================
   Custom Scrollbar — dezent, auf-Theme (statt dem weißen System-Scrollbar).
   Gilt global (Seite + Dropdowns). Firefox: scrollbar-width/-color; WebKit: ::-webkit.
   =========================================================================== */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--gsv2-border-strong) transparent;
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--gsv2-border-strong);
  border-radius: 999px;
  border: 2px solid var(--gsv2-bg);
}
::-webkit-scrollbar-thumb:hover {
  background: color-mix(in srgb, var(--gsv2-accent), transparent 45%);
}

/* ==================== base ==================== */
/* GSv2 Base — das Seiten-Fundament: die Tokens einmal aufs Dokument angewendet
   (schwarzer Grund, Font, Textfarbe) statt pro Produkt dupliziert (DRY).
   Sticky-Footer inklusive: body = flex-Spalte, <main> füllt die Resthöhe →
   der Footer klebt IMMER am Viewport-Boden, auch bei wenig Inhalt (Muster
   aus shop/website hierher zentralisiert). Produkt-CSS layert nur Extras. */

/* Reset — stand wortgleich in website/shop/chat/kiksi-os. BEWUSST der grobe
   `*`-Reset und nicht die feinere Variante: die Produkte sind seit jeher gegen
   diesen designt (Inputs/Buttons/Listen ohne Default-Padding). Eine "sauberere"
   Fassung wuerde in sechs Live-Produkten stillschweigend Abstaende aendern.
   Produkte duerfen ihre lokale Kopie loeschen — sie ist deckungsgleich.
   NICHT auf ::before/::after ausweiten: die Beam-Effekte (.gsv2-btn-beam,
   .gsv2-card-beam) bauen auf `inset:-1px; padding:1px` mit content-box —
   border-box wuerde den umlaufenden Rand in sich zusammenziehen. */
* { box-sizing: border-box; margin: 0; padding: 0; }

/* [hidden] muss JEDE display-Regel schlagen. Das UA-Stylesheet setzt nur ein
   schwaches `display:none` — sobald eine Komponente `display:flex/grid` mitbringt,
   bleibt das Element trotz hidden-Attribut sichtbar (real passiert: der Abo-Banner
   im Wallet liess sich nicht wegklicken). Deshalb hier hart, einmal fuer alle. */
[hidden] { display: none !important; }

body {
    margin: 0;
    background: var(--gsv2-bg);
    color: var(--gsv2-text);
    font-family: var(--gsv2-font);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

main {
    flex: 1 0 auto;
    width: 100%;
}

/* Inhaltsspalte — ZWEI benannte Breiten, nach SEITENTYP zu waehlen. Vorher hatte
   jedes Produkt seine eigene Zahl (720 im Shop, 760 im Wallet) ohne Begruendung.

   .gsv2-container       720px  Fokus & Lesen: Shop, Checkout, Login, Legal.
                                Eng ist hier Absicht — die Entscheidung soll nicht
                                zerfasern, und Zeilen ueber ~75 Zeichen liest
                                niemand gern.
   .gsv2-container-wide 1180px  Werkzeuge: Wallet, Admin, Dashboards. Daten und
                                Aktionen sollen nebeneinander sichtbar sein.

   BEIDE zentriert mit Deckel — ohne Deckel laufen Zeilen auf breiten Schirmen
   unlesbar auseinander. Wer die breite Stufe waehlt, muss die Flaeche auch
   NUTZEN (mehrspaltig): eine einzelne Spalte in 1180px ist nur eine schmale
   Spalte in einem groesseren leeren Feld.
   --gsv2-container-w bleibt als Feinjustierung fuer Sonderfaelle. */
.gsv2-container {
    width: min(var(--gsv2-container-w, 720px), 100%);
    margin-inline: auto;
    padding: clamp(3rem, 8vw, 5.5rem) clamp(1.2rem, 5vw, 1.5rem) 5rem;
}
/* Werkzeuge starten naeher an der Navbar: sie haben keinen Seitentitel, der Luft
   braucht — die Daten sollen sofort sichtbar sein, ohne Scrollen. */
.gsv2-container-wide {
    --gsv2-container-w: 1180px;
    padding-top: clamp(1.8rem, 4vw, 2.6rem);
}

/* Reduzierte Bewegung respektieren — gilt fuer ALLE Layer-Animationen
   (Beam, Shine, Typing, Card-Hover) statt pro Produkt nachgeruestet. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ==================== buttons ==================== */
/* ===========================================================================
   GSv2 Buttons — geteilt über alle Produkte (gsv2_core Design-Layer).
   Pur CSS, kein Framework. Nutzt die Tokens aus tokens.css.
   =========================================================================== */
.gsv2-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.7rem 1.4rem;
  border-radius: var(--gsv2-radius-sm);
  font: 600 0.95rem/1 var(--gsv2-font);
  letter-spacing: 0.01em;
  color: var(--gsv2-text);
  background: var(--gsv2-bg-3);
  border: 1px solid var(--gsv2-border-strong);
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.15s var(--gsv2-ease),
              background 0.2s var(--gsv2-ease),
              border-color 0.2s var(--gsv2-ease),
              box-shadow 0.2s var(--gsv2-ease);
}
.gsv2-btn:hover  { transform: translateY(-1px); border-color: var(--gsv2-accent); }
.gsv2-btn:active { transform: translateY(0); }
.gsv2-btn:focus-visible { outline: 2px solid var(--gsv2-accent); outline-offset: 2px; }

/* Primary — soft-blue Signature-Gradient */
.gsv2-btn-primary {
  background: var(--gsv2-gradient);
  color: #06121f;
  border-color: transparent;
}
.gsv2-btn-primary:hover {
  box-shadow: 0 0 0 1px var(--gsv2-accent), 0 8px 30px var(--gsv2-accent-glow);
}

/* Glow — animierter Schein hinter dem Button (Magic-UI-Stil, pur CSS) */
.gsv2-btn-glow { position: relative; isolation: isolate; }
.gsv2-btn-glow::before {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: inherit;
  background: var(--gsv2-gradient);
  filter: blur(12px);
  opacity: 0.3;
  transition: opacity 0.3s var(--gsv2-ease);
}
.gsv2-btn-glow:hover::before { opacity: 0.85; }

/* Ghost — dezent, für sekundäre Aktionen */
.gsv2-btn-ghost {
  background: transparent;
  border-color: var(--gsv2-border);
  color: var(--gsv2-text-muted);
}
.gsv2-btn-ghost:hover { color: var(--gsv2-text); border-color: var(--gsv2-accent); }
/* Gedrueckt: fuer Wahl-Gruppen (eine Option von mehreren). Der Zustand haengt
   am Attribut, nicht an einer Klasse — Vorlesesoftware liest ihn so mit. */
.gsv2-btn-ghost[aria-pressed="true"] {
  color: var(--gsv2-text);
  border-color: var(--gsv2-accent);
  background: color-mix(in srgb, var(--gsv2-accent), transparent 88%);
}

/* Small — kompakte Buttons für Tabellenzeilen / Toolbars (Admin-Flächen) */
.gsv2-btn-sm {
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
  border-radius: var(--gsv2-radius-sm);
}

/* Danger — destruktive Aktionen (löschen, deaktivieren). Ghost-Grundform,
   damit Tabellen nicht rot schreien; Vollton erst beim Hover. */
.gsv2-btn-danger {
  background: transparent;
  border-color: color-mix(in srgb, var(--gsv2-danger), transparent 55%);
  color: var(--gsv2-danger);
}
.gsv2-btn-danger:hover {
  background: var(--gsv2-danger);
  border-color: var(--gsv2-danger);
  color: #fff;
}

/* Close — das "X" an Bannern, Dialogen, Hinweisen. Bewusst KEIN .gsv2-btn:
   ein Schliessen-Kreuz soll wie Text wirken, nicht wie eine Handlungsflaeche —
   sonst konkurriert es mit dem eigentlichen Button daneben.
   Lag vorher lokal im Wallet (.wallet-nudge-close), wird aber ueberall gebraucht. */
.gsv2-btn-close {
  background: none;
  border: none;
  padding: 0 0.2rem;
  line-height: 1;
  font-size: 1.25rem;
  color: var(--gsv2-text-dim);
  cursor: pointer;
  transition: color 0.2s var(--gsv2-ease);
}
.gsv2-btn-close:hover { color: var(--gsv2-text); }
.gsv2-btn-close:focus-visible { outline: 2px solid var(--gsv2-accent); outline-offset: 2px; }

/* Beam — derselbe rotierende Rand wie .gsv2-card-beam (effects.css), aber NUR beim
   Hover ein-/ausgeblendet (Karte = permanent, Button = on-hover). Nutzt die globale
   gsv2-beam-Animation + --gsv2-beam-angle aus effects.css. */
.gsv2-btn-beam { position: relative; }
.gsv2-btn-beam::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--gsv2-beam-angle, 0deg),
              transparent 0deg, var(--gsv2-accent) 60deg, transparent 120deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: gsv2-beam 4s linear infinite;
  /* Unsichtbar = angehalten: ein Rand mit opacity 0 muss sich nicht drehen,
     sonst zeichnet der Browser ihn trotzdem in jedem Frame neu. */
  animation-play-state: paused;
  opacity: 0;
  transition: opacity 0.3s var(--gsv2-ease);
  pointer-events: none;
}
.gsv2-btn-beam:hover::before { opacity: 1; animation-play-state: running; }

/* ==================== effects ==================== */
/* ===========================================================================
   GSv2 Signature-Effekte — geteilt (gsv2_core Design-Layer). Pur CSS/Keyframes,
   inspiriert von Magic UI / Aceternity, aber framework-frei (kein React).
   =========================================================================== */

/* --- Animierte Gradient-Headline -------------------------------------------- */
.gsv2-headline {
  font: 800 clamp(2.2rem, 6vw, 4.2rem)/1.05 var(--gsv2-font);
  letter-spacing: -0.02em;
  background: linear-gradient(100deg, #ffffff 0%, var(--gsv2-accent) 45%, var(--gsv2-accent-hover) 60%, #ffffff 100%);
  background-size: 200% auto;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: gsv2-shine 6s linear infinite;
}
@keyframes gsv2-shine { to { background-position: 200% center; } }

/* --- Badge auf einer Karte ("Best value", "Neu", ...) -----------------------
   Sitzt auf der Oberkante der Karte, mittig. Lag lokal im Shop (.product-badge);
   sobald ein zweites Produkt eine Karte hervorheben will, gehoert es hierher.
   Die Karte darunter braucht `position: relative` — .gsv2-card hat das bereits. */
.gsv2-badge {
  position: absolute;
  top: -13px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  z-index: 3;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #06121f;
  background: var(--gsv2-gradient);
  border: 1px solid color-mix(in srgb, var(--gsv2-accent), transparent 35%);
  padding: 0.34rem 0.85rem;
  border-radius: 999px;
  box-shadow: 0 8px 22px -8px var(--gsv2-accent-glow);
}

/* --- Card mit umlaufendem Border-Beam --------------------------------------- */
.gsv2-card {
  position: relative;
  background:
    radial-gradient(120% 80% at 50% -10%, color-mix(in srgb, var(--gsv2-accent), transparent 94%), transparent 60%),
    linear-gradient(180deg, #121214 0%, #0b0b0d 100%);
  border: 1px solid var(--gsv2-border);
  border-radius: var(--gsv2-radius);
  padding: 1.9rem;
  overflow: hidden;
  box-shadow: 0 1px 0 0 rgba(255,255,255,0.04) inset, 0 24px 60px -30px rgba(0,0,0,0.9);
  transition: transform 0.25s var(--gsv2-ease), border-color 0.25s var(--gsv2-ease),
              box-shadow 0.25s var(--gsv2-ease);
}
.gsv2-card:hover {
  transform: translateY(-3px);
  border-color: var(--gsv2-border-strong);
  box-shadow: 0 1px 0 0 rgba(255,255,255,0.05) inset, 0 30px 70px -28px rgba(0,0,0,0.95),
              0 0 0 1px color-mix(in srgb, var(--gsv2-accent), transparent 92%);
}
/* Magic-Card: Akzent-Glow folgt dem Cursor INNERHALB der Karte (Aceternity-Stil) */
.gsv2-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.35s var(--gsv2-ease);
  background: radial-gradient(260px circle at var(--card-x, 50%) var(--card-y, 50%),
              color-mix(in srgb, var(--gsv2-accent), transparent 86%), transparent 65%);
}
.gsv2-card:hover::after { opacity: 1; }
.gsv2-card-beam::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--gsv2-beam-angle, 0deg),
              transparent 0deg, var(--gsv2-accent) 60deg, transparent 120deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: gsv2-beam 4s linear infinite;
}
@property --gsv2-beam-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@keyframes gsv2-beam { to { --gsv2-beam-angle: 360deg; } }
/* Dauerlaeufer (Beam, Shine) ausserhalb des Bildes: angehalten. effects.js setzt
   die Klasse per IntersectionObserver — was niemand sieht, kostet nichts. */
.gsv2-offscreen, .gsv2-offscreen::before { animation-play-state: paused; }

/* --- Typing-Caret (blinkt während getippt wird) ----------------------------- */
.gsv2-typing::after {
  content: "▍";
  margin-left: 1px;
  color: var(--gsv2-accent);
  animation: gsv2-caret 1s step-end infinite;
}
@keyframes gsv2-caret { 50% { opacity: 0; } }

/* --- Eingabefelder ---------------------------------------------------------
   Auf Schwarz gehoert ein Feld nicht heller, sondern TIEFER als der Grund —
   sonst leuchtet jedes Formular wie ein Fremdkoerper zwischen den Karten.
   Fokus zeigt der Akzent, nicht der Browser-Default (der ist blau und
   ignoriert das Chamaeleon). */
.gsv2-input {
  width: 100%;
  padding: 0.7rem 0.9rem;
  border-radius: var(--gsv2-radius-sm);
  background: var(--gsv2-bg);
  border: 1px solid var(--gsv2-border-strong);
  color: var(--gsv2-text);
  font: 500 0.95rem/1.4 var(--gsv2-font);
  transition: border-color 0.2s var(--gsv2-ease), box-shadow 0.2s var(--gsv2-ease);
}
.gsv2-input::placeholder { color: var(--gsv2-text-dim); }
.gsv2-input:hover { border-color: color-mix(in srgb, var(--gsv2-accent), transparent 55%); }
.gsv2-input:focus {
  outline: none;
  border-color: var(--gsv2-accent);
  box-shadow: 0 0 0 3px var(--gsv2-accent-glow);
}
.gsv2-input:disabled { opacity: 0.5; cursor: not-allowed; }
/* Monospace-Variante fuer Codes/Keys — Ziffern und Buchstaben gleich breit,
   damit ein 16-stelliger Key beim Tippen nicht springt. */
.gsv2-input-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0.08em;
}

/* --- Modal ------------------------------------------------------------------
   Steuerung ueber das native [hidden]-Attribut (wie .gsv2-lang-menu), NICHT
   ueber eine .active-Klasse: ein Element, das versteckt ist, soll das auch
   fuer Screenreader und fuers DOM sein. */
.gsv2-modal[hidden] { display: none; }
/* Der Schleier ueber der Seite — EINE Abdunklung, zwei Traeger: das Modal
   (dialog.js, Wallet) und der Vorhang hinter dem offenen Marken-Menü. */
.gsv2-modal,
.gsv2-veil {
  background: rgba(0, 0, 0, 0.72);
}
.gsv2-modal {
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
/* Hinter einem offenen Navbar-Menü (Marke, Nutzer) wird der INHALT
   weichgezeichnet, nicht der Vorhang:
   ein backdrop-filter wird in jedem gezeichneten Frame neu angewendet — solange
   das Dreieck sich bewegt, hiesse das dreissigmal pro Sekunde ein Blur ueber die
   ganze Seite. Ein `filter` auf dem stillstehenden Inhalt wird einmal gerastert
   und danach als fertige Ebene wiederverwendet. Blur und Abdunklung kommen so
   gleichzeitig, ohne pro Frame zu kosten. Ausgenommen: die Leiste selbst, der
   Vorhang, Toasts und ein offenes Modal — alles direkte Kinder des <body>. */
body.gsv2-menu-open > :not(.gsv2-navbar):not(.gsv2-veil):not(.gsv2-toasts):not(.gsv2-modal) {
  filter: blur(5px);
}
.gsv2-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.2rem;
  animation: gsv2-modal-in 0.2s var(--gsv2-ease);
}
/* Vorhang hinter einem offenen Navbar-Menü: unter der Navbar (z 50), ueber allem anderen.
   Liegt im <body>, nicht in der Navbar — deren backdrop-filter macht sie zum
   Bezugsrahmen fuer fixierte Kinder, der Vorhang bliebe sonst in der Leiste.
   BEWUSST OHNE Ueberblendung: der Vorhang schaltet ([hidden]) und dunkelt nur
   ab; den Blur traegt der Inhalt (body.gsv2-menu-open, oben). */
.gsv2-veil {
  position: fixed;
  inset: 0;
  z-index: 45;
}
/* Die Box ist bewusst KEINE .gsv2-card: die Karte hebt sich bei Hover und laesst
   den Cursor-Glow wandern — auf einem Dialog, der ohnehin im Fokus steht, wirkt
   das unruhig. Gleiche Sprache (Radius, Rand, Tiefe), ohne die Interaktion. */
.gsv2-modal-box {
  width: min(440px, 100%);
  max-height: 85vh;
  overflow-y: auto;
  padding: 1.9rem;
  border-radius: var(--gsv2-radius);
  border: 1px solid var(--gsv2-border-strong);
  background: linear-gradient(180deg, #121214 0%, #0b0b0d 100%);
  box-shadow: 0 1px 0 0 rgba(255,255,255,0.04) inset, 0 40px 90px -30px rgba(0,0,0,0.95);
  animation: gsv2-modal-rise 0.25s var(--gsv2-ease);
}
@keyframes gsv2-modal-in   { from { opacity: 0; } }
@keyframes gsv2-modal-rise { from { opacity: 0; transform: translateY(14px); } }

/* Titel und Text eines Dialogs — in jedem Produkt gleich. */
.gsv2-modal-box > h3 { font-size: 1.1rem; font-weight: 600; }
.gsv2-modal-box > p  {
  margin-top: 0.5rem;
  color: var(--gsv2-text-muted);
  font-size: 0.9rem;
  line-height: 1.55;
}
/* Button-Zeile eines Dialogs — EINE Klasse fuer JEDES Modal (dialog.js, Wallet). */
.gsv2-modal-actions {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
  justify-content: center;
}
.gsv2-modal-actions .gsv2-btn { flex: 1; }

/* Rueckfragen + Hinweise (dialog.js). Titel und Text liegen schon als
   .gsv2-modal-box > h3 / > p vor — hier fehlt nur der Abstand zur Knopfreihe
   und das Verhalten, wenn einer von beiden fehlt (dann [hidden]). */
#gsv2-dialog .gsv2-modal-actions { margin-top: 1.4rem; }
#gsv2-dialog .gsv2-dialog-text { white-space: pre-line; }  /* \n aus dem Aufruf */
#gsv2-dialog [hidden] { display: none; }
/* --- Toast: kurze Rückmeldung am Bildschirmrand (toast.js) -------------------
   WANN TOAST UND WANN NICHT — die Trennlinie ist der ORT DER URSACHE, nicht die
   Schwere der Meldung:

     Am Ort der Handlung bleibt der FACHFEHLER — „not enough coins", „already
     entered". Er beantwortet, warum GENAU dieser Knopf gerade nichts tut, und
     gehört deshalb an den Knopf oder in die Statuszeile darüber (so macht es die
     Giveaway-Fläche, so der Redeem-Knopf im Wallet).

     In den Toast gehört die STÖRUNG — „bei uns klemmt gerade etwas". Sie hängt an
     keinem bestimmten Knopf, der Nutzer kann nichts dagegen tun, und sie darf ihm
     den Blick auf die Seite nicht verstellen. Ein modaler Dialog wäre hier zu
     schwer: Er verlangt eine Antwort auf eine Nachricht, auf die es keine gibt.

   Oben rechts statt unten mittig, weil unten die Eingaben liegen (Chat-Feld,
   Formular-Knöpfe) — eine Meldung, die den Absende-Knopf verdeckt, macht aus
   einem Hinweis ein Hindernis. Mehrere Toasts stapeln im Container, statt
   einander zu überlagern. */
.gsv2-toasts {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 10000;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  /* Der Container liegt über der ganzen Seite — ohne das hier fingen seine
     unsichtbaren Ränder Klicks ab, die dem Inhalt darunter gelten. */
  pointer-events: none;
  max-width: min(23rem, calc(100vw - 2rem));
}

.gsv2-toast {
  pointer-events: auto;   /* der Toast selbst ist bedienbar (Schließen-Knopf) */
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.8rem 0.9rem;
  background: var(--gsv2-surface);
  border: 1px solid var(--gsv2-border-strong);
  border-left: 3px solid var(--gsv2-accent);
  border-radius: 0.6rem;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  color: var(--gsv2-text);
  font-size: 0.88rem;
  line-height: 1.45;
  animation: gsv2-toast-in 0.2s var(--gsv2-ease);
}

/* Die Art steht in der Farbe der linken Kante — kein zusätzliches Wort wie
   „Error:" davor. Die Meldung sagt schon, was los ist; eine Beschriftung
   wiederholte sie nur (Root-CLAUDE.md, „UI-Texte"). */
.gsv2-toast--error   { border-left-color: var(--gsv2-danger); }
.gsv2-toast--success { border-left-color: var(--gsv2-success); }
.gsv2-toast--warning { border-left-color: var(--gsv2-warning); }

.gsv2-toast__text { flex: 1; min-width: 0; overflow-wrap: anywhere; }

.gsv2-toast__close {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0 0.15rem;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--gsv2-text-dim);
  cursor: pointer;
}
.gsv2-toast__close:hover { color: var(--gsv2-text); }

.gsv2-toast--leaving { animation: gsv2-toast-out 0.2s var(--gsv2-ease) forwards; }

@keyframes gsv2-toast-in {
  from { opacity: 0; transform: translateX(0.75rem); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes gsv2-toast-out {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(0.75rem); }
}

/* Wer Bewegung abgestellt hat, bekommt die Meldung ohne Flug — sie ist eine
   Information, keine Vorführung. */
@media (prefers-reduced-motion: reduce) {
  .gsv2-toast, .gsv2-toast--leaving { animation: none; }
}

/* --- Spotlight-Grid-Hintergrund (Cursor-folgender Glow auf dezentem Raster) --
   RESERVIERT für die gsv2.com-Hauptseiten-Überarbeitung (User-Entscheidung):
   bewusst NICHT auf der Shop-Seite verwendet (zu verspielt fürs Bezahlen), aber
   NICHT tot — bei gsv2.com einsetzen. Vor dem Löschen: GSv2.0/website fragen. */
.gsv2-grid-bg {
  position: relative;
  background-color: var(--gsv2-bg);
  background-image:
    linear-gradient(var(--gsv2-border) 1px, transparent 1px),
    linear-gradient(90deg, var(--gsv2-border) 1px, transparent 1px);
  background-size: 44px 44px;
}
.gsv2-grid-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(400px circle at var(--gsv2-spot-x, 50%) var(--gsv2-spot-y, 0%),
              var(--gsv2-accent-glow), transparent 70%);
  transition: background 0.1s var(--gsv2-ease);
}

/* ==================== layout ==================== */
/* ===========================================================================
   GSv2 Layout — geteilte Navbar + Footer (gsv2_core Design-Layer).
   NEU & produkt-agnostisch (NICHT die Kiksi-Navbar, die zu spezifisch ist).
   Pur CSS, nutzt die Tokens. JS-Injektion via layout.js.
   =========================================================================== */

/* --- Navbar ----------------------------------------------------------------- */
.gsv2-navbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem clamp(1.2rem, 5vw, 4rem);
  background: rgba(0, 0, 0, 0.7);
  /* Dauerhafter backdrop-filter kostet bei JEDEM Scroll-Frame — Radius klein halten. */
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--gsv2-border);
}
/* Anker des Marken-Menüs: es haengt am Logo, nicht an der Navbar. */
.gsv2-brand { position: relative; display: inline-flex; }

.gsv2-navbar-brand {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font: 800 1.35rem/1 var(--gsv2-font);
  letter-spacing: -0.01em;
  color: var(--gsv2-text);
  text-decoration: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: transform 0.3s var(--gsv2-ease);
}
/* Offenes Menü: die Marke waechst spuerbar (um ihre Mitte, damit das Dreieck
   darunter mittig bleibt) und das Logo glimmt im Akzent — so sagt sie selbst,
   dass ein zweiter Klick zur Firmenseite fuehrt. */
.gsv2-brand.is-open .gsv2-navbar-brand { transform: scale(1.12); }
.gsv2-brand.is-open .gsv2-brand-logo {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--gsv2-accent), transparent 30%),
              0 0 22px color-mix(in srgb, var(--gsv2-accent), transparent 55%);
}
/* Das Logo traegt die Marke mit — kleiner als die Wortmarke erkennt man es nicht.
   Selektor bewusst mit dem Elternteil: eine allgemeinere `img`-Regel an dieser
   Stelle hat die Logo-Groesse einmal still ueberstimmt. */
.gsv2-navbar-brand .gsv2-brand-logo {
  height: 40px;
  width: auto;
  border-radius: 50%;
}

/* --- Marken-Menü: das Produkt-Dreieck unter der Marke -----------------------
   Ein auf den Kopf gestelltes Dreieck, oben offen — dort steht die Marke selbst.
   Der Anker ist ein Punkt (0x0) mittig unter ihr; jeder Eintrag sitzt darauf und
   wird per translate auf seinen Platz geschoben, die Plaetze kommen als Faktoren
   aus layout.js. Breite und Hoehe sind getrennt: die Marke steht am Bildrand,
   deshalb wird das Dreieck bei wenig Platz SCHMALER (layout.js misst und setzt
   --gsv2-menu-spread), bleibt aber mittig — und behaelt seine Hoehe, damit die
   Beschriftung der oberen Ecken nicht in die Spitze laeuft. */
.gsv2-brandmenu {
  --gsv2-menu-spread: 67px;
  --gsv2-menu-drop: 92px;
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  width: 0;
  height: 0;
  z-index: 60;
}

.gsv2-brandmenu-item {
  position: absolute;
  top: -1.75rem;
  left: -2.25rem;
  width: 4.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  color: var(--gsv2-text-muted);
  font: 600 0.78rem/1.2 var(--gsv2-font);
  text-align: center;
  text-decoration: none;
  /* Das Menü liegt ueber dem Seiteninhalt; ein Saum haelt die Namen lesbar,
     wenn darunter Text steht. */
  text-shadow: 0 1px 4px #000, 0 0 12px #000;
  opacity: 0;
  transform: scale(0.35);
  pointer-events: none;
  transition: transform 0.34s var(--gsv2-ease), opacity 0.24s var(--gsv2-ease);
}
.gsv2-brand.is-open .gsv2-brandmenu-item {
  opacity: 1;
  transform: translate(calc(var(--gsv2-item-x) * var(--gsv2-menu-spread)),
                       calc(var(--gsv2-item-y) * var(--gsv2-menu-drop))) scale(1);
  transition-delay: var(--gsv2-item-delay);
  pointer-events: auto;
}
.gsv2-brandmenu-item:hover,
.gsv2-brandmenu-item:focus-visible { color: var(--gsv2-text); outline: none; }

/* Noch nicht erreichbar: sichtbar, aber ohne Ziel — deshalb auch ohne Zeiger. */
.gsv2-brandmenu-item.is-soon { pointer-events: none; }
.gsv2-brand.is-open .gsv2-brandmenu-item.is-soon { opacity: 0.55; }
.gsv2-brandmenu-soon {
  font-size: 0.62rem;
  font-weight: 500;
  white-space: nowrap;
  color: var(--gsv2-text-dim);
}

/* Die Kante laeuft von der oberen Ecke auf die Spitze zu. Sie verbindet die
   PRODUKTE miteinander — zur Marke hinauf gibt es keine Linie, dort ist das
   Dreieck offen. Beide Enden verschwinden unter den Punkten, die spaeter
   gezeichnet werden.
   NEUTRAL im Chamaeleon-Akzent, nicht in einer Produktfarbe: die Linie gehoert
   keinem der beiden Produkte an ihren Enden. */
.gsv2-brandmenu-item::before {
  content: "";
  position: absolute;
  top: 1.75rem;
  left: 50%;
  width: var(--gsv2-edge-length, 0px);
  height: 1px;
  background: color-mix(in srgb, var(--gsv2-accent), transparent 55%);
  transform-origin: 0 50%;
  transform: rotate(var(--gsv2-edge-angle, 0deg));
  opacity: 0;
  transition: opacity 0.2s var(--gsv2-ease);
}
.gsv2-brand.is-open .gsv2-brandmenu-item::before {
  opacity: 1;
  transition-delay: calc(var(--gsv2-item-delay) + 120ms);
}

/* Das Produktbild FUELLT den Kreis; Rand und Schein in der Produktfarbe liegen
   direkt am Bild, als glimme es selbst — kein Bild auf einer Scheibe. */
.gsv2-brandmenu-dot {
  position: relative;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid var(--gsv2-item-accent, var(--gsv2-border-strong));
  box-shadow: 0 0 16px color-mix(in srgb, var(--gsv2-item-accent, var(--gsv2-accent)), transparent 55%);
  transition: transform 0.2s var(--gsv2-ease);   /* der Schein schaltet, nur die Bewegung gleitet */
}
.gsv2-brandmenu-dot img { width: 100%; height: 100%; object-fit: cover; display: block; }

.gsv2-brandmenu-item:hover .gsv2-brandmenu-dot,
.gsv2-brandmenu-item:focus-visible .gsv2-brandmenu-dot {
  transform: translateY(-2px);
  box-shadow: 0 0 22px color-mix(in srgb, var(--gsv2-item-accent, var(--gsv2-accent)), transparent 35%);
}


.gsv2-navbar-brand .accent { color: var(--gsv2-accent); }
/* Wortmarke als EINE Einheit — kein abgetrenntes ".0" */
.gsv2-wordmark { font-weight: 800; letter-spacing: -0.02em; white-space: nowrap; }
.gsv2-wordmark .accent { color: var(--gsv2-accent); }
.gsv2-navbar-actions { display: flex; align-items: center; gap: 0.6rem; }

/* Icons in Navbar-Buttons (crisp SVG statt Emoji) */
.gsv2-btn svg { width: 15px; height: 15px; flex-shrink: 0; display: block; }
.gsv2-lang-btn .gsv2-chev { width: 10px; height: 10px; opacity: 0.55; }
.gsv2-lang-current { font-variant-numeric: tabular-nums; }

/* Dropdowns der Navbar — EIN Aussehen fuer das Sprachmenü und das Nutzermenü.
   Beide haengen rechts unter ihrem Knopf und schalten per [hidden]. */
.gsv2-lang, .gsv2-user { position: relative; }
.gsv2-lang-menu, .gsv2-usermenu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  width: 230px;
  max-height: 340px;
  overflow-y: auto;
  background: var(--gsv2-bg-2);
  border: 1px solid var(--gsv2-border-strong);
  border-radius: var(--gsv2-radius-sm);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 60;
  box-shadow: 0 20px 50px -20px rgba(0, 0, 0, 0.9);
}
.gsv2-lang-menu[hidden], .gsv2-usermenu[hidden] { display: none; }
.gsv2-lang-item, .gsv2-usermenu-item {
  text-align: left;
  padding: 8px 10px;
  border: none;
  background: transparent;
  color: var(--gsv2-text-muted);
  font: 500 0.9rem var(--gsv2-font);
  border-radius: 6px;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s var(--gsv2-ease), color 0.15s var(--gsv2-ease);
}
.gsv2-lang-item:hover, .gsv2-usermenu-item:hover {
  background: color-mix(in srgb, var(--gsv2-accent), transparent 88%);
  color: var(--gsv2-accent-hover);
  padding-left: 14px;   /* sanfter Slide nach rechts */
}
.gsv2-lang-item.active, .gsv2-usermenu-item.active { color: var(--gsv2-accent); font-weight: 600; }

/* Das Nutzermenü hat wenige Eintraege — die Hoehengrenze mit Scrollen gilt nur
   fuer die 104 Sprachen. */
.gsv2-usermenu { max-height: none; overflow: visible; }

/* Icon-Knoepfe der Navbar (Zurueck, Neu laden): quadratisch, ohne Text. */
.gsv2-refresh-btn, .gsv2-back-btn { padding: 0.7rem; }
/* Die linke Seite: Zurueck-Knopf und Marke nebeneinander. */
.gsv2-navbar-lead { display: flex; align-items: center; gap: 0.75rem; }

/* Nutzermenü: Profilbild als runder Knopf, Eintraege mit Icon, Abmelden rot. */
.gsv2-user-btn {
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid var(--gsv2-border-strong);
  border-radius: 50%;
  background: var(--gsv2-bg-3);
  cursor: pointer;
  overflow: hidden;
  display: grid;
  place-items: center;
  color: var(--gsv2-text);
  font: 700 0.95rem/1 var(--gsv2-font);
  transition: border-color 0.2s var(--gsv2-ease);
}
.gsv2-user-btn:hover,
.gsv2-user-btn[aria-expanded="true"] { border-color: var(--gsv2-accent); }
.gsv2-user-btn:focus-visible { outline: 2px solid var(--gsv2-accent); outline-offset: 2px; }
.gsv2-user-avatar { width: 100%; height: 100%; object-fit: cover; display: block; }
.gsv2-usermenu-name {
  padding: 8px 10px 6px;
  font-weight: 600;
  color: var(--gsv2-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gsv2-usermenu-item { display: flex; align-items: center; gap: 0.6rem; }
.gsv2-usermenu-item svg { width: 15px; height: 15px; flex-shrink: 0; }
.gsv2-usermenu-sep { height: 1px; margin: 4px 6px; background: var(--gsv2-border); }
.gsv2-usermenu-item.is-danger:hover {
  color: var(--gsv2-danger);
  background: color-mix(in srgb, var(--gsv2-danger), transparent 88%);
}

/* Sehr schmale Geraete (bis 384px): die Leiste behaelt JEDES Element und
   dieselbe Anordnung — nichts wird versteckt oder verschoben —, nur alles
   einen Tick kleiner. Ohne das lief die vollste Fassung (Zurueck, Marke,
   Sprache, Profilbild) bei 360px ueber den Rand und schnitt das Profilbild ab.
   Muss NACH allen Grundregeln der Leiste stehen: gleiche Spezifitaet, die
   spaetere Regel gewinnt. */
@media (max-width: 24rem) {
  .gsv2-navbar { padding-inline: 0.75rem; gap: 0.6rem; }
  .gsv2-navbar-lead { gap: 0.5rem; }
  .gsv2-navbar-actions { gap: 0.4rem; }
  .gsv2-navbar-brand { font-size: 1.2rem; gap: 0.45rem; }
  .gsv2-navbar-brand .gsv2-brand-logo { height: 34px; }
  .gsv2-lang-btn { padding-inline: 0.9rem; }
  .gsv2-refresh-btn, .gsv2-back-btn { padding: 0.6rem; }
  .gsv2-user-btn { width: 34px; height: 34px; }
}

/* --- Footer ----------------------------------------------------------------- */
.gsv2-footer {
  border-top: 1px solid var(--gsv2-border);
  background: var(--gsv2-bg-2);
  padding: 3rem clamp(1.2rem, 5vw, 4rem) 1.5rem;
  color: var(--gsv2-text-muted);
}
.gsv2-footer-main {
  display: flex;
  flex-wrap: wrap;
  gap: 2.5rem;
  justify-content: space-between;
  /* volle Breite (Seitenabstand kommt aus .gsv2-footer padding, wie die Navbar) */
}
.gsv2-footer-brand { max-width: 280px; }
.gsv2-footer-brand .logo {
  display: flex; align-items: center; gap: 0.5rem;
  font-weight: 800; font-size: 1.1rem; color: var(--gsv2-text);
}
.gsv2-footer-brand .logo img { height: 24px; }
.gsv2-footer-brand .logo .accent { color: var(--gsv2-accent); }
.gsv2-footer-tagline { margin-top: 0.7rem; font-size: 0.9rem; line-height: 1.6; }
.gsv2-footer-cols { display: flex; flex-wrap: wrap; gap: 2.5rem; }
.gsv2-footer-col h4 {
  color: var(--gsv2-text); font-size: 0.8rem; text-transform: uppercase;
  letter-spacing: 0.08em; margin-bottom: 0.8rem;
}
.gsv2-footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 0.5rem; }
.gsv2-footer-col a { color: var(--gsv2-text-muted); text-decoration: none; font-size: 0.9rem; transition: color 0.2s var(--gsv2-ease); }
.gsv2-footer-col a:hover { color: var(--gsv2-accent); }
/* Noch nicht erreichbares Produkt: steht in der Liste, aber gedimmt und ohne Link. */
.gsv2-footer-col .is-soon { color: var(--gsv2-text-dim); font-size: 0.9rem; }
.gsv2-footer-bottom {
  margin: 2.5rem 0 0; padding-top: 1.5rem;
  border-top: 1px solid var(--gsv2-border);
  display: flex; flex-wrap: wrap; gap: 0.8rem; justify-content: space-between;
  align-items: center; font-size: 0.85rem;
}
.gsv2-footer-bottom a { color: var(--gsv2-text-muted); text-decoration: none; }
.gsv2-footer-bottom a:hover { color: var(--gsv2-accent); }
.gsv2-footer-legal { display: flex; gap: 0.6rem; align-items: center; }
/* Kompakt (renderGsv2Footer({compact:true})): nur die untere Zeile, ohne den
   Abstand, den sie sonst zum Block darueber haelt. */
.gsv2-footer--compact { padding: 0.9rem clamp(1.2rem, 5vw, 4rem); }
.gsv2-footer--compact .gsv2-footer-bottom { margin: 0; padding-top: 0; border-top: 0; }

/* ==================== markdown ==================== */
/* Gerenderter Fliesstext (js/markdown.js). Die Wurzel traegt .gsv2-md; alles
   darunter sind normale Elemente — kein Produkt stylt sie noch einmal. Massstab
   ist, was ChatGPT und Claude gelernt haben: ruhiger Text, Code in einer Box mit
   Kopfzeile, Tabellen mit duennen Linien, Zitate mit Akzentkante. */
.gsv2-md { line-height: 1.65; overflow-wrap: anywhere; }
.gsv2-md > :first-child { margin-top: 0; }
.gsv2-md > :last-child  { margin-bottom: 0; }
.gsv2-md p, .gsv2-md ul, .gsv2-md ol, .gsv2-md blockquote,
.gsv2-md .gsv2-md-table, .gsv2-md .gsv2-md-code { margin: 0.75em 0; }
.gsv2-md h3, .gsv2-md h4, .gsv2-md h5, .gsv2-md h6 {
  margin: 1.3em 0 0.5em; line-height: 1.3; font-weight: 600; color: var(--gsv2-text);
}
.gsv2-md .gsv2-md-h1 { font-size: 1.35em; }
.gsv2-md .gsv2-md-h2 { font-size: 1.2em; }
.gsv2-md .gsv2-md-h3 { font-size: 1.08em; }
.gsv2-md .gsv2-md-h4 { font-size: 1em; }
.gsv2-md ul, .gsv2-md ol { padding-left: 1.5em; }
.gsv2-md li { margin: 0.25em 0; }
.gsv2-md li > ul, .gsv2-md li > ol { margin: 0.25em 0 0; }
.gsv2-md a { color: var(--gsv2-accent); text-decoration: none; }
.gsv2-md a:hover { text-decoration: underline; }
.gsv2-md hr { border: 0; border-top: 1px solid var(--gsv2-border); margin: 1.2em 0; }
.gsv2-md blockquote {
  padding: 0.2em 0 0.2em 1em;
  border-left: 3px solid var(--gsv2-accent);
  color: var(--gsv2-text-muted);
}
/* Inline-Code: leicht abgesetzt, nie fett, nie groesser als der Text. */
.gsv2-md code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9em;
}
.gsv2-md :not(pre) > code {
  padding: 0.12em 0.4em;
  border-radius: 5px;
  background: color-mix(in srgb, var(--gsv2-text), transparent 90%);
}
/* Codeblock: Kopfzeile mit Sprache und Kopieren, darunter der Code. Der Grund
   liegt TIEFER als die Flaeche (wie .gsv2-input) — Code ist Inhalt, kein Kasten. */
.gsv2-md-code {
  border: 1px solid var(--gsv2-border);
  border-radius: var(--gsv2-radius-sm);
  background: var(--gsv2-bg);
  overflow: hidden;
}
.gsv2-md-code-head {
  display: flex; align-items: center; justify-content: space-between; gap: 0.6rem;
  padding: 0.35rem 0.5rem 0.35rem 0.9rem;
  background: color-mix(in srgb, var(--gsv2-text), transparent 94%);
  border-bottom: 1px solid var(--gsv2-border);
  font-size: 0.78em; color: var(--gsv2-text-dim);
}
.gsv2-md-copy {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.25rem 0.55rem;
  background: none; border: 0; border-radius: 6px;
  font: inherit; color: var(--gsv2-text-muted); cursor: pointer;
  transition: background 0.15s var(--gsv2-ease), color 0.15s var(--gsv2-ease);
}
.gsv2-md-copy:hover { background: color-mix(in srgb, var(--gsv2-text), transparent 90%); color: var(--gsv2-text); }
.gsv2-md-copy.is-done { color: var(--gsv2-success); }
.gsv2-md-copy svg { width: 13px; height: 13px; }
.gsv2-md pre {
  margin: 0; padding: 0.9rem 1rem;
  overflow-x: auto;
  font-size: 0.88em; line-height: 1.55;
}
.gsv2-md pre code { padding: 0; background: none; font-size: 1em; }
/* Tabelle: scrollt bei Bedarf seitlich, statt das Layout zu sprengen. */
.gsv2-md-table { overflow-x: auto; }
.gsv2-md table { border-collapse: collapse; width: 100%; font-size: 0.93em; }
.gsv2-md th, .gsv2-md td {
  padding: 0.45em 0.8em; text-align: left; vertical-align: top;
  border: 1px solid var(--gsv2-border);
}
.gsv2-md th {
  font-weight: 600;
  background: color-mix(in srgb, var(--gsv2-text), transparent 94%);
}

/* ==================== appearance ==================== */
/* Das vom Nutzer gewaehlte Aussehen (gsv2_core.appearance) — greift NUR, wenn
   theme.js ein Wallpaper auf <html> gesetzt hat. Ohne Wallpaper aendert dieser
   Abschnitt NICHTS: kein backdrop-filter, keine Alpha-Flaeche, keine Kosten.
   Das ist Absicht (Root-CLAUDE.md, "Bewegung kostet"): Glas ueber Schwarz zeigt
   nichts und rechnet trotzdem bei jedem Scroll-Frame.

   Drei Attribute, drei Fragen:
     data-gsv2-wallpaper  welche Familie liegt (die FARBE kommt vom Chamaeleon)
     data-gsv2-look       wie stark das Bild durchs Glas kommt
     data-gsv2-scheme     ob der Inhalt hell oder dunkel ist */

/* Das Bild: fest hinter allem, ueber dem schwarzen Grund. `isolation` macht den
   body zum Stapel-Kontext, damit z-index:-1 das Bild HINTER den Inhalt legt,
   aber VOR den Body-Hintergrund — ohne das laege es unter dem Schwarz und
   bliebe unsichtbar. */
html[data-gsv2-wallpaper] body { isolation: isolate; }
html[data-gsv2-wallpaper] body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--gsv2-wallpaper) center / cover no-repeat;
  pointer-events: none;
}

/* Die Optik: drei Werte je Look. Die Deckkraften tragen auf JEDEM eigenen
   Wallpaper — die Familien sind so gebaut, dass keine Anhebung noetig ist
   (design-season/design-season.txt, "Die zwei Bedingungen"). Ein Wert unter
   0.30 waere auf hellem Grund unlesbar, einer ueber 0.78 zeigt kein Bild mehr. */
html[data-gsv2-look="clear"]   { --gsv2-glass-alpha: 0.30; --gsv2-glass-blur: 14px; --gsv2-glass-sat: 185%; }
html[data-gsv2-look="frosted"] { --gsv2-glass-alpha: 0.56; --gsv2-glass-blur: 26px; --gsv2-glass-sat: 170%; }
html[data-gsv2-look="dense"]   { --gsv2-glass-alpha: 0.78; --gsv2-glass-blur: 34px; --gsv2-glass-sat: 140%; }

/* Die Farbrollen des Inhalts. Dunkel ist der Normalfall und entspricht den
   Tokens; hell kippt sie ZUSAMMEN — Text, Linien, Glas und Akzent. */
html[data-gsv2-wallpaper] {
  --gsv2-glass-rgb: 10, 10, 12;
  --gsv2-accent-ink: var(--gsv2-accent);
}
html[data-gsv2-scheme="light"] {
  --gsv2-glass-rgb: 245, 246, 250;
  --gsv2-bg: #eef0f4;          /* Grund hinter dem Bild — sichtbar nur, wenn es nicht laedt */
  --gsv2-text: #14141a;
  --gsv2-text-muted: #4d4d59;
  --gsv2-text-dim: #6b6b78;
  --gsv2-border: rgba(0, 0, 0, 0.10);
  --gsv2-border-strong: rgba(0, 0, 0, 0.18);
  /* Der Akzent ist "auf Schwarz lesbar" abgeleitet (farbschema.txt) — auf hellem
     Glas erreicht Silber 1.5:1, Lime 1.2:1. Gerechnet statt gepflegt: derselbe
     Ton, abgedunkelt bis er traegt (alle vier ueber 6.5:1). theme.js setzt
     --gsv2-accent inline auf <html>, deshalb ein ABGELEITETER Token statt einer
     Ueberschreibung, die gegen inline verloere. */
  --gsv2-accent-ink: color-mix(in srgb, var(--gsv2-accent), #05050a 62%);
}

/* Karte und Navbar werden Glas: nur die zweite Ebene wechselt von deckend auf
   Alpha, der Akzent-Hauch bleibt. Die Navbar bekommt den Radius gedeckelt — sie
   liegt bei JEDEM Scroll-Frame ueber bewegtem Inhalt, die Karten nicht. */
html[data-gsv2-wallpaper] .gsv2-card {
  background:
    radial-gradient(120% 80% at 50% -10%, color-mix(in srgb, var(--gsv2-accent-ink), transparent 90%), transparent 60%),
    rgba(var(--gsv2-glass-rgb), var(--gsv2-glass-alpha));
  backdrop-filter: blur(var(--gsv2-glass-blur)) saturate(var(--gsv2-glass-sat));
  -webkit-backdrop-filter: blur(var(--gsv2-glass-blur)) saturate(var(--gsv2-glass-sat));
  border-color: var(--gsv2-border-strong);
}
html[data-gsv2-wallpaper] .gsv2-navbar {
  background: rgba(var(--gsv2-glass-rgb), var(--gsv2-glass-alpha));
  backdrop-filter: blur(min(var(--gsv2-glass-blur), 20px)) saturate(var(--gsv2-glass-sat));
  -webkit-backdrop-filter: blur(min(var(--gsv2-glass-blur), 20px)) saturate(var(--gsv2-glass-sat));
}

/* Textschutz: nur bei duennem Glas ueber dunklem Inhalt. Ein heller Schein um
   dunkle Schrift frisst die Buchstaben an, statt sie abzuheben — im hellen
   Schema deshalb nie. text-shadow vererbt sich, die Karte reicht. */
html[data-gsv2-look="clear"]:not([data-gsv2-scheme="light"]) .gsv2-card,
html[data-gsv2-look="clear"]:not([data-gsv2-scheme="light"]) .gsv2-navbar {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 14px rgba(0, 0, 0, 0.55);
}

/* Die Wortmarke traegt den Akzent als SCHRIFT — auf hellem Glas die Ableitung. */
html[data-gsv2-wallpaper] .gsv2-wordmark .accent,
html[data-gsv2-wallpaper] .gsv2-navbar-brand .accent { color: var(--gsv2-accent-ink); }


/* ==================== legal ==================== */
/* ===========================================================================
   Rechtstexte (Impressum/Datenschutz/AGB). Gerendert von gsv2_core.legal —
   die Klassen gehoeren zum Renderer, nicht zu einer Website, und liegen
   deshalb hier: sonst haengt das Aussehen davon ab, WELCHE Domain den Text
   ausliefert. Genau das war der Fall, solange .legal-content in der Website
   lag und .legal-table/.legal-note nirgends definiert waren — Tabellen und
   Hinweiskaesten der Datenschutzerklaerung rendeten roh.
   =========================================================================== */

.legal-content {
  max-width: 780px;
  margin: 0 auto;
  padding: 3.5rem clamp(1.2rem, 5vw, 2.5rem) 4.5rem;
}
.legal-content h1 {
  font-size: clamp(1.9rem, 4.5vw, 2.6rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin-bottom: 0.4rem;
}
.legal-content .legal-meta {
  display: block;
  font: 500 0.78rem var(--gsv2-font);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gsv2-text-dim);
  margin-bottom: 2.2rem;
}
.legal-content h2 {
  font-size: 1.25rem;
  font-weight: 700;
  margin: 2.2rem 0 0.7rem;
}
.legal-content h3 {
  font-size: 1.05rem;
  font-weight: 600;
  margin: 1.6rem 0 0.5rem;
}
.legal-content p,
.legal-content li {
  color: var(--gsv2-text-muted);
  margin-bottom: 0.8rem;
}
/* Die Anschrift kommt als EIN Absatz mit Zeilenumbruechen — ein Impressum
   ohne Zeilenumbruch in der Adresse liest sich wie ein Formfehler. */
.legal-content .legal-address { white-space: pre-line; }
.legal-content ul,
.legal-content ol { padding-inline-start: 1.4rem; margin-bottom: 0.8rem; }
.legal-content a { color: var(--gsv2-accent); text-decoration: none; }
.legal-content a:hover { color: var(--gsv2-accent-hover); text-decoration: underline; }

/* --- Hinweiskasten: die eine Aussage, die ein Leser mitnehmen soll ---------- */
.legal-note {
  margin: 1.4rem 0;
  padding: 1rem 1.2rem;
  background: var(--gsv2-surface);
  border: 1px solid var(--gsv2-border);
  border-inline-start: 3px solid var(--gsv2-accent);
  border-radius: var(--gsv2-radius-sm);
}
.legal-note strong {
  display: block;
  color: var(--gsv2-text);
  margin-bottom: 0.35rem;
}
.legal-note p:last-child { margin-bottom: 0; }

/* --- Tabellen: Aufbewahrungsfristen, Empfaenger, Rechtsgrundlagen ----------
   Der Wrapper scrollt, nicht die Seite: eine vierspaltige Empfaengertabelle
   passt auf keinem Telefon in die Breite, und eine quer scrollende SEITE
   verliert den Leser. */
.legal-table-wrap {
  overflow-x: auto;
  margin: 1rem 0 1.4rem;
  border: 1px solid var(--gsv2-border);
  border-radius: var(--gsv2-radius-sm);
}
.legal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
  min-width: 34rem;
}
.legal-table th,
.legal-table td {
  padding: 0.7rem 0.9rem;
  text-align: start;
  vertical-align: top;
  border-bottom: 1px solid var(--gsv2-border);
}
.legal-table th {
  color: var(--gsv2-text);
  font-weight: 600;
  background: var(--gsv2-bg-2);
  white-space: nowrap;
}
.legal-table td { color: var(--gsv2-text-muted); }
.legal-table tbody tr:last-child td { border-bottom: none; }

/* --- Begriff/Wert: Kontaktangaben, Registerdaten --------------------------- */
.legal-definitions {
  margin: 0.6rem 0 1.2rem;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1.2rem;
}
.legal-definitions dt { color: var(--gsv2-text-dim); }
.legal-definitions dd { color: var(--gsv2-text-muted); margin: 0; }
@media (max-width: 30rem) {
  .legal-definitions { grid-template-columns: 1fr; gap: 0.1rem; }
  .legal-definitions dd { margin-bottom: 0.6rem; }
}
