/* ==========================================================================
   Bestell-Wizard (Startseite)
   Mobile-first: Basisstile gelten für schmale Viewports, Breakpoints
   erweitern das Layout für Tablet/Desktop.
   ========================================================================== */

.shop-wizard {
  flex: 1 0 auto; /* füllt <main>, damit der graue Hintergrund statt Weissraum bis zum Footer reicht (siehe Sticky-Footer-Regeln in index.css) */
  padding: clamp(24px, 4vw, 48px) clamp(18px, 5vw, 56px) clamp(48px, 8vw, 96px);
  background: var(--soft-grey);
  scroll-margin-top: 84px; /* Anker-Sprung berücksichtigt den sticky Header */
}

.wizard-shell {
  max-width: 760px;
  margin: 0 auto;
}

/* Produktschritt auf der Startseite darf breiter sein, damit die Karten
   nicht zu schmal gequetscht werden. */
.wizard-shell.wizard-shell--wide {
  max-width: 1180px;
}

/* ---- Fortschrittsanzeige ---- */

.wizard-progress {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
}

/* Drei unterscheidbare Zustände: kommend = grauer Kreis + gedämpfter Text,
   aktiv = roter, ausgefüllter Kreis + fetter Text, erledigt = grüner Kreis
   mit Häkchen (gleiches Icon wie sonst auf der Seite) statt Zahl. */
.wizard-progress li {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
}

.wizard-progress-num {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--mid-grey);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 700;
}

.wizard-progress-num svg {
  display: block;
  width: 12px;
  height: 12px;
}

.wizard-progress li.active {
  color: var(--strong);
  font-weight: 700;
}

.wizard-progress li.active .wizard-progress-num {
  background: var(--red);
  color: var(--paper);
}

.wizard-progress li.done {
  color: var(--strong);
}

.wizard-progress li.done .wizard-progress-num {
  background: var(--pure-green);
  color: var(--paper);
}

/* ---- Panel / Steps ---- */

.wizard-panel {
  background: var(--paper);
  border-radius: var(--box-radius);
  padding: clamp(20px, 4vw, 36px);
  box-shadow: 0 1px 0 var(--mid-grey);
}

/* Personalisierungs-Schritt (Konfigurator, data-stage="config"): hier stellen
   die .wizard-subcard-Karten selbst die weisse Fläche (siehe oben) - die
   grosse weisse .wizard-panel-Fläche würde sonst als zusätzliche, sichtbare
   Box um die Karten herum stehen bleiben. Nur für diesen einen Schritt
   deaktiviert, die anderen Schritte (Bemerkung, Adresse, Zusammenfassung)
   behalten die grosse weisse Fläche. */
.wizard-panel:has(> section[data-stage="config"]:not(.hidden)) {
  background: transparent;
  box-shadow: none;
  /* Ohne sichtbaren Titel (siehe config-step-title) bleibt hier sonst der
     normale .wizard-panel-Abstand nach oben übrig - dadurch startet der
     Inhalt tiefer als die Bestellung-Box rechts und der Abstand zur
     Fortschrittsliste (1-2-3-4-5) wirkt zu gross. Die Karten bringen ihr
     eigenes Padding selbst mit. */
  padding-top: 0;
  /* Links/rechts ebenfalls entfernt - vorher hatten die Karten links/rechts
     das Panel-Padding UND ihr eigenes (siehe .wizard-subcard), dadurch
     waren sie schmaler/stärker eingerückt als die Bestellung-Box rechts
     bzw. (gestapelt, Tablet) darunter, die nur ihr eigenes Padding hat. */
  padding-left: 0;
  padding-right: 0;
}

/* ---- Zweispaltiges Layout: Panel links, Bestell-Übersicht rechts ---- */

.wizard-layout {
  display: flex;
  align-items: flex-start;
  gap: 32px;
}

.wizard-layout > .wizard-panel {
  flex: 1 1 auto;
  min-width: 0;
}

.wizard-aside {
  position: sticky;
  top: 96px;
  width: 340px;
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Schritt "config" ohne Personalisierung: das Panel links enthält dann nur
   noch einen Hinweistext ("...rechts in der Bestell-Übersicht...") - statt
   einer leeren linken Spalte blenden wir das Panel aus und zentrieren die
   Bestellung stattdessen (siehe product.js, goToStage()). */
.wizard-layout.wizard-layout--center-aside {
  justify-content: center;
}

.wizard-layout--center-aside > .wizard-panel {
  display: none;
}

.wizard-layout--center-aside > .wizard-aside {
  position: static;
  width: 100%;
  max-width: 420px;
}

/* Bemerkung/Adresse/Zusammenfassung: keine Bestellung-Box mehr nötig, siehe
   product.js goToStage() - die Buttons sitzen dort bereits im
   .wizard-nav-slot direkt unter dem Inhalt, Menge/Preis wären nur doppelt. */
.wizard-layout--hide-aside > .wizard-aside {
  display: none;
}

/* Ohne die Bestellung-Box daneben würde das Panel die volle Shell-Breite
   einnehmen - Felder wie das Bemerkung-Textarea wären dadurch unnötig breit.
   Gleiches Prinzip wie .wizard-layout--center-aside oben: einziges
   sichtbares Kind wird auf eine angenehme Breite begrenzt und zentriert. */
.wizard-layout.wizard-layout--hide-aside {
  justify-content: center;
}

.wizard-layout--hide-aside > .wizard-panel {
  max-width: 65%;
}

.wizard-summary-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--paper);
  border-radius: var(--box-radius);
  padding: 20px;
  box-shadow: 0 1px 0 var(--mid-grey);
}

/* .wizard-field wird auch ausserhalb der Summary-Card verwendet (Adress-
   /Bemerkung-Formular) und braucht dort weiterhin sein eigenes margin-bottom
   - deshalb hier gezielt nur für die direkten Kinder der Summary-Card
   zurückgesetzt, nicht global. */
.wizard-summary-card > .wizard-field {
  margin-bottom: 0;
}

.wizard-summary-heading {
  font-size: var(--fs-base);
  font-weight: 600;
  margin-bottom: 0;
}

/* .wizard-field setzt "display: grid"; dessen Default "justify-items: stretch"
   streckt .wizard-stepper (keine eigene Breite) auf die volle Zeilenbreite -
   die leere Fläche rechts vom sichtbaren Pill gehörte dadurch technisch zur
   Stepper-Box und reagierte auf Hover/Klick. "justify-items: start" lässt den
   Stepper auf seine Inhaltsbreite schrumpfen. */
.wizard-qty-row {
  justify-items: start;
}

.wizard-qty-row .wizard-field-error {
  flex-basis: 100%;
}

.wizard-qty-label {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--strong);
}

.wizard-stepper {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--soft-grey);
  border-radius: 11px;
  overflow: hidden;
}

.wizard-stepper-btn {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  color: var(--strong);
  font-size: var(--fs-base);
  font-weight: 700;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .wizard-stepper-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--red) 10%, var(--soft-grey));
  }
}

.wizard-stepper-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.wizard-stepper input {
  width: 40px;
  height: 32px;
  border: 0;
  border-radius: 0;
  background: transparent;
  text-align: center;
  font-size: var(--fs-sm);
  font-weight: 700;
  padding: 0;
}

.wizard-stepper input::-webkit-outer-spin-button,
.wizard-stepper input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.wizard-stepper input[type="number"] {
  -moz-appearance: textfield;
}

.wizard-stepper input:disabled {
  color: var(--muted);
}

.wizard-summary-lines {
  display: flex;
  flex-direction: column;
  gap: 7px;
  background: var(--soft-grey);
  border-radius: 13px;
  padding: 12px 14px;
}

.wizard-summary-lines .wizard-summary-line {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--muted);
}

.wizard-summary-lines .wizard-summary-line b {
  color: var(--strong);
  font-weight: 600;
  text-align: right;
}

.wizard-summary-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.wizard-summary-total span:first-child {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--strong);
}

.wizard-summary-total span:last-child {
  font-size: var(--fs-xl);
  font-weight: 800;
  color: var(--red);
}

.wizard-trust {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 0 4px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--muted);
  margin-bottom: 0;
}

@media (max-width: 960px) {
  .wizard-layout {
    flex-direction: column;
    /* Gestapelt wird der 32px-gap zur vertikalen Lücke und würde sich zum
       Padding-Bottom des Panels (.wizard-panel, clamp 20-36px) addieren -
       das Panel-Padding reicht als Abstand. */
    gap: 0;
  }

  .wizard-aside {
    position: static;
    width: 100%;
  }

  /* .wizard-layout hat "align-items: flex-start" (für die Desktop-Reihe,
     damit Panel/Bestellung nicht auf gleiche Höhe gezwungen werden) - im
     gestapelten (column) Zustand wird das aber zur Cross-Achse (horizontal)
     und verhindert das Strecken auf volle Breite. Gleiches Gegenstück wie
     das explizite width:100% bei .wizard-aside oben. */
  .wizard-layout > .wizard-panel {
    width: 100%;
  }

  .wizard-layout--hide-aside > .wizard-panel {
    max-width: 100%;
  }
}

.wizard-step-title {
  font-size: clamp(1.25rem, 3vw, 1.625rem);
  margin-bottom: 18px;
}

.wizard-field {
  display: grid;
  gap: 7px;
  font-weight: 500;
  margin-bottom: 16px;
}

.wizard-field input,
.wizard-field textarea {
  max-width: 280px;
}

.wizard-field textarea {
  max-width: none;
}

/* Browser-Standardpfeil sitzt zu nah am rechten Rand (kein appearance:none
   irgendwo global gesetzt, siehe global.css) - eigenes, kleines Chevron-SVG
   mit deutlich mehr Abstand zum Rand statt des nativen Pfeils. */
.wizard-field select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 42px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23565858' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 16px center;
  background-size: 14px;
}

.wizard-hint {
  display: block;
  color: var(--muted);
  font-weight: 400;
  font-size: var(--fs-sm);
  /* margin: 0 statt nur margin-bottom: 0 - der Browser-Default-margin-top
     von <p> addierte sich sonst zum flex-gap der umgebenden .wizard-subcard
     (siehe dort) und liess z.B. zwei aufeinanderfolgende .wizard-hint-
     Absätze mit unnötig grossem Abstand erscheinen. */
  margin: 0;
}

/* Zusätzlich zu .wizard-hint (nicht statt) auf dem <p> gesetzt (siehe
   faceFileGroupTemplate() in wizard-step.js), daher hier nur die
   Abweichungen Farbe/Hintergrund/Rahmen/Abstand. */
.wizard-hint--info {
  color: var(--black);
  background: rgba(var(--gold-rgb), 0.12);
  border: 1px solid rgba(var(--gold-rgb), 0.45);
  border-radius: var(--box-radius);
  padding: 10px 12px;
}

.wizard-message {
  min-height: 20px;
  font-weight: 500;
  text-align: center;
  margin: 0 0 16px;
}

/* Leer (kein Status-Text aktuell, siehe product.js messageEl.textContent =
   "") - dann auch keinen Platz reservieren, sonst bleibt eine unbegründete
   Lücke stehen, die auf Mobile besonders auffällt. */
.wizard-message:empty {
  min-height: 0;
  margin: 0;
}

/* ---- Auswahlkarten (Kategorie / Sprache) ----------------------------------
   Flache Karten wie im Design: Bild oben, Text darunter, Preis und Button
   am Kartenende. Keine Rundung, kein Schatten; getrennt durch eine feine
   Linie, Hover mit leichter Tönung. Gilt für Startseite, /products und den
   Variantenschritt. */

.wizard-choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: 0;
}

.wizard-choice-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 100%;
  text-align: left;
  padding: 28px 28px 26px;
  background: transparent;
  border: 0;
  border-left: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 0;
  box-shadow: none;
  cursor: pointer;
  font-family: inherit;
  color: var(--text-dark);
  transition: background 0.25s ease;
}

.wizard-choice-card:first-child {
  border-left: 0;
}

.wizard-choice-card > span {
  display: block;
}

@media (hover: hover) and (pointer: fine) {
  .wizard-choice-card:hover:not(:disabled) {
    background: rgba(112, 58, 62, 0.14);
  }

  .choice-card-btn:hover {
    background: var(--red-light);
  }
}

.wizard-choice-card:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: -2px;
}

.choice-card-media {
  position: relative;
  width: 100%;
  margin-bottom: 18px;
}

.choice-card-media img {
  display: block;
  width: 100%;
  height: 260px;
  object-fit: contain;
  object-position: left center;
}

.wizard-choice-card .wizard-choice-label {
  font-family: var(--font-heading);
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--text-dark);
  margin-bottom: 6px;
}

.wizard-choice-card .wizard-choice-desc {
  max-width: 340px;
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--text-dark);
}

/* Mit .wizard-choice-card davor, sonst überschreibt `.wizard-choice-card > span
   { display: block }` das flex (und damit das gap). */
.wizard-choice-card .choice-card-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: auto;
  padding-top: 10px;
}

.choice-card-price .price-number {
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--text-dark);
}

.choice-card-price .price-label {
  font-size: 0.74rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--text-dark);
}

.choice-card-btn {
  margin-top: 18px;
  padding: 12px 30px;
  background: var(--red);
  color: var(--cream);
  font-size: var(--fs-base);
  font-weight: 700;
  border-radius: var(--button-radius);
  transition: background 0.2s ease;
}

/* Karte, die auf eine andere Seite führt (Spielanfrage): echter Link statt
   Button. Ohne Preis steht der Button am Kartenende. Das Foto füllt den
   Bildbereich (cover), die Kartenbilder daneben sind freigestellt (contain). */
a.wizard-choice-card {
  text-decoration: none;
}

.wizard-choice-card--link .wizard-choice-desc {
  margin-bottom: 18px;
}

.wizard-choice-card--link .choice-card-btn {
  margin-top: auto;
}

.choice-card-media--cover img {
  object-fit: cover;
  object-position: center;
}

/* Variantenschritt («Welches Kartenbild?»): ohne Button, dafür jede Karte
   einzeln umrandet, damit auch auf Mobile klar ist, was zusammengehört. */
.wizard-choice-grid[data-choice-group="variant"] {
  gap: 16px;
}

.wizard-choice-grid[data-choice-group="variant"] .wizard-choice-card {
  border: 1px solid var(--mid-grey);
}

.wizard-choice-card:disabled {
  cursor: not-allowed;
}

.wizard-choice-card:disabled .choice-card-media,
.wizard-choice-card:disabled .wizard-choice-label,
.wizard-choice-card:disabled .wizard-choice-desc,
.wizard-choice-card:disabled .choice-card-price {
  opacity: 0.6;
}

.wizard-choice-badge {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--mid-grey);
  padding: 4px 8px;
  border-radius: 999px;
  margin-bottom: 6px;
}

/* Liegt im Bildbereich (.choice-card-media) und ist dort zentriert. Dunkler,
   halbtransparenter Hintergrund, damit der Text auf jedem Foto lesbar bleibt. */
.choice-card-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  margin-bottom: 0;
  max-width: calc(100% - 24px);
  padding: 8px 16px;
  border-radius: var(--box-radius);
  font-size: clamp(0.75rem, 1.5vw, 0.9375rem);
  letter-spacing: 0.04em;
  text-align: center;
  color: white;
  background: rgba(var(--overlay-rgb), 0.82);
}

/* Einspaltig (Mobile): waagrechte statt senkrechter Trennlinie, damit klar
   bleibt, wo eine Karte aufhört. Der Variantenschritt hat eigene Rahmen. */
@media (max-width: 600px) {
  .wizard-choice-grid {
    grid-template-columns: 1fr;
  }

  .wizard-choice-grid:not([data-choice-group="variant"]) .wizard-choice-card {
    border-left: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.07);
  }

  .wizard-choice-grid:not([data-choice-group="variant"]) .wizard-choice-card:first-child {
    border-top: 0;
  }
}

@media (max-width: 720px) {
  .choice-card-media img {
    height: 200px;
  }

  .wizard-choice-card .wizard-choice-label {
    font-size: 1.15rem;
  }

  .wizard-choice-card .wizard-choice-desc {
    font-size: 0.9rem;
  }
}

/* ---- Personalisierung ---- */

/* Umgibt jeden inhaltlichen Teilschritt innerhalb der "config"-Stufe
   (Personalisierungsart / Bildkarten wählen / Fotos hochladen) mit einem
   eigenen, leicht abgesetzten Block + Nummer-Label: jeder Schritt ist eine
   eigene weisse Karte auf grauem Grund (.shop-wizard-Hintergrund), nicht
   mehr grau innerhalb der weissen .wizard-panel-Fläche (siehe
   .wizard-panel:has(...) weiter oben, das die eigene weisse Fläche nur für
   den Personalisierungs-Schritt abschaltet).
   Flex-Column + gap statt einzelner margin-bottom-Werte an jedem Kind - die
   einzelnen Kinder haben ihr eigenes margin-bottom entfernt (siehe
   .wizard-kicker, .wizard-personalization-options,
   .wizard-face-figure-select, .wizard-face-tabs weiter unten). */
.wizard-subcard {
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--paper);
  border-radius: var(--box-radius);
  padding: 18px;
  box-shadow: 0 1px 0 var(--mid-grey);
}

.wizard-subcard > .wizard-group-error,
.wizard-subcard > .wizard-field-error {
  margin-bottom: 0;
}

.wizard-kicker {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin-bottom: 0;
}

.wizard-kicker-num {
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--red);
  /* "Schritt 2" soll nie zwischen Wort und Zahl umbrechen - sonst bricht auf
     schmalen Screens eher das (mit dem Kicker in einer Flex-Reihe stehende)
     .wizard-kicker-title um. */
  white-space: nowrap;
}

.wizard-kicker-title {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--strong);
}

/* ---- Personalisierungsart: Karten statt einfacher Checkbox-Liste ---- */

.wizard-type-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.wizard-type-card {
  position: relative;
  display: block;
  border-radius: 14px;
  padding: 0;
  background: var(--soft-grey);
  cursor: pointer;
}

/* Natives Checkbox-Element bleibt real vorhanden (Tastatur/Screenreader),
   ist aber visuell versteckt - die Karte selbst übernimmt die Darstellung. */
.wizard-type-card input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.wizard-type-card-body {
  display: block;
  /* .wizard-type-card (Grid-Item) wird per align-items:stretch auf die Höhe
     der grössten Karte in der Zeile gestreckt - ohne height:100% bliebe
     .wizard-type-card-body nur so hoch wie der eigene Inhalt, darunter
     bliebe der graue Kartenhintergrund statt der roten Auswahlfarbe
     sichtbar. */
  height: 100%;
  padding: 14px;
  border-radius: 14px;
}

.wizard-type-card input:checked ~ .wizard-type-card-body {
  background: color-mix(in srgb, var(--red) 8%, var(--paper));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 25%, transparent);
}

/* Hover nur bei freigeschalteten, noch nicht ausgewählten Karten - Häkchen
   bleibt aus (kein :checked), Hintergrund sieht aber wie ausgewählt aus.
   Nur für echte Maus-Geräte: auf Touch-Geräten bleibt :hover nach dem
   Tippen sonst oft hängen, die Karte wirkte beim Abwählen weiter markiert. */
@media (hover: hover) and (pointer: fine) {
  .wizard-type-card:not(.disabled):hover input:not(:checked) ~ .wizard-type-card-body {
    background: color-mix(in srgb, var(--red) 8%, var(--paper));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--red) 25%, transparent);
  }
}

.wizard-type-card input:focus-visible ~ .wizard-type-card-body {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.wizard-type-card-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.wizard-type-card-name {
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--strong);
}

/* Immer sichtbar (nicht nur wenn ausgewählt): leere Checkbox-Outline an
   derselben Stelle, wo bei Auswahl das rote Häkchen und bei gesperrten
   Karten das Schloss erscheint. */
.wizard-type-card-badge {
  display: flex;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: 6px;
  border: 1.5px solid var(--mid-grey);
  background: var(--paper);
  color: transparent;
  align-items: center;
  justify-content: center;
}

.wizard-type-card-badge svg {
  display: block;
  width: 13px;
  height: 13px;
}

.wizard-type-card input:checked ~ .wizard-type-card-body .wizard-type-card-badge {
  border-color: transparent;
  background: var(--red);
  color: var(--paper);
}

.wizard-type-card-lock {
  display: flex;
  color: var(--muted);
}

.wizard-type-card-lock svg {
  display: block;
  width: 15px;
  height: 15px;
}

.wizard-type-card-note {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--muted);
}

/* Gesperrte Karten (zu geringe Menge) zeigen nur das Schloss, keinen
   Auswahl-Zustand - Klick bleibt über :disabled ohnehin wirkungslos. */
.wizard-type-card.disabled {
  opacity: 0.65;
  cursor: not-allowed;
}

.wizard-type-card.disabled .wizard-type-card-name {
  color: var(--muted);
}

.wizard-type-card:not(.disabled) .wizard-type-card-lock {
  display: none;
}

.wizard-type-card.disabled .wizard-type-card-badge {
  display: none !important;
}

.wizard-personalization-options.has-error {
  box-shadow: inset 0 0 0 2px var(--red);
  border-radius: var(--box-radius);
  padding: 10px;
  margin: -10px -10px 0;
}

#pw-special_wishes-row.disabled,
#pw-back-row.disabled {
  opacity: 0.55;
}

@media (max-width: 619px) {
  .wizard-type-grid {
    grid-template-columns: 1fr;
  }

  /* Nur auf Mobile: Figuren volle Breite gestapelt statt nebeneinander,
     Farben festes 2x2 statt flex-wrap (das mal 3+1, mal 2+2 umbrach) - auf
     Tablet/Desktop ist genug Platz, dort bleibt die ursprüngliche Reihe
     unverändert. */
  .wizard-face-figure-select {
    flex-direction: column;
    gap: 10px;
  }

  .wizard-face-suits {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
  }

  .wizard-chip-body {
    width: 100%;
    justify-content: center;
  }
}

.wizard-consent {
  margin: 16px 0;
}

.wizard-consent .checkbox-row {
  align-items: flex-start;
  background: transparent;
  padding: 0;
}

.wizard-consent .checkbox-row input {
  margin-top: 2px;
}

.wizard-consent.has-error {
  box-shadow: inset 0 0 0 2px var(--red);
}

/* Natives <details>/<summary> (siehe faceFileGroupTemplate() in
   wizard-step.js), damit sich der standardmässig offene Kasten ([open] im
   Markup) manuell einklappen lässt. Gleiche Info-Box-Optik wie
   .wizard-hint--info, mit eigenem Radius/Padding fürs <details>-Element. */
.wizard-ai-checklist {
  border-radius: var(--button-radius);
  background: rgba(var(--gold-rgb), 0.12);
  border: 1px solid rgba(var(--gold-rgb), 0.45);
  padding: 8px 12px;
}

.wizard-ai-checklist[open] {
  padding-bottom: 10px;
}

.wizard-ai-checklist-summary {
  cursor: pointer;
  color: var(--black);
  font-weight: 600;
  font-size: var(--fs-sm);
}

.wizard-ai-checklist-list {
  margin: 8px 0 0;
  padding-left: 20px;
  color: var(--black);
  font-size: var(--fs-sm);
  display: grid;
  gap: 4px;
}

.wizard-file-groups {
  display: grid;
  gap: 16px;
  margin: 18px 0 16px;
}

.wizard-file-group {
  background: var(--soft-grey);
  border-radius: var(--box-radius);
  padding: 16px;
}

/* Gesicht-Gruppe ist in zwei eigene .wizard-subcard-Karten aufgeteilt
   ("Bildkarten wählen" / "Fotos hochladen") - der äussere
   .wizard-file-group-Wrapper bleibt aus JS-Gründen bestehen (Kategorie-
   Zuordnung, Fehler-Highlighting), braucht aber keinen eigenen
   Hintergrund/Padding mehr, sonst gäbe es eine graue Box in der grauen Box. */
.wizard-file-group[data-file-category="face"] {
  background: transparent;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* "Rückseite" und "Spezielle Wünsche" haben je nur eine einzelne
   .wizard-subcard - gleicher Grund wie bei "Gesicht" oben: der äussere
   Wrapper braucht keinen eigenen Hintergrund/Padding. */
.wizard-file-group[data-file-category="special_wishes"],
.wizard-file-group[data-file-category="back"] {
  background: transparent;
  padding: 0;
}

/* Das Textfeld ist ein Kind von .wizard-subcard (flex + gap:12px, siehe
   oben) - eigenes margin-bottom würde den Abstand zu den Referenzbildern
   darunter verdoppeln. */
.wizard-file-group[data-file-category="special_wishes"] .wizard-field {
  margin-bottom: 0;
}

/* Select + Textarea sind Kinder von [data-box-front-card] (.wizard-subcard,
   flex + gap:12px, siehe oben) - eigenes margin-bottom (auch mit .has-error)
   würde den Abstand zum Text-Umschalter/Textfeld darunter verdoppeln,
   gleiches Prinzip wie bei "Spezielle Wünsche" oben. */
[data-box-front-card] .wizard-field {
  margin-bottom: 0;
}

.wizard-optional-note {
  font-weight: 400;
  color: var(--muted);
}

.wizard-special-wishes-files {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.wizard-special-wishes-files .wizard-field-label {
  font-weight: 500;
  margin: 0;
}

.wizard-special-wishes-files .wizard-add-file-slot {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.wizard-special-wishes-files .wizard-add-file-slot svg {
  display: block;
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.wizard-file-group.has-error {
  box-shadow: inset 0 0 0 2px var(--red);
}

/* Bei "Gesicht" stecken "Bildkarten wählen" und "Fotos hochladen" in
   derselben .wizard-file-group (siehe oben) - der Fehler betrifft aber nur
   die Uploads, nicht die separate "Vorderseite Verpackung"-Karte
   (data-box-front-card). Ohne dieses Override ginge der rote Rahmen um die
   ganze (transparente) Gruppe und würde als Linie zwischen den Karten
   durchscheinen. */
.wizard-file-group[data-file-category="face"].has-error {
  box-shadow: none;
}

.wizard-file-group[data-file-category="face"].has-error > .wizard-subcard:not([data-box-front-card]) {
  box-shadow: inset 0 0 0 2px var(--red);
}

.wizard-group-error {
  color: var(--red);
  font-weight: 500;
  font-size: var(--fs-sm);
  margin: 0 0 10px;
}

.wizard-group-error:empty {
  display: none;
}

/* .wizard-file-slots setzt selbst kein margin-bottom - Abstand nach oben
   hier ergänzt, damit die Fehlermeldung nicht direkt an den Kacheln klebt. */
.wizard-file-group > .wizard-file-slots + .wizard-group-error {
  margin-top: 10px;
}

/* In .wizard-special-wishes-files übernimmt bereits der flex gap (10px) den
   Abstand zu Kacheln/Button - eigenes margin würde ihn nur verdoppeln. */
.wizard-special-wishes-files > .wizard-group-error {
  margin: 0;
}

/* margin-top: -10px zieht das Fieldset enger an den Kicker heran. Das
   <legend> übernimmt die Rolle des Hinweistexts, ist aber Kind dieses
   Fieldsets statt eigenes Geschwister-Element - daher der negative Margin
   hier statt an einem separaten Hinweis-Element. */
.wizard-face-figure-select {
  border: 0;
  padding: 0;
  margin: -10px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}

.wizard-face-figure-select legend,
.wizard-face-suits legend {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--muted);
  padding: 0;
  width: 100%;
}

/* Schritt-2-Legend ist quasi der Untertitel zum Kicker darüber - grösserer
   Abstand nach unten zu den Bildkarten-Chips (siehe .wizard-face-figure-select
   margin-top: -10px, das Fieldset zieht sich eng an den Kicker). */
.wizard-face-figure-select legend {
  margin-bottom: 12px;
}

/* "Welche Farben?" beschreibt dagegen direkt die Farb-Chips darunter, nicht
   die ganze Sektion - deshalb hier eng am eigenen Inhalt statt am Tab davor. */
.wizard-face-suits legend {
  margin-bottom: 6px;
}

/* ---- Chips: Figuren- und Farbauswahl ---- */

.wizard-chip {
  position: relative;
  display: block;
  cursor: pointer;
}

.wizard-chip input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.wizard-chip-body {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 15px;
  border-radius: 11px;
  background: var(--soft-grey);
  color: var(--strong);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.wizard-chip input:checked ~ .wizard-chip-body {
  background: var(--red);
  color: var(--paper);
}

.wizard-chip input:checked ~ .wizard-chip-body .suit-red {
  color: var(--paper);
}

/* Hover bei noch nicht ausgewählten Chips sieht wie der ausgewählte Zustand
   aus, das Häkchen bleibt aber aus (nur von :checked gesteuert). Nur für
   echte Maus-Geräte: auf Touch-Geräten bleibt :hover nach dem Tippen sonst
   oft hängen, der Chip wirkte beim Abwählen weiter ausgewählt. */
@media (hover: hover) and (pointer: fine) {
  .wizard-chip:hover input:not(:checked) ~ .wizard-chip-body {
    background: var(--red);
    color: var(--paper);
  }

  .wizard-chip:hover input:not(:checked) ~ .wizard-chip-body .suit-red {
    color: var(--paper);
  }
}

.wizard-chip input:focus-visible ~ .wizard-chip-body {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.wizard-chip-mark {
  display: inline-flex;
  align-items: center;
  opacity: 0.9;
}

.wizard-chip-mark svg {
  display: block;
  width: 12px;
  height: 12px;
}

/* Nicht ausgewählt: Plus - ausgewählt: Häkchen. Muss spezifischer sein als
   ".wizard-chip-mark svg" oben (Klasse + Typ-Selektor), sonst gewinnt die
   generische Regel und das Häkchen bleibt immer sichtbar. */
.wizard-chip-mark svg.wizard-chip-mark-check {
  display: none;
}

.wizard-chip input:checked ~ .wizard-chip-body .wizard-chip-mark-plus {
  display: none;
}

.wizard-chip input:checked ~ .wizard-chip-body .wizard-chip-mark-check {
  display: block;
}

.wizard-face-card-fields {
  display: grid;
  gap: 12px;
}

.wizard-face-figure-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: var(--paper);
  border-radius: var(--box-radius);
}

.wizard-face-suits {
  border: 0;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.wizard-face-same-photo-row {
  margin-bottom: 0;
}

/* Herz und Eck sind auf den Jasskarten selbst rot gedruckt, Kreuz und
   Schaufel schwarz - das übernehmen wir hier bei der Farbauswahl. */
.suit-red {
  color: var(--red);
  font-weight: 600;
}

/* ---- "Gut zum Druck"-Vorschau (Modal) - siehe openBoxPreview() in
   wizard-step.js. Natives <dialog>, gleiches Grundmuster wie
   .example-lightbox (index.css): eigenes Rahmen/Radius/Schatten statt der
   Browser-Standardbox, ::backdrop für den abgedunkelten Hintergrund. */
.wizard-box-preview-modal {
  width: min(360px, calc(100vw - 32px));
  padding: 0;
  border: 0;
  border-radius: var(--box-radius);
  background: var(--paper);
  box-shadow: 0 24px 80px rgba(var(--overlay-rgb), 0.24);
}

.wizard-box-preview-modal::backdrop {
  background: rgba(var(--overlay-rgb), 0.72);
}

.wizard-box-preview-modal-body {
  position: relative;
  display: grid;
  gap: 14px;
  padding: clamp(20px, 4vw, 32px);
}

.wizard-box-preview-modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--soft-grey);
  color: var(--ink);
  cursor: pointer;
}

.wizard-box-preview-modal-close svg {
  width: 16px;
  height: 16px;
}

.wizard-box-preview-modal-title {
  margin: 0;
  padding-right: 32px;
  font-weight: 600;
  color: var(--strong);
  text-align: center;
}

/* Kartenformat 57 x 89mm (siehe PrintPdfService::CARD_WIDTH/HEIGHT_PT) - die
   Foto- und Schablonen-Ebene darunter/darüber sind nur in diesem
   Seitenverhältnis korrekt zueinander positioniert. Hintergrund weiss statt
   grau, da es kein Bild-Asset für den Kartenhintergrund gibt - weiss kommt
   dem echten Kartenpapier am nächsten. Dünner Rand statt Schatten, um die
   Karte gegen den ebenfalls weissen Modal-Hintergrund abzugrenzen. */
.wizard-box-preview-card {
  position: relative;
  width: min(260px, 60vw);
  aspect-ratio: 57 / 89;
  margin: 0 auto;
  border: 1px solid var(--mid-grey);
  border-radius: var(--button-radius);
  overflow: hidden;
  background: var(--paper);
}

/* Schwarze Rand-Linie kurz vor der Schnittkante, wie auf dem echten
   Jasskarten-Andruck: ca. 3.5mm Abstand zur Schnittkante bei 57 x 89mm
   Kartenformat (6.1% der Breite / 3.9% der Höhe, je Achse einzeln, da die
   Karte nicht quadratisch ist) und ca. 2.7mm Eckenradius (5.4% / 3.3% der
   dadurch entstehenden kleineren Innenfläche - border-radius-Prozente
   beziehen sich auf die eigene Box, nicht auf die Karte). Als ::after statt
   eigenem Element, liegt dank normaler Stapelreihenfolge über Foto und
   Schablone. */
.wizard-box-preview-card::after {
  content: '';
  position: absolute;
  inset: 3.9% 6.1%;
  border: 1px solid var(--black);
  border-radius: 5.4% / 3.3%;
  pointer-events: none;
}

/* Position/Grösse der Figur auf der Karte: 40.98 x 73.40mm, zentriert, kein
   Offset (siehe PrintPdfService::FIGURE_WIDTH/HEIGHT_MM und
   FIGURE_OFFSET_X/Y_MM=0/0), als Prozentwerte der Kartenfläche:
   40.98/57.0 = 71.89% Breite, 73.40/89.0 = 82.47% Höhe, Rest je hälftig
   Rand. object-fit: fill statt cover/contain, weil TCPDF::Image() das Foto
   im echten Druck genauso ohne Seitenverhältnis-Erhalt auf diese Fläche
   streckt (siehe PrintPdfService::drawPersonalizedSlots()). */
.wizard-box-preview-photo {
  position: absolute;
  top: 8.76%;
  left: 14.05%;
  width: 71.89%;
  height: 82.47%;
  object-fit: fill;
}

.wizard-box-preview-stencil {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.wizard-box-preview-suit-switch-wrap {
  display: grid;
  gap: 6px;
  justify-items: center;
}

.wizard-box-preview-suit-switch-label {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.wizard-box-preview-suit-switch {
  display: flex;
  justify-content: center;
  gap: 8px;
}

/* Farbcodiert statt neutral grau (Herz/Eck rot, Kreuz/Schaufel schwarz, wie
   bei den Farb-Chips weiter oben, siehe .suit-red). Hintergrund bleibt immer
   weiss - die aktive Auswahl zeigt sich über einen dickeren, farbigen Rand
   statt einer vollflächigen Füllung, damit Kreuz/Schaufel (schwarz) im
   aktiven Zustand nicht mit einer reinen "ausgewählt"-Einfärbung verwechselt
   wird. */
.wizard-box-preview-suit-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.5px solid var(--mid-grey);
  background: var(--paper);
  color: var(--ink);
  font-size: var(--fs-md);
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.wizard-box-preview-suit-btn.suit-red {
  color: var(--red);
}

.wizard-box-preview-suit-btn.is-active {
  border-color: var(--ink);
  border-width: 2px;
}

.wizard-box-preview-suit-btn.is-active.suit-red {
  border-color: var(--red);
}

/* Farben, die im Druck-PDF die Standard-Vorlage statt eines eigenen Fotos
   bekommen (siehe FIGURE_TEMPLATE_IMAGES/acceptedSuitPhotoUrl() in
   wizard-step.js) - gestrichelter statt durchgezogener Rand, ohne die
   Farbcodierung selbst zu verändern. */
.wizard-box-preview-suit-btn.is-template {
  border-style: dashed;
}

.wizard-box-preview-status {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  text-align: center;
}

.wizard-box-preview-hint {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  text-align: center;
}

/* ---- Tabs: eine Figur (König/Dame/Bauer) gleichzeitig im Fokus ---- */

.wizard-face-tabs {
  display: flex;
  gap: 4px;
  background: var(--soft-grey);
  padding: 5px;
  border-radius: 13px;
}

.wizard-tab {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  border: 0;
  flex: 1;
  padding: 9px;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 600;
  text-align: center;
  cursor: pointer;
}

.wizard-tab.on {
  background: var(--paper);
  color: var(--strong);
}

/* Hover bei den nicht aktiven Tabs: gleiche Optik wie die aktive Tab, damit
   klar wird, dass man wechseln kann (gleiches Prinzip wie bei den Chips/
   Personalisierungsart-Karten). */
@media (hover: hover) and (pointer: fine) {
  .wizard-tab:not(.on):hover {
    background: var(--paper);
    color: var(--strong);
  }
}

.wizard-face-tab-panel--off {
  display: none;
}

/* "Alle generieren" (siehe faceFileGroupTemplate()/startAiGenerateAll() in
   wizard-step.js) - stösst alle noch offenen Fotos aller Figuren/Farben auf
   einmal an statt einzeln über den Generieren-Knopf in der Kachel. Ganz
   ausgeblendet statt nur disabled, solange es nichts zu generieren gibt
   (siehe refreshGenerateAllButton()).
   align-self: flex-end statt der von .wizard-face-figure-block geerbten
   Standard-Ausrichtung "stretch", sonst würde die Zeile über die gesamte
   Kartenbreite gehen. */
.wizard-ai-generate-all-row {
  align-self: flex-end;
  margin: 4px 0;
}

.wizard-ai-generate-all {
  width: auto;
}

/* ---- Switch: "Gleiches Foto für alle Farben" ---- */

.wizard-switch-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--soft-grey);
  border-radius: 13px;
  cursor: pointer;
}

.wizard-switch-row input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.wizard-switch-track {
  flex: 0 0 auto;
  width: 40px;
  height: 23px;
  border-radius: 999px;
  background: var(--light-grey);
  display: flex;
  align-items: center;
  padding: 3px;
  transition: background 0.18s ease;
}

.wizard-switch-thumb {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--paper);
  transition: transform 0.18s ease;
}

.wizard-switch-row input:checked ~ .wizard-switch-track {
  background: var(--red);
}

.wizard-switch-row input:checked ~ .wizard-switch-track .wizard-switch-thumb {
  transform: translateX(17px);
}

.wizard-switch-row input:focus-visible ~ .wizard-switch-track {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.wizard-switch-label {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--strong);
}

/* ---- Datei-Kacheln statt Datei-Button ---- */

.wizard-file-slots {
  display: grid;
  /* 140px Mindestbreite ergibt bei 4 Kacheln (Herz/Kreuz/Schaufel/Eck) auf
     Mobile eine saubere 2x2-Anordnung statt 3+1; auf breiteren Screens bzw.
     bei weniger Kacheln bleibt auto-fill weiterhin flexibel. */
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}

.wizard-file-slot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  position: relative;
}

.wizard-file-slot label.file-upload-btn {
  position: relative;
  display: flex;
  width: 100%;
  aspect-ratio: 3 / 4;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--soft-grey);
  color: var(--light-grey);
  border-radius: 14px;
  cursor: pointer;
}

/* Reine Bildvorschau (bei "Gesicht" und den Referenzbildern zu "Spezielle
   Wünsche", siehe fileSlotTemplate/updatePreview in
   wizard-step.js) - liegt dank position:absolute automatisch über
   dem Upload-Icon/Häkchen darunter, kein zusätzliches Ausblenden nötig. */
.wizard-file-tile-preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (hover: hover) and (pointer: fine) {
  .wizard-file-slot label.file-upload-btn:hover {
    background: var(--mid-grey);
  }
}

.wizard-file-slot--missing label.file-upload-btn {
  box-shadow: inset 0 0 0 2px var(--red);
  background: var(--paper);
}

.wizard-file-tile--done label.file-upload-btn {
  background: color-mix(in srgb, var(--red) 8%, var(--paper));
  color: var(--red);
}

.wizard-file-tile--dragover label.file-upload-btn {
  box-shadow: inset 0 0 0 2px var(--red);
  background: color-mix(in srgb, var(--red) 14%, var(--paper));
  color: var(--red);
}

/* Nach dem Akzeptieren gesperrt (siehe lockFileSlot()) - Kachel bleibt
   sichtbar (Ergebnis soll man weiterhin sehen), wirkt aber unklickbar. */
.wizard-file-slot--locked label.file-upload-btn {
  cursor: default;
}

/* Während eine Generierung läuft, temporär gesperrt (siehe renderAiUi()) -
   anders als --locked oben kein dauerhafter Zustand, deshalb ohne die
   Häkchen-Optik von .wizard-file-tile-check. */
.wizard-file-slot--generating label.file-upload-btn {
  cursor: default;
}

.wizard-file-slot--locked .wizard-file-tile-check {
  opacity: 1;
}

.file-upload-icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.wizard-file-tile-check {
  display: none;
}

.wizard-file-tile-check svg {
  display: block;
  width: 26px;
  height: 26px;
}

.wizard-file-tile--done .file-upload-icon {
  display: none;
}

.wizard-file-tile--done .wizard-file-tile-check {
  display: block;
}

.wizard-file-slot input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}

.wizard-file-tile-caption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  text-align: center;
  /* Ohne das hier und unten bei .wizard-file-slot-name schrumpft ein
     Flex-Kind standardmässig nicht unter seine Inhaltsbreite (min-width:
     auto) - der Dateiname konnte dadurch aus der schmalen Kachel
     herauslaufen, statt wie vorgesehen mit "..." abgeschnitten zu werden. */
  min-width: 0;
  width: 100%;
}

.wizard-file-tile-label {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--strong);
}

.wizard-file-slot-name {
  display: block;
  width: 100%;
  min-width: 0;
  font-size: var(--fs-xs);
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wizard-file-slot-clear {
  position: absolute;
  top: -6px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 0;
  background: var(--strong);
  border-radius: 50%;
  color: var(--paper);
  cursor: pointer;
  padding: 0;
}

.wizard-file-slot-clear svg {
  display: block;
  width: 11px;
  height: 11px;
}

@media (hover: hover) and (pointer: fine) {
  .wizard-file-slot-clear:hover {
    background: var(--red);
  }
}

.wizard-file-slot-clear.hidden {
  display: none;
}

/* Zusätzliches Referenzbild-Feld bei "Spezielle Wünsche" (über "+ Weiteres
   Bild" hinzugefügt, siehe data-add-special-wishes-slot in wizard-step.js) -
   im Gegensatz zu .wizard-file-slot-clear (räumt nur die Datei aus einer
   Kachel) entfernt dieser Button das ganze Feld. Sitzt an derselben Stelle
   (oben rechts) wie .wizard-file-slot-clear und wird von wizard-step.js
   genau umgekehrt dazu ein-/ausgeblendet - nie beide gleichzeitig sichtbar.
   Nur bei dynamisch hinzugefügten Feldern vorhanden, nicht beim
   Standard-Feld. */
.wizard-file-slot-remove {
  position: absolute;
  top: -6px;
  right: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 0;
  background: var(--muted);
  border-radius: 50%;
  color: var(--paper);
  cursor: pointer;
  padding: 0;
}

.wizard-file-slot-remove svg {
  display: block;
  width: 11px;
  height: 11px;
}

@media (hover: hover) and (pointer: fine) {
  .wizard-file-slot-remove:hover {
    background: var(--red);
  }
}

.wizard-file-slot-remove.hidden {
  display: none;
}

/* ---- KI-Bildbearbeitung (Generieren/Akzeptieren, siehe aiFlowTemplate() in
   wizard-step.js) - sitzt innerhalb eines .wizard-file-slot,
   also auf dieselbe Kachelbreite begrenzt (siehe .wizard-file-slots
   grid-template-columns weiter oben). */

.wizard-ai-flow {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin-top: 2px;
}

.wizard-ai-generate {
  width: 100%;
}

.wizard-ai-progress {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-xs);
  color: var(--muted);
}

.wizard-ai-result {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
}

.wizard-ai-result-label {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--strong);
  margin: 0;
}

.wizard-ai-result-preview {
  width: 100%;
  /* Leonardo generiert exakt 768x1376px, Preset "9:16" (siehe
     AiImageService::createGeneration() width/height) - nicht 3/4 wie beim
     generischen Datei-Vorschaubild für Kundenfotos. Bei falschem
     Seitenverhältnis schneidet object-fit:cover oben/unten vom Bild ab. */
  aspect-ratio: 768 / 1376;
  object-fit: cover;
  border-radius: 14px;
  display: block;
}

/* Wrapper-<button> um das Ergebnisbild - öffnet es per Klick in einem neuen
   Tab (siehe data-ai-zoom-Handler), damit man es vor dem "Akzeptieren" auch
   vergrössert prüfen kann. Reset der Button-Grunddarstellung, damit das Bild
   optisch unverändert bleibt. */
.wizard-ai-result-zoom {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
}

.wizard-ai-result-zoom-icon {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: white;
  pointer-events: none;
}

.wizard-ai-result-zoom-icon svg {
  width: 16px;
  height: 16px;
}

/* :focus-visible bleibt unabhängig vom Zeigegerät aktiv (Tastatur-Fokus) -
   nur :hover ist auf echte Hover-Geräte beschränkt (Sticky-Hover-Bug). */
.wizard-ai-result-zoom:focus-visible .wizard-ai-result-zoom-icon {
  background: var(--strong);
}

@media (hover: hover) and (pointer: fine) {
  .wizard-ai-result-zoom:hover .wizard-ai-result-zoom-icon {
    background: var(--strong);
  }
}

.wizard-ai-attempts {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin: 0;
}

/* Zeigt alle bisherigen Versuche als Thumbnails, sobald mehr als einer
   existiert (siehe renderAiUi()) - der Kunde kann jederzeit eine ältere,
   bessere Version statt der zuletzt generierten auswählen. */
.wizard-ai-options-hint {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin: 0;
}

.wizard-ai-options {
  display: flex;
  gap: 8px;
  width: 100%;
}

.wizard-ai-option {
  flex: 1;
  padding: 0;
  border: 2px solid var(--mid-grey);
  border-radius: 10px;
  background: none;
  cursor: pointer;
  overflow: hidden;
  aspect-ratio: 768 / 1376;
}

.wizard-ai-option img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.wizard-ai-option.on {
  border-color: var(--red);
}

/* Nach "Akzeptieren" bleiben die Thumbnails sichtbar, aber nicht mehr
   anklickbar (siehe selectAiResult()) - visuell gedimmt als Hinweis, dass
   die Auswahl endgültig ist. */
.wizard-ai-options.locked .wizard-ai-option {
  cursor: not-allowed;
  pointer-events: none;
}

.wizard-ai-options.locked .wizard-ai-option:not(.on) {
  opacity: 0.5;
}

.wizard-ai-result-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}

/* Gleiche Optik wie der "Zurück"-Knopf (.wizard-nav-back) - dort an
   .wizard-nav gebunden, hier bewusst als eigene, ungebundene Klasse, da
   dieser Knopf nicht im Wizard-Navigationsbereich steht. */
.wizard-ai-regenerate {
  font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--mid-grey);
}

/* ".button.wizard-ai-regenerate" statt nur ".wizard-ai-regenerate" braucht
   dieselbe Spezifität (2 Klassen) wie ".button.secondary:hover" in
   global.css, sonst gewinnt dessen rotes Hover (Spezifität schlägt
   Cascade-Reihenfolge). */
@media (hover: hover) and (pointer: fine) {
  .button.wizard-ai-regenerate:hover:not(:disabled) {
    background: var(--strong);
    color: white;
    box-shadow: inset 0 0 0 1px var(--strong);
  }
}

.wizard-ai-error {
  font-size: var(--fs-xs);
  color: var(--red);
  margin: 0;
}

.wizard-ai-error:empty {
  display: none;
}

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

.wizard-form-grid {
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;
  gap: 14px;
}

.wizard-form-grid .wizard-field input {
  max-width: none;
}

.wizard-char-counter {
  display: block;
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: 400;
  text-align: right;
  margin-top: -3px;
}

.wizard-char-counter--near {
  color: var(--red);
}

.wizard-field-error {
  display: block;
  color: var(--red);
  font-size: var(--fs-sm);
  font-weight: 500;
  min-height: 16px;
  margin-top: 2px;
}

.wizard-field-error:empty {
  display: none;
}

.wizard-field.has-error input,
.wizard-field.has-error textarea {
  box-shadow: inset 0 0 0 2px var(--red);
  background: white;
}

.wizard-ship-toggle {
  margin: 20px 0 4px;
}

.wizard-shipping-block {
  margin-top: 8px;
  padding: 16px;
  background: var(--soft-grey);
  border-radius: var(--box-radius);
}

/* Inputs sind global gleich eingefärbt wie der Block-Hintergrund
   (--soft-grey) - ohne diese Regel verschwinden die Felder optisch. */
.wizard-shipping-block input {
  background: var(--paper);
}

.wizard-subheading {
  margin: 0 0 14px;
  font-size: var(--fs-base);
}

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

.wizard-summary {
  display: grid;
  gap: 16px;
}

.wizard-summary-group h4 {
  margin: 0 0 8px;
  font-size: var(--fs-base);
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: var(--fs-xs);
}

.wizard-summary-dl {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 16px;
  margin: 0;
}

.wizard-summary-dl dt {
  color: var(--muted);
  font-weight: 500;
}

.wizard-summary-dl dd {
  margin: 0;
  /* E-Mail-Adressen/Strassen ohne Leerzeichen können auf schmalen
     Mobile-Breiten (~320-375px) breiter als die Spalte sein - sonst würde
     das die Zusammenfassung horizontal aufsprengen statt umzubrechen. */
  overflow-wrap: anywhere;
}

.wizard-summary-price {
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--mid-grey);
  font-weight: 500;
  color: var(--strong);
}

.wizard-summary-price-row {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  margin: 0 0 4px;
}

.wizard-summary-price-row--total {
  margin: 8px 0 0;
  font-weight: 700;
}

.wizard-summary-files {
  margin-top: 10px;
}

/* ---- Gutscheinfeld (Bemerkung bzw. Zusammenfassung, siehe voucher-field.js) ---- */

.wizard-voucher {
  margin-top: 20px;
}

/* Knopf, der wie ein Textlink aussieht: klappt nur das Feld auf. */
.wizard-voucher-toggle,
.wizard-voucher-remove {
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--red);
  font: inherit;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.wizard-voucher-form {
  margin: 10px 0 0;
}

.wizard-voucher-row {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 10px;
}

.wizard-voucher-row input {
  /* Schmale Grundbreite, damit Feld und Knopf auch auf dem Handy in einer
     Zeile bleiben; flex-wrap greift nur bei sehr schmalen Geräten. */
  flex: 1 1 140px;
  width: auto;
  min-width: 0;
  text-transform: uppercase;
}

/* Gegen ".button { width: 100% }" im Handy-Block von global.css: der
   Einlösen-Knopf bleibt neben dem Feld und füllt dessen Höhe. */
.wizard-voucher-row .button {
  flex: 0 0 auto;
  width: auto;
  min-height: 48px;
}

.wizard-voucher-applied {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  padding: 12px 14px;
  background: rgba(var(--success-green-rgb), 0.1);
  border-radius: var(--box-radius);
  color: var(--strong);
  font-weight: 500;
}

.wizard-summary-files-label {
  margin: 0 0 4px;
  font-size: var(--fs-xs);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.wizard-summary-files ul {
  margin: 0;
  padding-left: 18px;
}

.wizard-summary-files li {
  margin-bottom: 2px;
  /* Lange Kamera-Dateinamen (z.B. IMG_20260825_143022_HDR.jpg) können auf
     schmalen Mobile-Breiten breiter als die Liste sein. */
  overflow-wrap: anywhere;
}

.wizard-summary-files-sublist {
  margin: 2px 0 6px;
  padding-left: 18px;
  color: var(--muted);
  font-size: var(--fs-sm);
}

/* ---- Navigation ---- */

.wizard-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}

.wizard-nav .button {
  flex: 1 1 auto;
}

.wizard-nav #wizard-back,
.wizard-nav .wizard-nav-back {
  order: 2;
  font-size: var(--fs-base);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--mid-grey);
}

/* .button.secondary hat denselben Grauton wie der Wizard-Hintergrund
   (--soft-grey) - der Rahmen (box-shadow oben) sorgt dafür, dass der Knopf
   trotzdem sichtbar bleibt. :not(:disabled) ergänzt, um dieselbe Spezifität
   wie ".button.secondary:hover:not(:disabled)" in global.css zu erreichen,
   sonst würde dessen rotes Hover gewinnen (gleiche Ursache wie bei
   .wizard-ai-regenerate weiter oben). */
@media (hover: hover) and (pointer: fine) {
  .wizard-nav #wizard-back:hover:not(:disabled),
  .wizard-nav .wizard-nav-back:hover:not(:disabled) {
    background: var(--strong);
    color: white;
    box-shadow: inset 0 0 0 1px var(--strong);
  }
}

.wizard-nav #wizard-next,
.wizard-nav #wizard-submit {
  order: 1;
}

/* Im Sidebar-Kontext (.wizard-summary-card) immer gestapelt, unabhängig vom
   Breakpoint unten - höhere Spezifität (zusätzliche Klasse) gewinnt gegen
   dessen @media-Variante. */
.wizard-summary-card .wizard-nav {
  flex-direction: column;
  flex-wrap: nowrap;
  margin-top: 0;
}

.wizard-summary-card .wizard-nav .button {
  width: 100%;
  min-width: 0;
}

.wizard-summary-card .wizard-nav #wizard-next,
.wizard-summary-card .wizard-nav #wizard-submit {
  order: 1;
  margin-right: 0;
}

.wizard-summary-card .wizard-nav #wizard-back,
.wizard-summary-card .wizard-nav .wizard-nav-back {
  order: 2;
  margin-right: 0;
}

/* ---- Done / Confirmation ---- */

#wizard-done-message {
  font-size: var(--fs-md);
}

/* ---- Responsive ---- */

@media (min-width: 620px) {
  .wizard-form-grid {
    grid-template-columns: 1fr 1fr;
  }

  .wizard-nav {
    justify-content: flex-end;
  }

  .wizard-nav .button {
    flex: 0 0 auto;
    min-width: 160px;
  }

  .wizard-nav #wizard-back,
  .wizard-nav .wizard-nav-back {
    order: 1;
    margin-right: auto;
  }

  .wizard-nav #wizard-next,
  .wizard-nav #wizard-submit {
    order: 2;
  }
}

@media (max-width: 619px) {
  /* :not(.wizard-panel--plain) ist ein defensiver Ausschluss für ein Panel
     ohne eigenes Padding (aktuell von keinem JS gesetzt) - bräuchte in dem
     Fall trotzdem eigenes Padding, sonst blieben die Karten durch den
     negativen margin ohne Seitenabstand.

     Der negative margin hebt das seitliche Padding von .shop-wizard
     (clamp(18px, 5vw, 56px), siehe oben) auf, damit die Karte bündig bis
     zum Bildschirmrand geht - dieselbe clamp()-Formel wie bei .shop-wizard,
     damit das bei jeder Breite exakt aufgeht (ein fixer Wert würde nur am
     Clamp-Minimum passen). */
  .wizard-panel:not(.wizard-panel--plain) {
    border-radius: 0;
    margin: 0 calc(-1 * clamp(18px, 5vw, 56px));
    /* width:100% (siehe @media (max-width: 960px) oben) bezieht sich auf die
       bereits eingerückte Breite des Elternelements - der negative margin
       zieht die Karte bis an den Bildschirmrand, ohne diese Ergänzung
       bliebe sie aber genauso breit wie vorher und bündig nur links; rechts
       bliebe eine Lücke von der doppelten Padding-Breite. +2x Padding
       gleicht das aus. */
    width: calc(100% + 2 * clamp(18px, 5vw, 56px));
    /* Auf der Adress-Seite gilt zusätzlich
       ".wizard-layout--hide-aside > .wizard-panel { max-width: 100%; }"
       (siehe @media max-width:960px oben) - max-width deckelt den benutzten
       Wert unabhängig davon, wie width berechnet wurde, daher würde die
       width-Berechnung oben sonst ignoriert. max-width:none hebt den Deckel
       hier gezielt wieder auf. */
    max-width: none;
    padding: 24px 18px;
  }

  /* Personalisierungs-Schritt (data-stage="config"): die Desktop/Tablet-Regel
     oben (.wizard-panel:has(...)) setzt padding-left/right:0, damit die
     .wizard-subcard-Karten nicht doppelt eingerückt sind. Diese Regel hat
     höhere Spezifität als die :not(--plain)-Regel oben und gewinnt daher
     auch hier im Mobile-Bleed, wodurch die Karten sonst gar keinen
     seitlichen Abstand mehr hätten. Gleiche Spezifität wie die
     Desktop-Regel, aber im mobilen Media-Query, stellt hier wieder 18px
     her, passend zum Innenabstand der anderen Schritte (siehe padding:
     24px 18px oben). */
  .wizard-panel:has(> section[data-stage="config"]:not(.hidden)):not(.wizard-panel--plain) {
    padding-left: 18px;
    padding-right: 18px;
  }

  /* Adress- und Übersicht-Schritt (data-stage="address"/"overview"): hier
     ist .wizard-panel selbst die sichtbare weisse Fläche (anders als bei
     "config", wo das Panel transparent bleibt und die .wizard-subcard-
     Karten die weisse Fläche stellen, siehe oben) - der Bleed von oben
     würde sie bündig/randlos ohne grauen Rand wirken lassen. Bleed/
     border-radius hier zurückgenommen: sichtbarer grauer Rand links/rechts,
     abgerundete Ecken, width:100% bezieht sich wieder auf das bereits von
     .shop-wizard eingerückte .wizard-layout. */
  .wizard-panel:has(> section[data-stage="address"]:not(.hidden)),
  .wizard-panel:has(> section[data-stage="overview"]:not(.hidden)) {
    border-radius: var(--box-radius);
    margin: 0;
    width: 100%;
    max-width: none;
  }

  .wizard-progress li span:not(.wizard-progress-num) {
    display: none;
  }
}

/* Seitenkopf der Produktübersicht (/products). */
.page-intro {
  text-align: center;
  margin: 0 auto 28px;
  max-width: 640px;
}

.page-intro h1 {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  color: var(--wine-900);
  margin: 0;
}
