/* Der Self-Service-Wizard unter /overlay.
 *
 * Baut auf site.css auf: dieselben Tokens (--paper, --ink, --rule), dieselbe
 * Haltung (Schweizer Raster, Haarlinien statt Kästen, keine Rundungen). Was
 * hier dazukommt, ist die App: Schrittanzeige, Slider, die Formulare der drei
 * Schritte und die zweigeteilte Vorschau.
 */

/* **`hidden` muss gewinnen.**
 *
 * Der Browser setzt für `[hidden]` ein `display: none`, aber jede eigene Regel
 * mit einem `display` ist spezifischer und hebt es auf. Genau so blieb die
 * Zeile „Passwortschutz: ja, 10 €" in der Bestellübersicht stehen, obwohl der
 * Haken aus war: `.wz-liste > div { display: flex }` gewann. Dasselbe traf den
 * Formatumschalter, der in der Seitenansicht verschwinden soll.
 *
 * Das `!important` ist hier das mildere Mittel: die Alternative wäre, an jeder
 * Regel mit `display` eine `[hidden]`-Ausnahme mitzuführen und bei der nächsten
 * zu vergessen. */
[hidden] { display: none !important; }

/* --------------------------------------------------------------- Das Raster */

.wizard { padding-block: clamp(32px, 5vw, 64px); }

.wz-raster {
  display: grid;
  /* **`minmax(0, 1fr)` auch einspaltig, nicht erst am Haltepunkt.**
     Eine Grid-Spalte ohne Angabe ist `auto` und wächst mit ihrem breitesten
     Inhalt. Der ist hier die Leinwand: `#wz-stage` misst im Layout die volle
     Formatbreite von 1080 px, denn `transform: scale()` verkleinert das
     Gezeichnete, nicht den Kasten. Die Spalte wurde damit 1080 px breit, der
     Rahmen darin ebenso, und die Skalierung rechnet `Rahmenbreite geteilt
     durch Szenenbreite`, also 1. Die Vorschau blieb in Originalgröße stehen
     und schob die ganze Seite waagerecht auf.
     Auf Desktop fiel das nie auf, dort steht `minmax(0, 1fr)` seit jeher. */
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}

/* **Auf schmalen Schirmen steht die Vorschau unten**, also in der Reihenfolge
   des Dokuments: erst die Eingaben, dann das Ergebnis.

   Vorher stand sie über dem Formular, mit dem Gedanken, der Kunde solle sofort
   sehen, was entsteht. Auf dem Telefon kostet das mehr, als es bringt: die
   Vorschau ist dort fast bildschirmhoch, das erste Eingabefeld liegt damit
   unter der Falte, und der Wizard beginnt mit etwas, das noch leer ist. Wer
   zwischendurch sehen will, wo er steht, scrollt einmal nach unten; wer fertig
   ist, findet das Ergebnis genau dort, wo er ohnehin ankommt.

   Auf breiten Schirmen stehen beide nebeneinander, dort stellt sich die Frage
   nicht. Die Vorschau klebt und bleibt beim Scrollen im Blick. */
@media (min-width: 1000px) {
  .wz-raster { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .wz-vorschau { position: sticky; top: 88px; }
}

/* Der Sprungpunkt beim Schrittwechsel. Die Kopfzeile klebt oben und wäre sonst
   über dem, wohin gescrollt wird: die Schrittanzeige läge darunter, und der
   neue Schritt begänne unsichtbar. */
.wz-steuerung { scroll-margin-top: 84px; }

/* ------------------------------------------------------- Die Schrittanzeige */

/* Knöpfe in einer Liste, kein Klick-Handler auf einem <li>: die Schritte sind
   bedienbar, also sind sie Knöpfe. Umbruch erlaubt, damit drei Namen auf 320 px
   nicht ineinanderlaufen. */
.wz-schritte {
  display: flex;
  flex-wrap: wrap;
  /* Zeilenabstand für den Umbruchfall: auf 320 px stehen die drei Namen
     untereinander und klebten sonst aneinander. */
  gap: 4px clamp(12px, 2.5vw, 28px);
  margin: 0 0 clamp(24px, 4vw, 40px);
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--rule);
}

.wz-schritt-knopf {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 0 2px 12px;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: none;
  font: inherit;
  cursor: pointer;
  color: var(--ink-soft);
}
.wz-schritt-knopf:hover { color: var(--ink); }
.wz-schritt-knopf.aktiv {
  color: var(--ink);
  border-bottom-color: var(--ink);
}
.wz-schritt-knopf:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.wz-nr {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
}
.wz-name { font-size: 14px; font-weight: 500; }

/* ------------------------------------------------------------- Der Slider */

/* Fenster und Bühne sind zwei Kästen. Ein `overflow` auf der Bühne selbst
   schnitte nichts ab: der Klippbereich gehört zur Box und wandert mit ihrem
   `transform` mit, und der ganze Wizard liefe nach links aus der Spalte heraus.
   `clip` statt `hidden`, damit das Fenster kein Scrollcontainer wird. */
/* Der negative Rand plus die Polsterung im Schritt sind ein Puffer an der
   Klippkante: ohne ihn sitzt jedes Feld, das die volle Breite hat, direkt auf
   der Schnittlinie, und sein Fokusrahmen wird links und rechts abgeschnitten.
   Sichtbar blieben nur die Kanten oben und unten. Die Optik ändert sich nicht,
   weil der Rand die Polsterung wieder aufhebt. */
/* Die Höhe folgt dem **sichtbaren** Schritt; das Skript setzt sie. Ohne das
   wäre das Fenster so hoch wie der längste Schritt, und der Fuß mit dem
   Weiter-Knopf stünde auf jedem kürzeren Schritt in der Leere darunter. Der
   Übergang läuft gleich lang wie der seitliche Schub, damit Höhe und Inhalt
   zusammen ankommen. */
.wz-fenster {
  overflow: clip;
  margin-inline: -4px;
  transition: height 260ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
  .wz-fenster { transition: none; }
}
.wz-schritt { padding-inline: 4px; }

.wz-buehne {
  display: flex;
  align-items: start;
  transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
  .wz-buehne { transition: none; }
}
.wz-schritt {
  flex: 0 0 100%;
  min-width: 0;
}
.wz-schritt-titel:focus-visible { outline-offset: 2px; }
.wz-schritt-titel {
  font-size: clamp(20px, 2.4vw, 26px);
  margin: 0 0 6px;
}
/* Der Fokus springt beim Schrittwechsel hierher, damit ein Screenreader den
   neuen Schritt ansagt. Sichtbar soll das nur bei Tastaturbedienung sein. */
.wz-schritt-titel:focus { outline: none; }
.wz-schritt-titel:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.wz-schritt-text {
  margin: 0 0 clamp(20px, 3vw, 28px);
  color: var(--ink-soft);
  font-size: 15px;
  max-width: 52ch;
}

/* ------------------------------------------------------------- Formulare */

.wz-felder { display: grid; gap: clamp(16px, 2vw, 22px); }

.wz-feld {
  margin: 0;
  display: grid;
  gap: 6px;
}
.wz-feld label,
.wz-feld-label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
/* Die Beschriftung einer Option ist Fließtext, keine Rubrik. */
.wz-option label,
.wz-feld .wz-option-text {
  font-family: inherit;
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}
.wz-feld-hinweis {
  font-size: 12.5px;
  color: var(--ink-soft);
  max-width: 56ch;
}
/* Felder, die zusammengehören, stehen nebeneinander: zwei Verlaufsfarben, ein
   Zeitraum, Farbe und Größe einer Zeile. Umbruch statt Quetschen, damit auf
   einem Telefon niemand in einem 40 Pixel breiten Feld tippt. */
.wz-reihe {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
  align-items: end;
}
.wz-reihe > * {
  flex: 1 1 190px;
  min-width: 0;
  margin: 0;
}
/* Zwei Reihen untereinander brauchen denselben Abstand, den eine Reihe zu ihrer
   eigenen naechsten Zeile haelt. Sonst klebt beim Verlauf die Reihe der Regler
   an der Reihe der Farben, und die vier Felder lesen sich als ein Block. */
.wz-reihe + .wz-reihe {
  margin-top: 12px;
}

/* Was zu einer Option gehört, rückt unter sie ein: so ist zu sehen, dass es die
   Folge dieser Wahl ist, und die Farben stehen dort, wo man sie sucht. Keine
   Kante links (Hausregel), die Einrückung trägt die Zuordnung. */
.wz-option-details {
  margin: 2px 0 10px 26px;
}
.wz-option-details:empty { display: none; }

/* ---------------------------------------------------------- Schriftwahl */

/* Jede Schrift zeigt sich selbst. Ein `option` lässt sich nicht in jedem
   Browser mit eigener Schrift setzen, deshalb eine Liste aus Radios. Die
   Familien kommen aus `public/assets/fonts/wizard/fonts.css`, erzeugt von
   `scripts/wizard-schriften.js`: kein fremder Host, auch nicht im Wizard. */
/* Eine feste Spaltenzahl und nicht `auto-fill`.
   Die Haarlinien entstehen aus dem Rasterabstand vor der Flaeche des Rasters.
   Eine Reihe, die nicht aufgeht, zeigt deshalb graue Leerzellen statt leerer
   Kacheln: mit gemischtem Satz wurden aus drei Spalten vier, und neun
   Schriften standen als 4+4+1 mit drei grauen Feldern daneben.
   Eins und drei teilen neun. `test/wizard-view.test.js` haelt fest, dass die
   Zahl der Schriften durch drei teilbar bleibt. */
.wz-schriften {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
}
@media (min-width: 34rem) {
  .wz-schriften { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.wz-schrift {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  background: var(--paper);
  cursor: pointer;
  transition: background 140ms ease;
}
.wz-schrift:hover { background: var(--paper-2); }
.wz-schrift input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.wz-schrift.aktiv {
  background: var(--ink);
  color: var(--paper);
}
.wz-schrift:has(input:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}
/* Der Name ist die Schriftprobe, nicht die Beschriftung der Kachel.
   `.wz-schrift` ist selbst ein `<label>` und erbt deshalb aus `.wz-feld label`
   Mono, Versalien, Sperrung und die zurückgenommene Farbe. Für die Rubrik
   darunter ist das richtig, für die Probe falsch:

   Versalien verbergen genau das, wonach man eine Schrift aussucht. x-Höhe,
   Ober- und Unterlängen, die Form des a und des g, all das ist in
   Großbuchstaben nicht zu sehen, und neun Kacheln sehen dann gleich aus.
   Die Sperrung von 0,06em gehört zur Mono-Rubrik und macht gemischten Satz
   locker.

   Fett, weil die Probe die einzige Stelle ist, an der die Schrift wirkt, und
   weil ein Name in 19px sonst gegen die Fläche verschwindet. Das Schriftblatt
   des Wizards trägt deshalb den Schnitt 700 und nicht 400, siehe
   scripts/wizard-schriften.js: ohne ihn synthetisierte der Browser das Fett
   aus dem Regular, und die Auswahl zeigte verzerrte Formen statt der Schrift. */
.wz-schrift-probe {
  font-size: 19px;
  line-height: 1.2;
  font-weight: 700;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
}
.wz-schrift.aktiv .wz-schrift-probe { color: var(--paper); }
/* Die Beschreibung ist die zweite Schriftprobe, in Lesegröße.
   Neben der Anmutung des Namens steht damit eine Zeile so, wie die Schrift
   spaeter im Fließtext wirkt, und genau daran entscheidet sich, ob eine
   Schrift fuer eine Seite taugt. Deshalb ebenfalls gemischt und ohne die
   Sperrung, die aus der Mono-Beschriftung geerbt waere. */
.wz-schrift-ton {
  font-size: 12.5px;
  line-height: 1.35;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-soft);
}
.wz-schrift.aktiv .wz-schrift-ton { color: var(--on-dark-soft); }

/* Eine Klasse je Familie: ein style-Attribut würde unter `style-src 'self'`
   still verworfen. Die Namen entsprechen den Dateinamen im Schriftblatt. */
.wz-s-inter { font-family: "Inter", sans-serif; }
.wz-s-roboto { font-family: "Roboto", sans-serif; }
.wz-s-instrument-sans { font-family: "Instrument Sans", sans-serif; }
.wz-s-manrope { font-family: "Manrope", sans-serif; }
.wz-s-plus-jakarta-sans { font-family: "Plus Jakarta Sans", sans-serif; }
.wz-s-space-grotesk { font-family: "Space Grotesk", sans-serif; }
.wz-s-bricolage-grotesque { font-family: "Bricolage Grotesque", sans-serif; }
.wz-s-newsreader { font-family: "Newsreader", serif; }
.wz-s-fraunces { font-family: "Fraunces", serif; }

/* Ein Schalter mit zwei Stellungen, gebaut wie der Formatumschalter über der
   Vorschau: dieselbe Bewegung, dieselbe Optik. Darunter liegen Radios, damit
   Tastatur und Screenreader eine Wahl vorfinden und keine zwei Knöpfe. */
.wz-segment {
  display: inline-flex;
  gap: 1px;
  border-block: 1px solid var(--rule);
  inline-size: fit-content;
  max-width: 100%;
}
.wz-segment-teil {
  cursor: pointer;
  color: var(--ink-soft);
}
.wz-segment-teil input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.wz-segment-teil > span {
  display: block;
  padding: 8px 16px;
  font-size: 14px;
  transition: background 140ms ease, color 140ms ease;
}
.wz-segment-teil:hover > span { color: var(--ink); }
.wz-segment-teil.aktiv > span {
  background: var(--ink);
  color: var(--paper);
}
.wz-segment-teil:has(input:focus-visible) > span {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.wz-feld-hinweis[data-art="gut"] { color: #2f6b46; }
.wz-feld-hinweis[data-art="fehler"] { color: #9a2b1f; }

.wz-feld input[type="text"],
.wz-feld input[type="email"],
.wz-feld select {
  font: inherit;
  font-size: 15.5px;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--rule);
  padding: 10px 12px;
  width: 100%;
}
/* **Der Rahmen liegt nach innen, nicht nach außen.**
 *
 * Ein Feld füllt hier die volle Spaltenbreite, und `.wz-fenster` klippt (das
 * muss es, sonst liefe der Schlitten aus seiner Spalte). Ein `outline-offset`
 * nach außen lag damit genau im abgeschnittenen Bereich: sichtbar blieben nur
 * die Kanten oben und unten, links und rechts fehlten. Nach innen gezogen ist
 * der Rahmen vollständig und ersetzt zugleich den Feldrand. */
.wz-feld input:focus-visible,
.wz-feld select:focus-visible,
.wz-feld textarea:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

/* Eine Gruppe fasst zusammen, was inhaltlich zusammengehört, ohne einen Kasten
   zu bauen: eine Haarlinie oben und etwas Luft genügen. */
.wz-gruppe {
  display: grid;
  gap: 14px;
  padding-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid var(--rule);
}
.wz-gruppe-titel {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
}
.wz-gruppe-text {
  margin: -6px 0 2px;
  font-size: 13px;
  color: var(--ink-soft);
  max-width: 56ch;
}

/* --------------------------------------------------------------- Adresse */

/* Feld und Suffix sitzen in einem Kasten, damit `name.clipmark.de` als eine
   Adresse zu lesen ist und nicht als Feld mit einer Bemerkung daneben. */
.wz-adresse {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--rule);
  background: var(--paper);
}
.wz-adresse:focus-within { outline: 2px solid var(--ink); outline-offset: 1px; }
.wz-adresse input {
  border: 0 !important;
  min-width: 0;
  flex: 1 1 auto;
}
.wz-adresse input:focus-visible { outline: none; }
.wz-adresse-suffix {
  display: flex;
  align-items: center;
  padding: 0 12px;
  border-left: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-soft);
  font-family: var(--mono);
  font-size: 13px;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- Farben */

/* Picker und Code nebeneinander: der Picker allein sagt nicht, welcher Wert
   eingestellt ist, und eine Hausfarbe kommt als Hex-Code aus dem Styleguide. */
.wz-farbe { display: flex; gap: 8px; align-items: center; }
.wz-feld input[type="color"] {
  inline-size: 52px;
  block-size: 42px;
  padding: 3px;
  border: 1px solid var(--rule);
  background: var(--paper);
  cursor: pointer;
  flex: 0 0 auto;
}
.wz-farbe-code {
  font-family: var(--mono) !important;
  font-size: 13px !important;
  max-width: 20ch;
}

/* --------------------------------------------------------------- Optionen */

.wz-optionen { display: grid; gap: 10px; }

/* ------------------------------------------------------ Teilen-Knöpfe
 *
 * Ein Raster aus Marken. Die Checkbox liegt in der Kachel und bleibt
 * bedienbar, ist aber unsichtbar: `display: none` nähme sie aus dem
 * Tabulatorlauf, und das Raster wäre nur noch mit der Maus zu bedienen.
 *
 * `auto-fill` statt einer festen Spaltenzahl: die Spalte des Wizards ist
 * schmaler als die Seite, und acht Marken sollen sich umbrechen dürfen, ohne
 * dass für jede Breite ein Haltepunkt gepflegt werden muss. */
.wz-teilen {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 8px;
}

.wz-teilen-kachel {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 14px 8px 12px;
  border: 1px solid var(--rule);
  color: var(--ink-soft);
  cursor: pointer;
  transition: border-color 140ms ease, color 140ms ease, background 140ms ease;
}
.wz-teilen-kachel:hover { border-color: var(--ink-soft); color: var(--ink); }

/* **Der Input ist selbst das Tippziel, nicht ein Pixel in der Ecke.**
   Er liegt unsichtbar über der ganzen Kachel, statt einen Pixel groß geklippt
   darin zu sitzen. `display: none` und `visibility: hidden` scheiden ohnehin
   aus, beide nehmen den Fokus; aber auch die geklippte Fassung verlässt sich
   darauf, dass das Label den Tipp weiterreicht, und diese Weiterleitung ist
   auf Touch-Geräten die wackeligste Stelle der ganzen Konstruktion. So
   entfällt sie: was getroffen wird, ist die Checkbox.

   `appearance: none` nimmt ihr das eigene Aussehen, `opacity: 0` den Rest.
   Sichtbar ist weiterhin nur, was die Kachel zeichnet. */
.wz-teilen-kachel input {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  appearance: none;
  opacity: 0;
  cursor: pointer;
  /* Ohne das wartet iOS auf einen möglichen Doppeltipp zum Zoomen, und die
     Auswahl fühlt sich träge an. */
  touch-action: manipulation;
}

.wz-teilen-zeichen { display: grid; place-items: center; block-size: 24px; }
.wz-teilen-zeichen svg { display: block; }
.wz-teilen-name {
  font-family: var(--mono);
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-align: center;
}

/* Gewählt: gefüllt, wie der aktive Schritt in der Schrittanzeige. Kein Haken
   in der Ecke — die Füllung sagt dasselbe und stört das Zeichen nicht. */
.wz-teilen-kachel.aktiv {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

/* Der Fokusrahmen sitzt an der Kachel, weil die Checkbox keine Fläche hat.
   Nach innen gezogen: `.wz-fenster` klippt, und ein Rahmen nach außen läge im
   abgeschnittenen Bereich. */
.wz-teilen-kachel:has(input:focus-visible) {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

/* Die beiden, die das Bild mitnehmen, tragen einen Punkt. Kein zweites Wort
   unter jedem Namen: der Hinweissatz unter dem Raster erklärt ihn einmal. */
.wz-teilen-kachel[data-mit-bild]::after {
  content: "";
  position: absolute;
  inset-block-start: 6px;
  inset-inline-end: 6px;
  inline-size: 5px;
  block-size: 5px;
  border-radius: 50%;
  background: currentColor;
}

.wz-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
}
.wz-option input {
  margin-top: 3px;
  accent-color: var(--ink);
  flex: 0 0 auto;
}
.wz-option-text { display: grid; gap: 2px; }
.wz-option-name { font-size: 15px; }
.wz-option-hinweis {
  font-size: 12.5px;
  color: var(--ink-soft);
  max-width: 48ch;
}
.wz-marke {
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 2px 6px;
  margin-left: 6px;
  background: var(--paper-2);
  color: var(--ink-soft);
  white-space: nowrap;
}

/* ------------------------------------------------------------ Positionen */

/* Drei Zeilen, je vier Ecken. Ein Klick genügt, und weil belegte Ecken tauschen
   statt zu sperren, gibt es keinen ungültigen Zwischenstand und keine
   Fehlermeldung. */
.wz-pos {
  display: grid;
  gap: 2px;
  border: 1px solid var(--rule);
  background: var(--paper);
}
.wz-pos-zeile {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 12px;
}
.wz-pos-zeile + .wz-pos-zeile { border-top: 1px solid var(--rule); }
.wz-pos-name { font-size: 14px; }
.wz-pos-ecken { display: flex; gap: 4px; }

.wz-pos-ecke {
  display: inline-flex;
  cursor: pointer;
  color: var(--ink-soft);
}
.wz-pos-ecke input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.wz-pos-bild {
  display: inline-flex;
  padding: 5px;
  border: 1px solid transparent;
  transition: color 140ms ease, background 140ms ease, border-color 140ms ease;
}
.wz-pos-ecke:hover .wz-pos-bild { color: var(--ink); border-color: var(--rule); }
.wz-pos-ecke.aktiv .wz-pos-bild {
  color: var(--paper);
  background: var(--ink);
  border-color: var(--ink);
}
.wz-pos-ecke:has(input:focus-visible) .wz-pos-bild {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

/* Für Screenreader lesbar, im Layout nicht vorhanden. */
.wz-nur-lesbar {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* -------------------------------------------------------------- Schieber */

.wz-schieber {
  display: flex;
  align-items: center;
  gap: 12px;
}
.wz-schieber input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
  accent-color: var(--ink);
}
/* Der Schieber füllt die Zeile: mehr als der Puffer an der Klippkante hergibt
   würde links abgeschnitten. */
.wz-schieber input[type="range"]:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
.wz-schieber-wert {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-soft);
  min-width: 3ch;
  text-align: right;
}

/* ---------------------------------------------------------- Datumsauswahl */

/* Feld und Knopf teilen sich einen Kasten, damit der Kalender zum Feld gehört
   und nicht daneben steht. */
.wz-mit-knopf {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--rule);
  background: var(--paper);
  position: relative;
}
.wz-mit-knopf:focus-within { outline: 2px solid var(--ink); outline-offset: -2px; }
.wz-mit-knopf input[type="text"] {
  border: 0 !important;
  min-width: 0;
  flex: 1 1 auto;
}
.wz-mit-knopf input[type="text"]:focus-visible { outline: none; }
.wz-kalender {
  display: flex;
  align-items: center;
  padding: 0 12px;
  border: 0;
  border-left: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-soft);
  cursor: pointer;
}
.wz-kalender:hover { color: var(--ink); }
.wz-kalender:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

/* Die Quelle ist nur der Träger des nativen Kalenders. `showPicker()` öffnet
   ihn ohne sichtbares Feld; wo das fehlt, wird sie eingeblendet. */
.wz-kalender-quelle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.wz-kalender-quelle.sichtbar {
  position: static;
  width: auto;
  height: auto;
  opacity: 1;
  pointer-events: auto;
  font: inherit;
  padding: 10px 12px;
  border: 0;
  border-left: 1px solid var(--rule);
}

/* ------------------------------------------------------------------ Logo */

.wz-logo-zone {
  display: grid;
  gap: 6px;
  justify-items: center;
  padding: 24px 20px;
  border: 1px dashed var(--rule);
  background: var(--paper-2);
  cursor: pointer;
  text-align: center;
  transition: background 160ms ease, border-color 160ms ease;
}
.wz-logo-zone.zieht,
.wz-logo-zone:hover { border-color: var(--ink); background: var(--paper); }
.wz-logo-zone.hat-logo { border-style: solid; background: var(--paper); }
.wz-logo-zeichen {
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
}
/* Der Kasten dahinter zeigt, dass ein transparentes Logo auf hellem Grund
   sitzt: ein weißes Logo auf weißem Grund sähe sonst nach fehlgeschlagenem
   Upload aus. */
.wz-logo-bild {
  max-height: 64px;
  max-width: 100%;
  object-fit: contain;
  margin-bottom: 4px;
}

/* ------------------------------------------------------- Zusammenfassung */

.wz-zusammenfassung {
  display: grid;
  gap: 10px;
  padding: clamp(16px, 2vw, 20px);
  border: 1px solid var(--rule);
  background: var(--paper-2);
}
.wz-liste { margin: 0; display: grid; gap: 6px; }
.wz-liste > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  font-size: 14px;
}
.wz-liste dt { color: var(--ink-soft); }
.wz-liste dd {
  margin: 0;
  text-align: right;
  overflow-wrap: anywhere;
}
.wz-liste-summe {
  padding-top: 8px;
  border-top: 1px solid var(--rule);
  font-weight: 600;
  font-size: 16px !important;
}
.wz-ust {
  margin: 0;
  font-size: 12px;
  color: var(--ink-soft);
}

/* ----------------------------------------------------------------- Vorschau */

.wz-vorschau-kopf {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: end;
  gap: 12px;
  margin-bottom: 14px;
}

.wz-reiter {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--rule);
}
.wz-reiter button {
  font: inherit;
  font-size: 14px;
  padding: 8px 14px 10px;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
}
.wz-reiter button:hover { color: var(--ink); }
.wz-reiter button.aktiv {
  color: var(--ink);
  border-bottom-color: var(--ink);
}
.wz-reiter button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }

.wz-format {
  display: flex;
  gap: 1px;
  border-block: 1px solid var(--rule);
  inline-size: fit-content;
}
.wz-format button {
  font: inherit;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  padding: 8px 14px;
  border: 0;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
}
.wz-format button.aktiv { background: var(--ink); color: var(--paper); }
.wz-format button:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }

/* Die Leinwand: Formatgröße, per CSS herunterskaliert, dasselbe Muster wie auf
   der Kundenseite. **Weder Polsterung noch Rahmen an diesem Kasten**: das
   Skript rechnet den Maßstab aus `clientWidth` und setzt die Höhe, beides würde
   die Bühne aus ihrem Kasten schieben. Der Ring ist deshalb ein box-shadow. */
.wz-rahmen {
  position: relative;
  background: var(--paper-2);
  box-shadow: 0 0 0 1px var(--rule);
  overflow: hidden;
}
#wz-stage { transform-origin: top left; }

/* Der Rahmen um die Seitenvorschau. Feste Höhe, damit der Sprung zwischen den
   Reitern das Layout nicht umbaut. */
.wz-seitenrahmen {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  background: var(--paper);
  height: min(72vh, 720px);
}

/* Die Adressleiste ist eine Attrappe und sagt, unter welcher Adresse die Seite
   später steht. Kein nachgebautes Browserfenster: die Adresse ist die
   Information, Ampelpunkte wären Dekoration. */
.wz-adressleiste {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 8px 12px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink-soft);
  font-family: var(--mono);
  font-size: 12.5px;
  overflow: hidden;
}
.wz-adressleiste-schloss { display: inline-flex; flex: 0 0 auto; }
.wz-adressleiste-url {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wz-seite {
  display: block;
  width: 100%;
  flex: 1 1 auto;
  border: 0;
}

/* --------------------------------------------------------------- Der Fuß */

.wz-fuss {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 12px 16px;
  margin-top: clamp(24px, 3vw, 36px);
  padding-top: 18px;
  border-top: 1px solid var(--rule);
}
/* Zurück steht links, alles andere rechts. */
.wz-fuss [data-zurueck] { margin-right: auto; }

/* Meldungen stehen neben dem Knopf, nicht **auf** ihm: die frühere Fassung
   schrieb Fehler in die Knopfbeschriftung, und der Knopf hieß danach dauerhaft
   "Speichern fehlgeschlagen". */
.wz-status {
  font-size: 13px;
  color: var(--ink-soft);
  text-align: right;
}
.wz-status[data-art="gut"] { color: #2f6b46; }
.wz-status[data-art="fehler"] { color: #9a2b1f; }

.wz-fuss-preis {
  margin: 10px 0 0;
  text-align: right;
  font-size: 13px;
  color: var(--ink-soft);
}

.knopf-voll[disabled] { opacity: 0.55; cursor: progress; }

/* ------------------------------------------------------- Änderungsmodus
 *
 * Der Wizard einer Seite, die es schon gibt. Zwei Dinge sehen anders aus, und
 * beide sagen dasselbe: hier wird geändert, nicht gekauft.
 *
 * Die Adresse steht fest. Gedämpft statt ausgegraut: sie ist keine
 * deaktivierte Bedienung, sondern eine Tatsache, die der Kunde lesen soll. Der
 * Zeiger sagt es beim Hinfassen dazu. */
.wz-adresse.ist-fest {
  background: var(--paper-2);
  color: var(--ink-soft);
}
.wz-adresse.ist-fest input { cursor: not-allowed; }

/* Ein Satz, der eine Folge ankündigt, und deshalb größer als eine Fußnote:
   dass eine Übernahme sofort öffentlich ist, darf man nicht überlesen. */
.wz-hinweis-gross {
  margin: clamp(20px, 3vw, 28px) 0 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-soft);
}
.wz-hinweis-gross b { color: var(--ink); font-weight: 500; }

/* ------------------------------------------ Rückweg aus einer Zahlung
 *
 * Steht zwischen der Schrittanzeige und dem Fenster, also im ersten Blick.
 * Wer von einer abgebrochenen Zahlung zurückkommt, braucht die Erklärung
 * sofort; über dem Bestellknopf läge sie unterhalb des sichtbaren Bereichs.
 *
 * Auffällig, aber ohne Signalfarbe: eine abgebrochene Zahlung ist kein Fehler
 * des Kunden, sondern eine Lage, aus der es weitergeht. Derselbe Zuschnitt wie
 * der Demohinweis, nur mit durchgezogener Linie: gestrichelt liest sich als
 * Platzhalter. */
.wz-zahlung {
  margin: 0 0 clamp(16px, 2.5vw, 24px);
  padding: 12px 14px;
  border: 1px solid var(--rule);
  background: var(--paper-2);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
}

/* ----------------------------------------------------- Hinweis im Demobetrieb
 *
 * Steht über dem Fuß mit dem Bestellknopf, nicht als Band am Seitenkopf: dort
 * überliest man ihn auf dem Weg durch die Schritte, hier steht er genau in dem
 * Moment, in dem jemand auf „bestellen" zielt.
 *
 * Auffällig, aber nicht alarmierend: gestrichelter Rahmen wie die Logo-Zone,
 * keine Signalfarbe. Es ist kein Fehler, sondern eine Ansage. */
.wz-demo {
  margin: clamp(20px, 3vw, 28px) 0 0;
  padding: 12px 14px;
  border: 1px dashed var(--rule);
  background: var(--paper-2);
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.5;
}
.wz-demo b { color: var(--ink); font-weight: 500; }


/* Deckkraft neben der Farbe.
   `input type="color"` kennt keinen Alphakanal, weder das Element noch der
   native Dialog. Ein `rgba()` liess sich deshalb nur eintippen, und der Picker
   daneben verschluckte die Transparenz beim naechsten Antippen. Der Regler
   setzt sie getrennt; die Farbe bleibt dabei unberuehrt und umgekehrt. */
.wz-deckkraft {
  display: grid;
  gap: 4px;
  margin-top: 10px;
}
.wz-deckkraft > label {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}