/* Betrachter /<code>/ovaling/ (Plan docs/site/PLAN.md 4.4, Paket C2, Luis 15.10.2026, 7a). Nur Variablen aus tokens.css,
   transparent, currentColor und color-mix. Angelehnt an die Detailseite der App: Bühne auf dem Bild der Familie mit Name und
   Level, Karte mit Seltenheit, Familie und Gene Score, Plätze wie MoveSlotBoxes, Werte wie _ValueRow, Sechseck wie
   StatHexagon, Glasfenster wie OvalGlassPanel. Lage des Bodens je Familie (backdropFloor) hängt build_site.py hinten an. */

/* Schrift in Seltenheitsfarbe: hell dunkler gemischt (Kontrast auf weißer Karte), dunkel die helle Fassung */
.vcard, .vpanel, .vsum, .vtier, .vhex { --rt: color-mix(in srgb, var(--c-deep) 82%, var(--text)); }
@media (prefers-color-scheme: dark) { .vcard, .vpanel, .vtier, .vhex { --rt: var(--c-hi); } }
.vsum { --rt: var(--c-hi); }

/* ---------- Kopf, Umschalter und Eingabe ---------- */
/* Kopf nur mit Titel (beim Umschalten springt nichts), Umschalter liegt halb auf seiner Unterkante */
.vhead { padding-top: calc(var(--head-h) + var(--s-l)); padding-bottom: calc(var(--s-l) + 30px); }
.vhead .headin { min-height: 0; }
.vwrap { position: relative; z-index: 1; margin-top: -30px; }

/* Umschalter wie OvalSegmented: eingelassene Leiste, die gewählte Fläche (Verlauf, Glanz, Kante) gleitet unter den Eintrag.
   Er steht ab dem ersten Bild da, damit die Eingabe darunter nicht springt, wenn viewer.js und die Daten kommen. Ohne JavaScript
   wäre er ohne Wirkung und fehlt. Gleiten erst mit .live: die erste Wahl aus dem Fragment (viewer.js) springt ohne Bewegung */
.vmodes {
  position: relative; isolation: isolate; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 560px;
  padding: 4px; border-radius: var(--r-full); border: 2px solid var(--ink); background: linear-gradient(var(--well-top), var(--well-bottom));
  box-shadow: 0 4px 0 var(--card-edge);
}
@media (scripting: none) { .vmodes { display: none; } }
.vmodes::before {
  content: ""; position: absolute; z-index: -1; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 4px); border-radius: var(--r-full);
  border: 2px solid var(--ink);
  background: linear-gradient(color-mix(in srgb, var(--white) 40%, transparent), color-mix(in srgb, var(--white) 4%, transparent)) center 3px / 82% 40% no-repeat,
    linear-gradient(var(--primary-top), var(--primary)) top / 100% calc(100% - 3px) no-repeat, var(--primary-edge);
}
.vmodes.live::before { transition: transform var(--t-medium) var(--spring); }
.vmodes[data-on="examples"]::before { transform: translateX(100%); }
.vmode {
  min-height: 48px; padding: 4px 10px 7px; border: 0; border-radius: var(--r-full); background: none; cursor: pointer; color: var(--text-muted);
  font: 700 clamp(14px, 3.9vw, 17px)/1.15 var(--display); text-align: center; transition: color var(--t-quick) var(--ease);
}
.vmode:hover { color: var(--text); }
.vmode[aria-pressed="true"] { color: var(--white); text-shadow: 0 1.5px 0 color-mix(in srgb, var(--ink) 55%, transparent); cursor: default; }
.vmode:focus-visible { border-radius: var(--r-full); outline-offset: 1px; }

.vform { max-width: 760px; margin-top: var(--s-l); padding: var(--s-l) var(--s-l) var(--s-s); }
.vwrap > .vform:first-child { margin-top: 0; }
/* Ab 900 px so breit wie die Spalte der Bühne darunter (Raster 1,05 zu 1 mit Abstand xxl) */
@media (min-width: 900px) { html.vopen .vform { max-width: calc((100% - var(--s-xxl)) * 1.05 / 2.05); } }
/* Eigenes Ovaling: Maskottchen und Satz über der Eingabe, mit gezeigtem Ovaling oder Meldung nur noch die Eingabe */
.vownhead { display: flex; align-items: center; gap: var(--s-m); margin-bottom: var(--s-m); }
.vownmascot { width: 84px; height: auto; flex: none; filter: drop-shadow(0 8px 10px color-mix(in srgb, var(--black) 18%, transparent)); }
.vowntext { margin: 0; font-weight: 700; font-size: 17px; line-height: 1.45; }
.vform.compact .vownhead { display: none; }
@media (max-width: 599px) { .vownmascot { width: 64px; } .vowntext { font-size: 16px; } }

/* Beispiele: Licht und Schatten auf dem Bild ihrer Familie, nicht gewählt unter einem Schleier, gewählt mit Ring in der Farbe
   der Familie (FamilyColors.accent) */
.vfams { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(8px, 2.5vw, 16px); }
.vfambtn {
  position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: center; gap: var(--s-s); min-width: 0; min-height: 72px;
  padding: 4px clamp(8px, 3vw, var(--s-m)) 4px 6px; border-radius: var(--r-l); border: 2.5px solid var(--ink); box-shadow: 0 4px 0 var(--card-edge);
  background: var(--g1) center 35% / cover no-repeat; cursor: pointer; color: var(--white);
  font: 600 clamp(16px, 4.6vw, 22px)/1.1 var(--display); text-align: left; transition: transform var(--t-quick) var(--spring), box-shadow var(--t-quick) var(--ease);
}
.vfambtn.fam-light { background-image: url("bg/family_light-1024.6a92649f.webp"); }
.vfambtn.fam-shadow { background-image: url("bg/family_shadow-1024.ce783ae1.webp"); }
.vfambtn::after { content: ""; position: absolute; inset: 0; z-index: -1; background: color-mix(in srgb, var(--bg) 58%, transparent); transition: opacity var(--t-quick) var(--ease); }
.vfambtn img { flex: none; width: clamp(40px, 12vw, 60px); height: clamp(40px, 12vw, 60px); object-fit: contain; filter: grayscale(0.5) drop-shadow(0 4px 4px color-mix(in srgb, var(--black) 30%, transparent)); transition: filter var(--t-quick) var(--ease); }
/* Ganze Wörter (Lumière, Bayangan), nur was gar nicht passt, bricht */
.vfambtn span { min-width: 0; overflow-wrap: break-word; }
.vfambtn:hover { transform: translateY(calc(-1 * var(--lift))); }
.vfambtn[aria-pressed="true"] { box-shadow: 0 0 0 3px var(--c), 0 4px 0 var(--card-edge); cursor: default; transform: none; }
.vfambtn[aria-pressed="true"]::after { opacity: 0; }
.vfambtn[aria-pressed="true"] img { filter: drop-shadow(0 4px 4px color-mix(in srgb, var(--black) 30%, transparent)); }
.vfambtn:focus-visible { outline-offset: 5px; border-radius: var(--r-l); }
/* Ziel des Sprunglinks (viewer.js gibt main tabindex -1): der Fokus springt hinein, ohne Rahmen um die ganze Seite */
main[tabindex="-1"]:focus { outline: none; }
.vinputrow { display: flex; align-items: flex-start; gap: var(--s-s); margin-top: 6px; }
.vinputrow input {
  flex: 1; min-width: 0; min-height: 52px; padding: 13px 16px; border-radius: var(--r-m); border: 1.5px solid var(--line);
  background: var(--surface); color: var(--text); font: 600 16px/1.3 var(--body); font-variant-numeric: tabular-nums; outline: none;
}
.vinputrow input:focus { border: 2px solid var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 16%, transparent); }
.vinputrow input[aria-invalid="true"] { border: 2px solid var(--danger); }
.vinputrow .ob { flex: none; margin-top: -1px; }
.vformlinks { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0 var(--s-l); font-size: 15px; font-weight: 700; }
.vformlinks a { display: inline-flex; align-items: center; min-height: 44px; }
.vformlinks .linkish { padding: 0; }
.vformlinks a:only-child, .vformlinks [hidden] + a { margin-left: auto; }

/* ---------- Meldungen ---------- */
.vmsg { display: flex; align-items: center; gap: var(--s-xl); margin-top: var(--s-xl); padding: var(--s-xl); max-width: 760px; }
.vmsgart { width: 96px; flex: none; filter: grayscale(0.35) drop-shadow(0 8px 10px color-mix(in srgb, var(--black) 15%, transparent)); }
.vmsgtext { font-weight: 700; font-size: 17px; }
.vmsg .buttons:has([hidden]:only-child) { display: none; }
.vnojs { margin-top: var(--s-xl); max-width: 760px; font-weight: 700; }
@media (max-width: 599px) {
  .vmsg { flex-direction: column; text-align: center; gap: var(--s-m); }
  .vmsg .buttons { justify-content: center; }
}

/* ---------- Bühne und Karte nebeneinander ab 900 px ---------- */
/* Mit Beispiel (viewer.js setzt .ex) kommen die Knöpfe der Familien dazu: am Handy über der Bühne, ab 900 px rechts oben */
.vgrid { display: grid; gap: var(--s-xl); margin-top: var(--s-xl); grid-template-areas: "stage" "info"; }
.vgrid.ex { grid-template-areas: "fams" "stage" "info"; }
.vfams { grid-area: fams; }
.vstagecol { grid-area: stage; min-width: 0; }
.vinfo { grid-area: info; }
.vinfo, .vdetails { display: grid; gap: var(--s-l); align-content: start; min-width: 0; }
@media (min-width: 900px) {
  .vgrid { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); align-items: start; gap: var(--s-xxl); grid-template-areas: "stage info"; }
  .vgrid.ex { grid-template-areas: "stage fams" "stage info"; grid-template-rows: auto 1fr; row-gap: var(--s-l); }
  .vstagecol { position: sticky; top: calc(var(--head-h) + var(--s-l)); }
}

/* ---------- Bühne: Bild der Familie, darin die 3D-Seite ---------- */
.vstage {
  position: relative; isolation: isolate; overflow: hidden; height: 58vh; height: 58svh; min-height: 340px; max-height: 760px;
  border-radius: var(--r-xxl); border: 2px solid var(--ink); box-shadow: 0 6px 0 var(--card-edge);
  /* Solange die Familie offen ist (Laden): der Garten unter dem Schleier wie der Grund der Seite, hell bei Tag */
  background: linear-gradient(var(--veil), var(--veil)), var(--garden) center / cover no-repeat;
}
@media (min-width: 900px) { .vstage { height: min(calc(100vh - var(--head-h) - 2 * var(--s-xl)), 720px); } }
/* color-scheme light wie die 3D-Seite: weicht das Farbschema von Rahmen und eingebetteter Seite ab (dunkler Modus), malt der
   Browser hinter die Seite eine deckende weiße Fläche statt des durchsichtigen Grunds */
.vframe { position: absolute; inset: 0; z-index: 1; display: block; width: 100%; height: 100%; border: 0; opacity: 0; color-scheme: light; transition: opacity var(--t-scene) var(--ease); }
.vstage.built .vframe { opacity: 1; }
.vstage.no3d .vframe { visibility: hidden; }
.vloading { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-s); pointer-events: none; }
.vloading span { padding: 6px 14px; border-radius: var(--r-full); background: var(--glass); color: var(--glass-text); font: 800 14px/1.2 var(--body); }
.vloadegg { width: 72px; height: auto; transform-origin: 50% 100%; filter: drop-shadow(0 6px 6px color-mix(in srgb, var(--black) 35%, transparent)); animation: vwobble 1400ms var(--ease) infinite; }
@keyframes vwobble { 0%, 40%, 100% { transform: rotate(0); } 50% { transform: rotate(-9deg); } 60% { transform: rotate(8deg); } 70% { transform: rotate(-5deg); } 80% { transform: rotate(2deg); } }
.vno3d { position: absolute; inset: 0; z-index: 2; }
.vegg { position: absolute; left: 50%; bottom: 25%; width: clamp(72px, 22%, 120px); height: auto; transform: translateX(-50%); filter: drop-shadow(0 8px 8px color-mix(in srgb, var(--black) 35%, transparent)); }
/* Ohne Figur gibt es kein Vollbild: der Satz steht unten, unter dem Boden des Bilds, und verdeckt das Ei nicht */
.vno3d p { position: absolute; left: var(--s-m); right: var(--s-m); bottom: var(--s-m); margin: 0; padding: var(--s-s) var(--s-m); border-radius: var(--r-m); text-align: center; font-weight: 700; }
.vtop { position: absolute; z-index: 3; top: var(--s-m); left: var(--s-m); right: var(--s-m); display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-s); pointer-events: none; }
.vname { margin: 6px 0 0 4px; font: 600 clamp(22px, 5.6vw, 30px)/1.1 var(--display); color: var(--white); text-shadow: var(--outline-shadow); overflow-wrap: anywhere; }
.vlevelpill {
  flex: none; display: inline-flex; align-items: center; height: 38px; padding: 0 14px; margin-left: auto; border-radius: var(--r-full);
  background: var(--surface); color: var(--text); border: 2px solid var(--ink); box-shadow: 0 3px 0 var(--card-edge); font: 600 16px/1 var(--display); white-space: nowrap;
}
.vfull { position: absolute; z-index: 3; right: var(--s-m); bottom: var(--s-m); min-height: 44px; padding: 0 18px; border-radius: var(--r-full); font: 700 14px/1 var(--body); cursor: pointer; }
.vfull:hover { border-color: var(--glass-text); }
/* Vollbild: Klasse für position fixed (am iPhone nur sie), sonst dazu die Fullscreen-API auf der Bühne */
.vstage.full { position: fixed; inset: 0; z-index: 60; width: 100%; height: 100vh; height: 100dvh; max-height: none; min-height: 0; border: 0; border-radius: 0; box-shadow: none; }
.vstage:fullscreen { height: 100%; border-radius: 0; }
.vstage.full .vtop { top: calc(var(--s-m) + env(safe-area-inset-top)); left: max(var(--s-m), env(safe-area-inset-left)); right: max(var(--s-m), env(safe-area-inset-right)); }
.vstage.full .vfull { bottom: calc(var(--s-m) + env(safe-area-inset-bottom)); right: max(var(--s-m), env(safe-area-inset-right)); }
html.vfull { overflow: hidden; }
/* Im Vollbild keine Stapelebenen der Vorfahren (z-index der Eingabe, sticky am Desktop), sonst lägen Kopf und Leiste darüber */
html.vfull .vwrap { z-index: auto; }
html.vfull .vstagecol { position: static; }
html.vfull .top, html.vfull .tabbar { visibility: hidden; }

/* ---------- Kopf der Karte ---------- */
.vcard { display: grid; gap: var(--s-m); }
.vchips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-s); }
.vchips .chip { font-size: 14px; padding: 5px 13px; }
.vfam { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 7px; }
.vsep { width: 1px; height: 14px; background: color-mix(in srgb, var(--c-on) 40%, transparent); }
.vfamicon { width: 16px; height: 16px; }
.vfam.nobonus .vsep, .vfam.nobonus .vfamicon { display: none; }
.vscore { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-m); padding-top: var(--s-xs); border-top: 1px dashed var(--line); }
.vscore strong { font: 600 40px/1 var(--display); color: var(--rt); font-variant-numeric: tabular-nums; }
.vlevelhead { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px var(--s-m); }
.vlevelhead strong { font: 600 20px/1.2 var(--display); }
.vlevelhead span { font-weight: 700; font-size: 14px; font-variant-numeric: tabular-nums; }
.vtrack { height: 12px; margin-top: 6px; border-radius: var(--r-full); overflow: hidden; background: linear-gradient(var(--track-top), var(--track-bottom)); border: 1.5px solid color-mix(in srgb, var(--ink) 35%, transparent); }
.vfill { display: block; height: 100%; border-radius: var(--r-full); background: linear-gradient(90deg, var(--primary-top), var(--primary)); }

/* ---------- Plätze (MoveSlotBoxes): drei Attacken, Trennlinie, Passive ---------- */
.vpanel { padding: var(--s-m) var(--s-m) var(--s-l); }
.vpanel .minor { margin-top: 0; }
.vslots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) var(--s-l) minmax(0, 1fr); gap: var(--s-s); align-items: start; padding-bottom: 6px; }
.vslot { position: relative; min-width: 0; }
.vslot.passive { grid-column: 5; }
.vslot.passive::before { content: ""; position: absolute; top: 0; bottom: 0; left: calc(-1 * (var(--s-s) + var(--s-l) / 2) - 1.5px); width: 3px; border-radius: 2px; background: var(--passive); }
.vslottitle { display: block; margin-bottom: 6px; text-align: center; font: 800 12px/1.2 var(--body); letter-spacing: 0.3px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Schrift der Passive im hellen Modus in der dunklen Fassung (--c-deep von .r-passive, über 4,5:1 auch auf dem getönten Feld), Linie in --passive */
.vslot.passive .vslottitle { color: var(--c-deep); }
@media (prefers-color-scheme: dark) { .vslot.passive .vslottitle { color: var(--passive-hi); } .vslot.passive::before { background: var(--passive-hi); } }
.vbox {
  position: relative; display: grid; place-items: center; width: 100%; aspect-ratio: 1; padding: 0; cursor: pointer; color: var(--text);
  border-radius: var(--r-l); border: 1.5px solid var(--line); background: var(--surface-raised); transition: transform var(--t-quick) var(--spring);
}
.vbox:hover { transform: translateY(calc(-1 * var(--lift))); }
.vbox:active { transform: scale(var(--press-scale)); }
.vbox.filled { overflow: hidden; border: var(--stroke-rarity) solid var(--c); background: color-mix(in srgb, var(--c) 12%, var(--surface-raised)); }
.vbox.filled > img { display: block; width: 100%; height: 100%; }
.vbox.passiveart { overflow: visible; border: 0; background: none; }
.vbox.passiveart > img { border-radius: 0; }
.vicon { width: 52%; height: 52%; fill: color-mix(in srgb, var(--c, var(--text)) 85%, transparent); stroke: var(--c, var(--text)); stroke-width: 1.8; }
.vbox.empty .vicon { fill: none; stroke: color-mix(in srgb, var(--text) 35%, transparent); }
.vbox.empty.r-passive { border-color: color-mix(in srgb, var(--passive) 50%, transparent); }
.vicon.aura .core, .vicon.aura .ring { fill: none; stroke-linecap: round; }
.vbox.empty.r-passive .vicon { stroke: color-mix(in srgb, var(--passive) 45%, transparent); }
.vbox.locked { background: color-mix(in srgb, var(--line) 55%, transparent); border: 1.5px solid color-mix(in srgb, var(--text-muted) 35%, transparent); overflow: hidden; }
.vchains { position: absolute; inset: 0; width: 100%; height: 100%; }
.vchains .cd { fill: none; stroke: color-mix(in srgb, var(--text) 70%, transparent); stroke-width: 7.5; }
.vchains .cd.bar { stroke-width: 9.4; stroke-linecap: round; }
.vchains .cl { fill: none; stroke: color-mix(in srgb, var(--surface) 55%, transparent); stroke-width: 3; stroke-linecap: round; }
.vlock { position: absolute; left: 50%; top: 60%; transform: translate(-50%, -50%); display: grid; place-items: center; width: 50%; aspect-ratio: 1; border-radius: 50%; background: var(--surface); border: 2.2px solid color-mix(in srgb, var(--text) 70%, transparent); box-shadow: var(--soft-shadow); }
.vlock img { width: 62%; height: 62%; }
/* Das kleine P der Passive (Ausnahme der Gestaltungsregeln, Luis 05.10.2026): mittig auf der Unterkante */
.vpmark { position: absolute; left: 50%; bottom: 0; transform: translate(-50%, 52%); font: 700 clamp(14px, 4.4vw, 20px)/1 var(--display); color: var(--passive-hi); text-shadow: var(--outline-shadow); pointer-events: none; }

/* ---------- Werte (wie _ValueRow) ---------- */
.vstats { display: grid; gap: 2px; }
.vstat {
  display: grid; grid-template-columns: 22px minmax(70px, 32%) minmax(0, 1fr) auto; align-items: center; gap: var(--s-s);
  width: 100%; min-height: 44px; padding: 6px 6px; border: 0; border-radius: var(--r-s); background: none; color: var(--text);
  font: inherit; text-align: left; cursor: pointer;
}
.vstat:hover { background: color-mix(in srgb, var(--c) 9%, transparent); }
.vstaticon { width: 22px; height: 22px; }
.vstatname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 700; color: var(--text-muted); }
.vstatbar { position: relative; height: 10px; overflow: hidden; border-radius: var(--r-full); background: var(--line); }
.vbonus, .vbase { position: absolute; left: 0; top: 0; bottom: 0; border-radius: var(--r-full); }
.vbonus { background: var(--c); }
.vbase { background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 70%, transparent), var(--accent)); }
/* Kerbe zwischen Grundbalken und Bonus: bei Epic haben beide dieselbe Farbe (accent gleich --c) */
.vstatbar.bonus .vbase { box-shadow: 2px 0 0 var(--surface); }
.vstatval { display: inline-flex; align-items: center; justify-content: flex-end; gap: 4px; min-width: 56px; font: 600 16px/1 var(--display); font-variant-numeric: tabular-nums; white-space: nowrap; }
.vstatval.up { color: var(--rt); }
.vlucky { width: 16px; height: 16px; }

/* ---------- Aufklappen, Sechseck, Steckbrief, Mehr Infos ---------- */
.vexp { margin-top: 0; }
.vexp > :not(summary) { padding: var(--s-m) var(--s-xs) 0; }
.vhex { padding-top: var(--s-s); }
.vhexsvg { display: block; width: 100%; max-width: 440px; height: auto; margin: 0 auto; overflow: visible; }
.vhexsvg .grid { fill: none; stroke: var(--line); stroke-width: 1; }
.vhexsvg .grid.outer { stroke-width: 2; }
.vhexsvg .area { fill: color-mix(in srgb, var(--c) 24%, transparent); stroke: var(--c); stroke-width: 2.6; stroke-linejoin: round; }
.vhexsvg .dot { fill: var(--c); }
/* Glückspunkt als Ring in --gold mit Kontur, sonst verschwände er bei Legendary unter dem Punkt in --c */
.vhexsvg .lucky { fill: var(--gold); stroke: var(--ink); stroke-width: 1.6; }
.vhexsvg .label { fill: var(--text-muted); font: 700 12px var(--body); }
.vprofile h2 { font-size: 20px; margin-bottom: var(--s-s); }
.vprofile p { font-size: 16px; }
.vprofile .note { margin-top: var(--s-s); font-size: 14px; }
.vrows { margin-top: 0; }
.vtier { color: var(--rt); }
.vidbox { margin-top: var(--s-m); padding: var(--s-m) var(--s-m) var(--s-l); border-radius: var(--r-m); background: var(--surface-raised); border: 1px solid var(--line); }
.vidbox code { display: block; margin: 4px 0 0; color: var(--text); font: 600 14px/1.45 ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; overflow-wrap: anywhere; }
.vidbox .buttons { margin-top: var(--s-s); }

/* ---------- Beispiele ---------- */
.vexample p { color: var(--text-muted); font-weight: 600; }
/* Pfeile links und rechts mittig auf der Bühne (Glas wie Vollbild), Punkte unten links, der gewählte in der Farbe der Familie */
.vexbtn {
  position: absolute; z-index: 3; top: calc(50% - 24px); display: grid; place-items: center; width: 48px; height: 48px; padding: 0;
  border-radius: 50%; cursor: pointer; transition: transform var(--t-quick) var(--spring), opacity var(--t-quick) var(--ease);
}
.vexbtn.prev { left: var(--s-s); }
.vexbtn.next { right: var(--s-s); }
.vexbtn:hover { transform: scale(1.08); border-color: var(--glass-text); }
.vexbtn:disabled { opacity: 0.35; cursor: default; transform: none; }
.vexbtn:focus-visible { border-radius: 50%; }
.vchev { width: 12px; height: 12px; margin-right: 5px; border-right: 3px solid currentColor; border-top: 3px solid currentColor; transform: rotate(45deg); }
.prev .vchev { margin: 0 0 0 5px; transform: rotate(-135deg); }
.vdots { position: absolute; z-index: 3; left: var(--s-m); bottom: var(--s-m); display: flex; align-items: center; gap: 6px; height: 44px; padding: 0 14px; border-radius: var(--r-full); pointer-events: none; }
.vdots li { width: 8px; height: 8px; border-radius: var(--r-full); background: color-mix(in srgb, var(--glass-text) 38%, transparent); transition: width var(--t-medium) var(--ease); }
.vdots li.on { width: 22px; background: var(--c, var(--glass-text)); }
.vstage.full .vexbtn.prev { left: max(var(--s-s), env(safe-area-inset-left)); }
.vstage.full .vexbtn.next { right: max(var(--s-s), env(safe-area-inset-right)); }
/* Ohne Figur steht unten der Satz, warum (die Punkte lägen darauf) */
.vstage.no3d .vdots { visibility: hidden; }
.vstage.full .vdots { bottom: calc(var(--s-m) + env(safe-area-inset-bottom)); left: max(var(--s-m), env(safe-area-inset-left)); }

/* ---------- Glasfenster der Plätze und Werte ---------- */
.vdialog { width: min(460px, calc(100vw - 2 * var(--page))); }
.vdhead { display: flex; align-items: center; gap: var(--s-m); margin: 0 44px var(--s-m) 0; }
.vdialog .vdhead h2 { margin: 0; font-size: 22px; }
.vdhead .sub { margin: 2px 0 0; color: var(--glass-muted); }
.vdtitle { min-width: 0; }
.vdart { flex: none; width: 64px; height: 64px; }
.vdart.small { width: 40px; height: 40px; }
.vdhead .frame { flex: none; width: 64px; height: 64px; }
.vdhead .frame img { width: 100%; height: 100%; }
.vdhead .frame.paw { display: grid; place-items: center; }
.vdicon { display: grid; place-items: center; flex: none; width: 56px; height: 56px; border-radius: var(--r-m); background: var(--glass-line); }
.vdicon img { width: 36px; height: 36px; }
.vdicon .vicon { width: 36px; height: 36px; fill: none; stroke: var(--glass-text); }
.vdialog .rows > div { border-bottom-color: var(--glass-line); }
.vdialog .rows dt { color: var(--glass-muted); }
.vdialog .rows dd { color: var(--glass-text); }
.vdialog .lines li::before { background: var(--night-accent); }
.vdialog .buff { color: var(--buff-text); }
.vdialog .debuff { color: var(--debuff-text); }
.vdtext { color: var(--glass-text); }
.vsum dd.up { color: var(--rt); }
.vsum dd.total { font: 600 22px/1 var(--display); }
.vsum .rows > div:last-child { border-top: 1.5px solid var(--glass-rim); padding-top: 8px; margin-top: 4px; }

/* Lage des Bodens je Familie, erzeugt von build_site.py aus FamilyColors.backdropFloor */
.vstage.fam-light { background: var(--edge) url("bg/family_light-1024.6a92649f.webp") 50% 75.0% / cover no-repeat; }
.vstage.fam-light .vegg { bottom: 25.0%; }
.vstage.fam-shadow { background: var(--edge) url("bg/family_shadow-1024.ce783ae1.webp") 50% 69.7% / cover no-repeat; }
.vstage.fam-shadow .vegg { bottom: 30.3%; }
