/* ============================================================
 * VPano Viewer Design Tokens
 * ------------------------------------------------------------
 * Single source of truth fuer das visuelle Look-and-Feel des
 * Standard-Panorama-Editors UND des Export/Public-Viewers.
 *
 * MUSS identisch sein mit:
 *   backend/src/templates/export-viewer/assets/viewer-tokens.css
 *
 * Pruefen: `node scripts/check-viewer-tokens.mjs`
 * ============================================================ */

:root,
.vp-light {
    color-scheme: light;

    --vp-glass-bg:        rgba(255, 255, 255, 0.82);
    --vp-glass-border:    rgba(15, 23, 42, 0.10);
    --vp-glass-shadow:    0 8px 32px rgba(0, 0, 0, 0.10);

    --vp-accent:          #0ea5e9;
    --vp-accent-strong:   #38bdf8;
    --vp-accent-glow:     rgba(14, 165, 233, 0.22);
    --vp-accent-ring:     rgba(14, 165, 233, 0.30);

    --vp-button-bg:       rgba(15, 23, 42, 0.06);
    --vp-button-border:   rgba(15, 23, 42, 0.13);
    --vp-button-text:     #0f172a;
    --vp-text-muted:      rgba(15, 23, 42, 0.52);

    /* ── Animated-Hotspots (Light) ───────────────────────────────
       Quelle: logo design/design_handoff_hotspots/README.md.
       White-signals werden im Light-Theme zu Dark-Ink (Accent-Flip),
       damit Marker auf hellen Panoramen lesbar bleiben. */
    --vp-hs-glass:           rgba(248, 250, 252, 0.72);
    --vp-hs-glass-strong:    rgba(252, 253, 254, 0.85);
    --vp-hs-glass-line:      rgba(15, 20, 28, 0.14);
    --vp-hs-glass-line-soft: rgba(15, 20, 28, 0.08);
    --vp-hs-ink:             #11151c;
    --vp-hs-ink-dim:         rgba(17, 21, 28, 0.60);
    --vp-hs-fill:            #11151c;
    --vp-hs-on-fill:         #ffffff;
    --vp-hs-accent:          #11151c;
    --vp-hs-blur:            saturate(1.4) blur(20px);
    --vp-hs-sh:              0 10px 30px -12px rgba(20, 30, 50, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.70);

    /* ── Mini-Karte («мини-карта») ───────────────────────────────
       Die Flaeche, auf der der Grundriss liegt (`surface`), das Raster ohne
       Grundriss (`grid`), der Schleier UEBER dem Grundriss (`veil`) und die
       Schrift auf der Karte (`ink`).

       Vorher standen diese vier Farben zweimal fest verdrahtet im Code:
       im Editor (`minimap/MinimapRenderer.ts`) IMMER dunkel, in der Tour
       (`viewer.js drawMinimap`) je nach `html.dark` hell oder dunkel. Im
       hellen Thema war die Karte im Editor also schwarz und in der
       veroeffentlichten Tour hell — genau die Meldung «мини-карта не
       соответствует выбранной теме».

       Deckend in JEDEM Thema, auch in Glas: ein Grundriss auf halb-
       durchsichtigem Grund ist nicht mehr lesbar (gleiche Begruendung wie
       beim Minimal-Theme, siehe oben). Das Thema entscheidet ueber die
       FARBE der Flaeche, nicht ueber ihre Durchsicht.

       Pflicht an ALLEN fuenf Theme-Stellen (Hell / Dunkel / Glas / Minimal
       dunkel / Minimal hell) — fehlt eine, faellt das Sondertheme auf Hell
       zurueck. */
    --vp-map-surface:        rgba(240, 244, 248, 0.95);
    --vp-map-grid:           rgba(15, 23, 42, 0.10);
    --vp-map-veil:           rgba(255, 255, 255, 0.12);
    --vp-map-ink:            rgba(15, 23, 42, 0.86);

    /* ── Rahmen des Players («--vp-ui-*») ────────────────────────
       Obere Pillen, Szenenname, rechte Knopfreihe, untere Leiste,
       Standortliste, Teilen, Autotour, Ton — alles, was NICHT Hotspot ist.

       Bis 2026-09-16 benutzte der Rahmen dieselben --vp-hs-*-Token wie die
       Hotspots. Das war praktisch (gleiche Farben) und falsch: der
       Hotspot-Umschalter [data-hotspot-theme] ueberschreibt die --vp-hs-*
       mit doppelter Spezifitaet, und weil seine Vorgabe DUNKEL ist, blieb
       der ganze Rahmen in JEDEM Thema dunkel. Gemessen: im hellen Thema
       rgb(61,29,53) fuer die Knopfreihe — identisch mit dem dunklen Thema.

       Die Werte sind eins zu eins die der --vp-hs-* desselben Themas; es
       aendert sich nichts am Aussehen, nur die Zustaendigkeit. Wer hier
       etwas ergaenzt, ergaenzt es in ALLEN FUENF Themen.

       Faustregel: Hotspot-Element -> --vp-hs-*, alles andere -> --vp-ui-*. */
    --vp-ui-glass:                 rgba(248, 250, 252, 0.72);
    --vp-ui-glass-strong:          rgba(252, 253, 254, 0.85);
    --vp-ui-glass-line:            rgba(15, 20, 28, 0.14);
    --vp-ui-glass-line-soft:       rgba(15, 20, 28, 0.08);
    --vp-ui-ink:                   #11151c;
    --vp-ui-ink-dim:               rgba(17, 21, 28, 0.60);
    --vp-ui-fill:                  #11151c;
    --vp-ui-on-fill:               #ffffff;
    --vp-ui-accent:                #11151c;
    --vp-ui-blur:                  saturate(1.4) blur(20px);
    --vp-ui-sh:                    0 10px 30px -12px rgba(20, 30, 50, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.70);
}

html.dark,
.vp-dark {
    color-scheme: dark;

    --vp-glass-bg:        rgba(9, 13, 22, 0.75);
    --vp-glass-border:    rgba(255, 255, 255, 0.10);
    --vp-glass-shadow:    0 8px 40px rgba(0, 0, 0, 0.55);

    --vp-accent:          #38bdf8;
    --vp-accent-strong:   #7dd3fc;
    --vp-accent-glow:     rgba(56, 189, 248, 0.22);
    --vp-accent-ring:     rgba(56, 189, 248, 0.30);

    --vp-button-bg:       rgba(255, 255, 255, 0.08);
    --vp-button-border:   rgba(255, 255, 255, 0.13);
    --vp-button-text:     #e8f2ff;
    --vp-text-muted:      rgba(220, 238, 255, 0.52);

    /* ── Animated-Hotspots (Dark) ────────────────────────────────
       Standardfall im Handoff. Weisses Signal auf dunkler Glas-Pille. */
    --vp-hs-glass:           rgba(13, 17, 28, 0.55);
    --vp-hs-glass-strong:    rgba(13, 17, 28, 0.74);
    --vp-hs-glass-line:      rgba(255, 255, 255, 0.16);
    --vp-hs-glass-line-soft: rgba(255, 255, 255, 0.09);
    --vp-hs-ink:             #f3f6fb;
    --vp-hs-ink-dim:         rgba(243, 246, 251, 0.62);
    --vp-hs-fill:            #f1f4f9;
    --vp-hs-on-fill:         #11151c;
    --vp-hs-accent:          #ffffff;
    --vp-hs-blur:            saturate(1.4) blur(20px);
    --vp-hs-sh:              0 10px 34px -10px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.10);

    /* Mini-Karte (siehe Erklaerung im Hell-Block). */
    --vp-map-surface:        rgba(24, 24, 27, 0.95);
    --vp-map-grid:           rgba(63, 63, 70, 0.40);
    --vp-map-veil:           rgba(0, 0, 0, 0.18);
    --vp-map-ink:            rgba(226, 232, 240, 0.92);

    /* ── Rahmen des Players («--vp-ui-*») ────────────────────────
       Obere Pillen, Szenenname, rechte Knopfreihe, untere Leiste,
       Standortliste, Teilen, Autotour, Ton — alles, was NICHT Hotspot ist.

       Bis 2026-09-16 benutzte der Rahmen dieselben --vp-hs-*-Token wie die
       Hotspots. Das war praktisch (gleiche Farben) und falsch: der
       Hotspot-Umschalter [data-hotspot-theme] ueberschreibt die --vp-hs-*
       mit doppelter Spezifitaet, und weil seine Vorgabe DUNKEL ist, blieb
       der ganze Rahmen in JEDEM Thema dunkel. Gemessen: im hellen Thema
       rgb(61,29,53) fuer die Knopfreihe — identisch mit dem dunklen Thema.

       Die Werte sind eins zu eins die der --vp-hs-* desselben Themas; es
       aendert sich nichts am Aussehen, nur die Zustaendigkeit. Wer hier
       etwas ergaenzt, ergaenzt es in ALLEN FUENF Themen.

       Faustregel: Hotspot-Element -> --vp-hs-*, alles andere -> --vp-ui-*. */
    --vp-ui-glass:                 rgba(13, 17, 28, 0.55);
    --vp-ui-glass-strong:          rgba(13, 17, 28, 0.74);
    --vp-ui-glass-line:            rgba(255, 255, 255, 0.16);
    --vp-ui-glass-line-soft:       rgba(255, 255, 255, 0.09);
    --vp-ui-ink:                   #f3f6fb;
    --vp-ui-ink-dim:               rgba(243, 246, 251, 0.62);
    --vp-ui-fill:                  #f1f4f9;
    --vp-ui-on-fill:               #11151c;
    --vp-ui-accent:                #ffffff;
    --vp-ui-blur:                  saturate(1.4) blur(20px);
    --vp-ui-sh:                    0 10px 34px -10px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.10);
}

/* Animated-Hotspots Theme-Override (unabhaengig vom Haupt-uiStyle).

   Reichweite: NUR die Hotspots. Bis 2026-09-16 stand hier «ueberschreibt NUR
   die --vp-hs-*-Tokens — andere UI-Tokens bleiben unberuehrt». Das stimmte
   woertlich und war trotzdem falsch: der ganze Player-Rahmen benutzte damals
   dieselben --vp-hs-*-Token. Der Satz hat den Fehler jahrelang gedeckt.
   Seit der Trennung traegt der Rahmen --vp-ui-* und ist hier aussen vor.

   Der Selektor ist ABSICHTLICH verdoppelt. Custom Properties entscheiden sich
   nach zwei Regeln, und beide standen dem Override im Weg:

   1. Spezifitaet, wenn zwei Regeln DASSELBE Element treffen. Im Public liegen
      `html.dark` (0,1,1) und `[data-hotspot-theme]` (0,1,0) beide auf <html>;
      einfach notiert verlor der Override, "Тема хотспотов = светлая" bei
      dunklem uiStyle blieb daher wirkungslos. Verdoppelt sind es (0,2,0) und
      der Override gewinnt — auch gegen html[data-ui-theme="glass"|"minimal"].

   2. Naehe, wenn die Regeln VERSCHIEDENE Elemente treffen. Da gewinnt immer
      der naechstgelegene Vorfahre, egal wie spezifisch der weiter oben ist.
      Deshalb reicht Spezifitaet allein nicht: das Attribut MUSS auf demselben
      Element sitzen wie die vp-*-Klasse (im Editor der Viewport-Wrapper) —
      sonst ueberschreibt der naehere Wrapper den Override wieder. */
[data-hotspot-theme="light"][data-hotspot-theme="light"] {
    --vp-hs-glass:           rgba(248, 250, 252, 0.72);
    --vp-hs-glass-strong:    rgba(252, 253, 254, 0.85);
    --vp-hs-glass-line:      rgba(15, 20, 28, 0.14);
    --vp-hs-glass-line-soft: rgba(15, 20, 28, 0.08);
    --vp-hs-ink:             #11151c;
    --vp-hs-ink-dim:         rgba(17, 21, 28, 0.60);
    --vp-hs-fill:            #11151c;
    --vp-hs-on-fill:         #ffffff;
    --vp-hs-accent:          #11151c;
    --vp-hs-sh:              0 10px 30px -12px rgba(20, 30, 50, 0.32), inset 0 1px 0 rgba(255, 255, 255, 0.70);
}
[data-hotspot-theme="dark"][data-hotspot-theme="dark"] {
    --vp-hs-glass:           rgba(13, 17, 28, 0.55);
    --vp-hs-glass-strong:    rgba(13, 17, 28, 0.74);
    --vp-hs-glass-line:      rgba(255, 255, 255, 0.16);
    --vp-hs-glass-line-soft: rgba(255, 255, 255, 0.09);
    --vp-hs-ink:             #f3f6fb;
    --vp-hs-ink-dim:         rgba(243, 246, 251, 0.62);
    --vp-hs-fill:            #f1f4f9;
    --vp-hs-on-fill:         #11151c;
    --vp-hs-accent:          #ffffff;
    --vp-hs-sh:              0 10px 34px -10px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.10);
}

/* Editor-Sondertheme: Glass (transparent ueber Panorama, weisser Text) */
.vp-glass,
html[data-ui-theme="glass"] {
    --vp-glass-bg:        rgba(255, 255, 255, 0.10);
    --vp-glass-border:    rgba(255, 255, 255, 0.25);
    --vp-glass-shadow:    0 6px 24px rgba(0, 0, 0, 0.25);
    --vp-button-text:     #ffffff;
    --vp-text-muted:      rgba(255, 255, 255, 0.70);
    --vp-accent:          #38bdf8;
    --vp-accent-strong:   #7dd3fc;
    --vp-accent-glow:     rgba(56, 189, 248, 0.22);
    --vp-accent-ring:     rgba(56, 189, 248, 0.30);

    /* Knopf-Flaechen. Fehlten hier bis 2026-09-16 und fielen damit auf die
       HELLEN Werte des :root-Blocks zurueck (dunkle Tinte, dunkle Haarlinie).
       Sichtbar wurde das an der Visitenkarte: die Kontaktzeilen und die
       Sozial-Knoepfe trugen im Glas-Thema einen dunklen Rand, den es dort
       nirgendwo sonst gibt. */
    --vp-button-bg:       rgba(255, 255, 255, 0.12);
    --vp-button-border:   rgba(255, 255, 255, 0.22);

    /* Panorama-UI-Glass Tokens — Glass = extra-transparent dark base.
       Sonst fallen panorama-ui-glass.css-Selektoren auf :root (Light) zurueck
       und das Glass-Theme sieht aus wie Light. */
    --vp-hs-glass:           rgba(255, 255, 255, 0.10);
    --vp-hs-glass-strong:    rgba(255, 255, 255, 0.16);
    --vp-hs-glass-line:      rgba(255, 255, 255, 0.22);
    --vp-hs-glass-line-soft: rgba(255, 255, 255, 0.12);
    --vp-hs-ink:             #ffffff;
    --vp-hs-ink-dim:         rgba(255, 255, 255, 0.65);
    --vp-hs-fill:            rgba(255, 255, 255, 0.95);
    --vp-hs-on-fill:         #11151c;
    --vp-hs-accent:          #ffffff;
    --vp-hs-blur:            saturate(1.6) blur(24px);
    --vp-hs-sh:              0 8px 28px -10px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.18);

    /* Mini-Karte: Glas gehoert zur dunklen Familie (der Player setzt dafuer
       `html.dark`), die Flaeche bleibt deshalb dunkel. Sie bleibt aber
       DECKEND — durchsichtig waere der Grundriss auf einer hellen Szene
       nicht mehr zu erkennen, und genau das Lesen ist der Zweck der Karte.
       Der Glas-Charakter traegt hier der Rahmen: Rand und Schatten des
       Karten-Panels kommen aus `--vp-hs-glass-line` / `--vp-hs-sh`. */
    --vp-map-surface:        rgba(24, 24, 27, 0.95);
    --vp-map-grid:           rgba(255, 255, 255, 0.14);
    --vp-map-veil:           rgba(0, 0, 0, 0.18);
    --vp-map-ink:            rgba(255, 255, 255, 0.90);

    /* ── Rahmen des Players («--vp-ui-*») ────────────────────────
       Obere Pillen, Szenenname, rechte Knopfreihe, untere Leiste,
       Standortliste, Teilen, Autotour, Ton — alles, was NICHT Hotspot ist.

       Bis 2026-09-16 benutzte der Rahmen dieselben --vp-hs-*-Token wie die
       Hotspots. Das war praktisch (gleiche Farben) und falsch: der
       Hotspot-Umschalter [data-hotspot-theme] ueberschreibt die --vp-hs-*
       mit doppelter Spezifitaet, und weil seine Vorgabe DUNKEL ist, blieb
       der ganze Rahmen in JEDEM Thema dunkel. Gemessen: im hellen Thema
       rgb(61,29,53) fuer die Knopfreihe — identisch mit dem dunklen Thema.

       Die Werte sind eins zu eins die der --vp-hs-* desselben Themas; es
       aendert sich nichts am Aussehen, nur die Zustaendigkeit. Wer hier
       etwas ergaenzt, ergaenzt es in ALLEN FUENF Themen.

       Faustregel: Hotspot-Element -> --vp-hs-*, alles andere -> --vp-ui-*. */
    --vp-ui-glass:                 rgba(255, 255, 255, 0.10);
    --vp-ui-glass-strong:          rgba(255, 255, 255, 0.16);
    --vp-ui-glass-line:            rgba(255, 255, 255, 0.22);
    --vp-ui-glass-line-soft:       rgba(255, 255, 255, 0.12);
    --vp-ui-ink:                   #ffffff;
    --vp-ui-ink-dim:               rgba(255, 255, 255, 0.65);
    --vp-ui-fill:                  rgba(255, 255, 255, 0.95);
    --vp-ui-on-fill:               #11151c;
    --vp-ui-accent:                #ffffff;
    --vp-ui-blur:                  saturate(1.6) blur(24px);
    --vp-ui-sh:                    0 8px 28px -10px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

/* ── Minimal, dunkel («Минимал тёмный», uiStyle "minimal") ────────
   Seit 2026-08-01 DECKEND statt halbdurchsichtig (User): keine Panorama-
   Durchsicht, kein Blur, kein Schatten — eine ruhige schwarze Flaeche, auf
   der Text immer gleich liest, egal wie hell die Szene dahinter ist. Genau
   das ist der Unterschied zum Glas-Theme; ein halbtransparentes Schwarz war
   nur ein dunkleres Glas.
   Die Farbe ist bewusst #101010 und nicht #000: reines Schwarz wirkt auf
   OLED wie ein Loch im Bild, die Kanten der Pille verschwinden. */
.vp-minimal,
html[data-ui-theme="minimal"] {
    --vp-glass-bg:        #101010;
    --vp-glass-border:    rgba(255, 255, 255, 0.14);
    --vp-glass-shadow:    none;
    --vp-button-text:     rgba(255, 255, 255, 0.88);
    --vp-text-muted:      rgba(255, 255, 255, 0.58);
    --vp-blur:            0px;
    --vp-saturate:        100%;

    /* Akzent und Knopf-Flaechen. Fehlten hier bis 2026-09-16 — damit lief das
       dunkle Minimal-Thema mit den HELLEN Werten des :root-Blocks: eine
       dunkle Haarlinie auf schwarzem Grund ist keine Linie, sie ist weg.
       Aufgefallen an der Visitenkarte, wo die Sozial-Knoepfe dadurch
       rahmenlos im Nichts standen. Die Farben sind die der dunklen
       Familie — Minimal ist ein dunkles Thema. */
    --vp-accent:          #38bdf8;
    --vp-accent-strong:   #7dd3fc;
    --vp-accent-glow:     rgba(56, 189, 248, 0.22);
    --vp-accent-ring:     rgba(56, 189, 248, 0.30);
    --vp-button-bg:       rgba(255, 255, 255, 0.08);
    --vp-button-border:   rgba(255, 255, 255, 0.14);

    --vp-hs-glass:           #101010;
    --vp-hs-glass-strong:    #1a1a1a;
    --vp-hs-glass-line:      rgba(255, 255, 255, 0.14);
    --vp-hs-glass-line-soft: rgba(255, 255, 255, 0.08);
    --vp-hs-ink:             #ffffff;
    --vp-hs-ink-dim:         rgba(255, 255, 255, 0.62);
    --vp-hs-fill:            rgba(255, 255, 255, 0.92);
    --vp-hs-on-fill:         #101010;
    --vp-hs-accent:          #ffffff;
    --vp-hs-blur:            none;
    --vp-hs-sh:              none;

    /* Mini-Karte: dieselbe ruhige schwarze Flaeche wie die uebrigen Pillen
       (#101010), damit die Karte nicht als fremdes Moebel im Bild steht. */
    --vp-map-surface:        #101010;
    --vp-map-grid:           rgba(255, 255, 255, 0.12);
    --vp-map-veil:           rgba(0, 0, 0, 0.18);
    --vp-map-ink:            rgba(255, 255, 255, 0.88);

    /* ── Rahmen des Players («--vp-ui-*») ────────────────────────
       Obere Pillen, Szenenname, rechte Knopfreihe, untere Leiste,
       Standortliste, Teilen, Autotour, Ton — alles, was NICHT Hotspot ist.

       Bis 2026-09-16 benutzte der Rahmen dieselben --vp-hs-*-Token wie die
       Hotspots. Das war praktisch (gleiche Farben) und falsch: der
       Hotspot-Umschalter [data-hotspot-theme] ueberschreibt die --vp-hs-*
       mit doppelter Spezifitaet, und weil seine Vorgabe DUNKEL ist, blieb
       der ganze Rahmen in JEDEM Thema dunkel. Gemessen: im hellen Thema
       rgb(61,29,53) fuer die Knopfreihe — identisch mit dem dunklen Thema.

       Die Werte sind eins zu eins die der --vp-hs-* desselben Themas; es
       aendert sich nichts am Aussehen, nur die Zustaendigkeit. Wer hier
       etwas ergaenzt, ergaenzt es in ALLEN FUENF Themen.

       Faustregel: Hotspot-Element -> --vp-hs-*, alles andere -> --vp-ui-*. */
    --vp-ui-glass:                 #101010;
    --vp-ui-glass-strong:          #1a1a1a;
    --vp-ui-glass-line:            rgba(255, 255, 255, 0.14);
    --vp-ui-glass-line-soft:       rgba(255, 255, 255, 0.08);
    --vp-ui-ink:                   #ffffff;
    --vp-ui-ink-dim:               rgba(255, 255, 255, 0.62);
    --vp-ui-fill:                  rgba(255, 255, 255, 0.92);
    --vp-ui-on-fill:               #101010;
    --vp-ui-accent:                #ffffff;
    --vp-ui-blur:                  none;
    --vp-ui-sh:                    none;
}

/* ── Minimal, hell («Минимал светлый», uiStyle "minimal-light") ───
   Spiegelbild des dunklen Minimal: deckendes Weiss, dunkle Schrift. Fuer
   helle Innenraeume und fuer Kunden, deren Logo auf Schwarz nicht steht.
   #ffffff bleibt hier bewusst rein — anders als beim Schwarz gibt es kein
   OLED-Problem, und ein Grauton saehe neben weissen Waenden schmutzig aus.
   Die Linie ist dunkel und leicht kraeftiger als im Glas-Theme, sonst
   verschwindet die Pille auf einer weissen Wand ganz. */
.vp-minimal-light,
html[data-ui-theme="minimal-light"] {
    color-scheme: light;

    --vp-glass-bg:        #ffffff;
    --vp-glass-border:    rgba(15, 20, 28, 0.16);
    --vp-glass-shadow:    none;
    --vp-button-text:     #11151c;
    --vp-text-muted:      rgba(17, 21, 28, 0.58);
    --vp-blur:            0px;
    --vp-saturate:        100%;

    /* Akzent und Knopf-Flaechen. Fehlten hier bis 2026-09-16 und kamen aus
       dem :root-Block. Das war nicht falsch (beides helle Themen), nur zu
       blass: #0ea5e9 auf deckendem Weiss liegt bei rund 3:1 und ist damit
       fuer Telefon-, E-Mail- und Web-Zeilen der Visitenkarte zu wenig.
       Eine Stufe dunkler bringt rund 4,6:1 — ohne den Charakter zu aendern.
       Im halbdurchsichtigen Hell-Thema bleibt der bisherige Wert stehen. */
    --vp-accent:          #0284c7;
    --vp-accent-strong:   #0ea5e9;
    --vp-accent-glow:     rgba(2, 132, 199, 0.20);
    --vp-accent-ring:     rgba(2, 132, 199, 0.28);
    --vp-button-bg:       rgba(15, 20, 28, 0.05);
    --vp-button-border:   rgba(15, 20, 28, 0.16);

    --vp-hs-glass:           #ffffff;
    --vp-hs-glass-strong:    #f2f4f7;
    --vp-hs-glass-line:      rgba(15, 20, 28, 0.16);
    --vp-hs-glass-line-soft: rgba(15, 20, 28, 0.09);
    --vp-hs-ink:             #11151c;
    --vp-hs-ink-dim:         rgba(17, 21, 28, 0.60);
    --vp-hs-fill:            #11151c;
    --vp-hs-on-fill:         #ffffff;
    --vp-hs-accent:          #11151c;
    --vp-hs-blur:            none;
    --vp-hs-sh:              none;

    /* Mini-Karte: deckendes Weiss wie die uebrigen Pillen. Das Raster ist
       dunkel und etwas kraeftiger als im Hell-Thema, sonst verschwindet es
       auf reinem Weiss. */
    --vp-map-surface:        #ffffff;
    --vp-map-grid:           rgba(15, 20, 28, 0.12);
    --vp-map-veil:           rgba(255, 255, 255, 0.12);
    --vp-map-ink:            rgba(17, 21, 28, 0.86);

    /* ── Rahmen des Players («--vp-ui-*») ────────────────────────
       Obere Pillen, Szenenname, rechte Knopfreihe, untere Leiste,
       Standortliste, Teilen, Autotour, Ton — alles, was NICHT Hotspot ist.

       Bis 2026-09-16 benutzte der Rahmen dieselben --vp-hs-*-Token wie die
       Hotspots. Das war praktisch (gleiche Farben) und falsch: der
       Hotspot-Umschalter [data-hotspot-theme] ueberschreibt die --vp-hs-*
       mit doppelter Spezifitaet, und weil seine Vorgabe DUNKEL ist, blieb
       der ganze Rahmen in JEDEM Thema dunkel. Gemessen: im hellen Thema
       rgb(61,29,53) fuer die Knopfreihe — identisch mit dem dunklen Thema.

       Die Werte sind eins zu eins die der --vp-hs-* desselben Themas; es
       aendert sich nichts am Aussehen, nur die Zustaendigkeit. Wer hier
       etwas ergaenzt, ergaenzt es in ALLEN FUENF Themen.

       Faustregel: Hotspot-Element -> --vp-hs-*, alles andere -> --vp-ui-*. */
    --vp-ui-glass:                 #ffffff;
    --vp-ui-glass-strong:          #f2f4f7;
    --vp-ui-glass-line:            rgba(15, 20, 28, 0.16);
    --vp-ui-glass-line-soft:       rgba(15, 20, 28, 0.09);
    --vp-ui-ink:                   #11151c;
    --vp-ui-ink-dim:               rgba(17, 21, 28, 0.60);
    --vp-ui-fill:                  #11151c;
    --vp-ui-on-fill:               #ffffff;
    --vp-ui-accent:                #11151c;
    --vp-ui-blur:                  none;
    --vp-ui-sh:                    none;
}

/* ── Geometrie / Spacing (themenuebergreifend) ────────────────── */
:root {
    --vp-blur:            18px;
    --vp-saturate:        180%;

    --vp-topbar-inset:    16px;
    --vp-topbar-gap:      12px;

    --vp-pill-pad-x:      8px;     /* matches Editor px-2 */
    --vp-pill-pad-y:      6px;     /* matches Editor py-1.5 */
    --vp-pill-gap:        4px;     /* matches Editor gap-1 */
    --vp-pill-radius:     9999px;
    --vp-card-radius:     14px;
    --vp-strip-radius:    16px;
    --vp-strip-item-radius: 10px;

    --vp-btn-size:        34px;
    --vp-icon-size:       16px;
    --vp-ctrl-size:       36px;
    --vp-ctrl-icon-size:  17px;

    /* Logo: gemeinsame Pille fuer Editor + Public (box-sizing: border-box).
       Content-Hoehe = max-h - 2*pad-y - 2*border = 40 - 8 - 2 = 30px sichtbares Bild. */
    --vp-logo-max-w:      140px;
    --vp-logo-max-h:      40px;
    --vp-logo-pad-x:      6px;
    --vp-logo-pad-y:      4px;
    --vp-logo-radius:     4px;

    --vp-hover-ring-width: 2px;    /* matches Editor ring-2 */

    /* ── Visitenkarte: Lage ──────────────────────────────────────
       Gemessen 2026-09-16 im Browser: die Karte stand auf `top: 60px`
       und lag damit 16px UEBER der Unterkante der oberen Pille — die
       zwei Knoepfe darunter (Visitenkarte, Hilfe) waren zu je 24 %
       verdeckt und dort nicht mehr anklickbar. Schlimmer bei 1280px
       Breite und auf dem Handy: dort reichte die 381px hohe Karte bis
       in die rechte Knopfreihe und deckte den Vollbild-Knopf zu 100 %
       zu. Die Karte hatte keine Hoehenbegrenzung — je laenger das
       Kleingedruckte des Kunden, desto mehr verschwand darunter.

       Rechnung (Desktop): 22px Oberkante der TopBar + 54px Hoehe der
       Pille + 8px Luft = 82 -> aufgerundet 84.
       `--vp-bc-rail-half` ist die halbe Hoehe der rechten Knopfreihe;
       sie sitzt bei `top: 50%`, ihre Oberkante liegt also bei
       50vh - rail-half. Die Karte endet 12px darueber. */
    --vp-bc-top:          84px;
    --vp-bc-right:        24px;
    --vp-bc-rail-half:    57px;

    --vp-title-size:      13px;
    --vp-title-weight:    700;
    --vp-title-tracking:  0.01em;

    --vp-transition:      150ms ease-out;

    /* Schrift: Editor erhaelt Geist via Next.js (--font-geist-sans).
       Im Export laedt style.css "Geist" via @font-face — gleiche Optik. */
    --vp-font-family:     var(--font-geist-sans, "Geist"), "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ============================================================
 * Gemeinsame Component-Styles (Editor + Export + Public-Viewer)
 * ------------------------------------------------------------
 * Diese Klassen werden im Export direkt verwendet. Der Editor
 * (Tailwind/JSX) referenziert dieselben Werte via Tokens und
 * matcht das Aussehen 1:1, ohne dass style.css es ueberschreibt.
 * ============================================================ */

/* Buttons sind transparent in einer Glass-Pill — keine eigene
   Hintergrund-Schicht. Hover gibt einen Akzent-Ring (kein border). */
.icon-button {
    background: transparent;
    border: none;
}
.icon-button:hover {
    border-color: transparent;
    box-shadow: 0 0 0 var(--vp-hover-ring-width) var(--vp-accent-ring);
}
.icon-button.is-active {
    border-color: transparent;
    box-shadow: 0 0 0 var(--vp-hover-ring-width) var(--vp-accent-ring);
}

/* TopBar-Pills: einheitliches Padding und Gap aus Tokens. */
#topBar .top-left,
#topBar .top-center,
#topBar .top-right {
    padding: var(--vp-pill-pad-y) var(--vp-pill-pad-x);
}
#topBar .top-right,
.tool-buttons {
    gap: var(--vp-pill-gap);
}

/* ============================================================
 * Panorama-UI Glass-Aliase (Handoff-kompatibel)
 * ------------------------------------------------------------
 * Die Klassen in panorama-ui-glass.css referenzieren die
 * unprefixed Token-Namen aus dem Handoff. Wir mappen sie auf
 * die existierende --vp-hs-* Suite, damit Theme-Switching
 * (light/dark/glass/minimal/auto) automatisch greift.
 * ============================================================ */
:root {
    /* Zeigen auf --vp-ui-*, nicht mehr auf --vp-hs-*: diese Aliase gehoeren
       zum RAHMEN (Handoff-Namen aus panorama-ui-glass.css), nicht zu den
       Hotspots. Sonst haette der Hotspot-Umschalter sie gleich mit gekapert. */
    --glass:           var(--vp-ui-glass);
    --glass-strong:    var(--vp-ui-glass-strong);
    --glass-line:      var(--vp-ui-glass-line);
    --glass-line-soft: var(--vp-ui-glass-line-soft);
    --ink:             var(--vp-ui-ink);
    --ink-dim:         var(--vp-ui-ink-dim);
    --grad:            var(--vp-ui-fill);
    --on-fill:         var(--vp-ui-on-fill);
    --blur:            var(--vp-ui-blur);
    --sh:              var(--vp-ui-sh);
    /* Handoff-Wert 1:1 (48px). */
    --hit:             48px;
}

/* ============================================================
 * Business Card (Visitenkarte)
 * ------------------------------------------------------------
 * Shared UI between EditorViewport (React) and Export/Public Viewer (viewer.js).
 * Must not rely on Tailwind-only colors (avoid drift).
 * ============================================================ */

.vp-bc-panel {
    position: absolute;
    /* Lage siehe Kommentar bei --vp-bc-top: die Karte haengt UNTER der
       oberen Pille, buendig mit deren rechter Kante, und endet ueber der
       rechten Knopfreihe. Vorher verdeckte sie beide. */
    top: var(--vp-bc-top, 84px);
    right: var(--vp-bc-right, 24px);
    z-index: 9000;
    min-width: 200px;
    max-width: min(280px, calc(100vw - 2 * var(--vp-bc-right, 24px)));
    /* Ohne border-box zaehlt max-height nur den Inhalt — Polsterung und
       Rahmen kaemen obendrauf, und die Karte ragte gemessene 26px zu weit
       nach unten (genau um 2x12px Polsterung + 2x1px Rahmen). */
    box-sizing: border-box;
    max-height: calc(50vh - var(--vp-bc-rail-half, 57px) - var(--vp-bc-top, 84px) - 12px);
    overflow-y: auto;
    overscroll-behavior: contain;
    pointer-events: auto;

    background: var(--vp-glass-bg);
    border: 1px solid var(--vp-glass-border);
    box-shadow: var(--vp-glass-shadow);
    backdrop-filter: blur(var(--vp-blur)) saturate(var(--vp-saturate));
    -webkit-backdrop-filter: blur(var(--vp-blur)) saturate(var(--vp-saturate));

    border-radius: 12px;
    padding: 12px;
    color: var(--vp-button-text);
    font-family: var(--vp-font-family);
    font-size: 13px;
    line-height: 1.4;

    display: none;
    animation: vp-bc-in 0.15s ease;
}

.vp-bc-panel.visible {
    display: block;
}

@keyframes vp-bc-in {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }
    to {
        opacity: 1;
        transform: none;
    }
}

.vp-bc-logo {
    border-radius: 10px;
    display: block;
    margin-bottom: 10px;
    height: auto;
    max-width: 100%;
    object-fit: contain;
}

.vp-bc-name {
    font-size: 15px;
    font-weight: 700;
    margin-bottom: 8px;
    line-height: 1.25;
}

.vp-bc-rows {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.vp-bc-row {
    display: flex;
    align-items: center;
    gap: 8px;
    border-radius: 10px;
    padding: 6px 8px;
    border: 1px solid var(--vp-glass-border);
    background: var(--vp-button-bg);
    overflow: hidden;
    text-overflow: ellipsis;
}

.vp-bc-row-icon {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    color: var(--vp-text-muted);
}

.vp-bc-row-icon svg {
    width: 16px;
    height: 16px;
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.vp-bc-row-text {
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.vp-bc-row--link {
    color: var(--vp-accent);
    text-decoration: none;
}

.vp-bc-row--link:hover {
    color: var(--vp-accent-strong);
    box-shadow: 0 0 0 var(--vp-hover-ring-width) var(--vp-accent-ring);
}

.vp-bc-row--text {
    color: var(--vp-button-text);
    opacity: 0.8;
}

.vp-bc-social {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 10px;
}

.vp-bc-social-link {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 10px;
    background: var(--vp-button-bg);
    border: 1px solid var(--vp-button-border);
    color: var(--vp-accent);
    text-decoration: none;
    transition: box-shadow 0.16s, color 0.16s, transform 0.12s;
}

.vp-bc-social-link:hover {
    color: var(--vp-accent-strong);
    transform: translateY(-1px);
    box-shadow: 0 0 0 var(--vp-hover-ring-width) var(--vp-accent-ring);
}

.vp-bc-social-icon {
    width: 16px;
    height: 16px;
    display: block;
}

.vp-bc-social-icon[data-ic-kind="brand"] {
    fill: currentColor;
}

.vp-bc-social-icon[data-ic-kind="fallback"] {
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.vp-bc-disclaimer {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--vp-glass-border);
    font-size: 11px;
    line-height: 1.45;
    color: var(--vp-text-muted);
    overflow-wrap: anywhere;
}

.vp-bc-disclaimer a {
    color: var(--vp-accent);
    text-decoration: underline;
}

.vp-bc-disclaimer a:hover {
    color: var(--vp-accent-strong);
}

.vp-bc-btn {
    overflow: hidden;
    padding: 0;
}

.vp-bc-btn img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ── Handy: die obere Pille sitzt hoeher und ist flacher ──────────
   Gemessen bei 393x852: TopBar-Oberkante 14px, Pillenhoehe 48px, also
   14 + 48 + 8 = 70. Die rechte Knopfreihe ist dort 100px hoch. */
@media (max-width: 640px) {
    :root {
        --vp-bc-top:       70px;
        --vp-bc-right:     14px;
        --vp-bc-rail-half: 50px;
    }
}
