/* ----------------------------------------------------------------------
   Pizzamacher – Styles
   Wizard-Layout (5 Schritte). Mobile- und Desktop-Wizard.
   Verwendet Tokens aus theme.css.
   ---------------------------------------------------------------------- */

* { box-sizing: border-box; }

html {
  font-size: var(--fs-root);
}
body {
  margin: 0;
  padding: 0;
  background: var(--background-site);
  color: var(--primary);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  /* Strikte Trennung Medium / Bold: kein synthetisches Bold/Italic durch
     den Browser. SpaceGrotesk hat nur einen Schnitt (Medium 400). Bei
     font-weight: 700 ohne passenden Schnitt rendert der Browser dann die
     Medium-Datei statt künstlich zu bolden. Echter Bold kommt
     ausschließlich über font-family: 'SpaceGroteskBold' (Highlights in
     der Anleitung). */
  font-synthesis: none;
}

h1, h2, h3, h4 {
  margin: 0 0 .4em;
  line-height: 1.2;
  font-weight: 700;
  color: var(--primary);
}
h1 { font-size: var(--fs-h1); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); font-weight: 600; }
h4 { font-size: var(--fs-h4); font-weight: 600; }

a { color: var(--secondary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------- App-Shell ---------- */

.app {
  max-width: 1000px;
  margin: 0 auto;
  padding: 1rem 1rem 6rem;
  min-height: 100vh;
}

.brand-row {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1rem;
  padding: .25rem .25rem;
}
.brand-row .brand {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-h4);
  color: var(--primary);
  /* Button-/Anchor-Reset: das Logo wirkt visuell wie Text, ist aber je nach
     Seite ein <button> (index.html → showModePicker) oder ein <a> (focaccia.html
     → Pizzamacher-Seite). Beide bekommen denselben Stil und Hover. */
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
  font-family: inherit;
  transition: opacity .15s ease;
}
.brand-row .brand:hover,
.brand-row .brand:focus-visible { opacity: .7; }
.brand-row .brand:focus-visible { outline: 2px solid var(--primary); outline-offset: 4px; }
.brand-row .brand .dot { color: var(--primary); }

.brand-actions {
  display: flex;
  gap: .4rem;
  align-items: center;
}

.brand-row .restart {
  font: inherit;
  font-size: var(--pill-font-size);
  color: var(--primary);
  background: transparent;
  border: var(--border-width) solid var(--border);
  border-radius: var(--pill-radius);
  padding: 0 var(--pill-padding-x);
  height: var(--pill-height);
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
}
.brand-row .restart .restart-icon {
  width: 1.05em;
  height: 1.05em;
  display: none;
}
/* Mobile: nur Icon, quadratischer Button — Text spart Platz neben Theme-Switch */
@media (max-width: 480px) {
  .brand-row .restart {
    width: var(--pill-height);
    padding: 0;
  }
  .brand-row .restart .restart-text { display: none; }
  .brand-row .restart .restart-icon { display: inline-block; }
}

.theme-switch {
  display: inline-flex;
  align-items: center;
  background: transparent;
  border: var(--border-width) solid var(--border);
  border-radius: var(--pill-radius);
  /* Padding und gap sind bewusst gleich groß, damit der Abstand zwischen
     den Theme-Buttons exakt dem Abstand zum Pill-Rand entspricht — sonst
     kleben die Icons-Kreise aneinander, sobald einer eine sichtbare
     Border bekommt (Hover oder is-active). */
  padding: 3px;
  gap: 3px;
  height: var(--pill-height);
}
.theme-btn {
  width: calc(var(--pill-height) - 8px);
  height: calc(var(--pill-height) - 8px);
  border: var(--border-width) solid transparent;
  background: transparent;
  border-radius: var(--pill-radius);
  color: var(--primary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: color .12s ease, background .12s ease;
}
.theme-btn svg { width: 55%; height: 55%; }
.theme-btn.is-active {
  background: var(--primary);
  color: var(--background-site);
  border-color: var(--primary);
}

/* ----------------------------------------------------------------------
   Theme-Tweaks
   ----------------------------------------------------------------------
   Praktisch alle theme-spezifischen Anpassungen wurden in Tokens überführt
   (siehe theme.css: --primary, --background-card, --background-card-muted,
   --primary-soft …). Hier bleiben nur noch wirklich theme-spezifische
   Designentscheidungen — aktuell keine.
   ---------------------------------------------------------------------- */

/* ---------- Stepper ---------- */

.stepper {
  display: flex;
  gap: .35rem;
  margin: .25rem 0 1.25rem;
  padding: 0 .25rem;
}
.stepper .step-pill {
  flex: 1;
  height: 1px;
  border-radius: 0;
  background: var(--accent-pending);
  transition: background .25s ease;
}
.stepper .step-pill.is-done   { background: var(--accent-done); }
.stepper .step-pill.is-active { background: var(--accent-active); }

.step-label-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 1rem;
  padding: 0 .25rem;
}
.step-label-row .step-label {
  font-size: var(--fs-tiny);
  color: var(--muted-foreground);
  text-transform: uppercase;
}
.step-label-row .step-label strong { color: var(--primary); font-weight: 700; }

/* ---------- Card ---------- */

.card {
  background: var(--background-card);
  color: var(--primary);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  /* Padding allseitig gleich. Damit der Card-Bottom nicht durch Trailing-
     Margins der Kinder aufgeblasen wird, setzt eine Regel weiter unten
     `margin-bottom: 0` auf das jeweils letzte sichtbare Direkt-Kind. */
  padding: var(--space-card);
}
/* Letztes direktes Kind in der Card: Bottom-Margin auf 0 zurücksetzen.
   Sonst summieren sich Card-Padding + Element-Margin zu doppeltem Abstand. */
.card > *:last-child { margin-bottom: 0; }
.card + .card { margin-top: var(--space-card); }

/* Heading, Lede und Top-Level-Hints in der Card teilen sich denselben
   vertikalen Rhythmus wie das Card-Padding — dadurch ist der Abstand
   zwischen Card-Wand → Heading → Inhalt → Hint → Wizard-Nav optisch
   identisch zum Innenabstand. Greift auch für direkte <h2> in der Card
   (z. B. "Schritt-für-Schritt-Anleitung", "Zeitplan") — die haben sonst
   nur den Default-h*-Margin von .4em und sitzen optisch zu nah am Rand.
   line-height: 1.1 zieht die Box dichter an die Glyphen, sodass der
   Margin zum Sub-Text optisch zum unteren Rhythmus passt — die globale
   h-line-height von 1.2 erzeugt sonst ~3 px unsichtbaren Half-Leading
   unter der Glyph-Bottom, was die Lücke zum Lede zu groß wirken lässt. */
.card .step-title,
.card > h1,
.card > h2 {
  font-family: var(--font-sans);
  font-size: var(--fs-h2);
  font-weight: 700;
  /* line-height: 1 entfernt den globalen h*-Half-Leading. Default-
     Margin ist der volle --space-card — passt zum Use-Case "Heading
     gefolgt von einem Container" (choice-grid, info-box, flour-box):
     dort sorgt die echte Container-Border für einen klaren Anker, der
     ohne Trim auskommt. */
  line-height: 1;
  margin: 0 0 var(--space-card);
  padding: 0;
  /* Mobile-Safety: lange Wörter ("Sole-Topping", "Schritt-für-Schritt-
     Anleitung", "Focacciamacher") brechen auf 375 px sauber um statt das
     Card-Layout zu sprengen. overflow-wrap regelt normal-getrennte Wörter,
     hyphens schaltet automatische Silbentrennung an wo das Browser-Wörter-
     buch (lang="de") hilft. */
  overflow-wrap: break-word;
  hyphens: auto;
}
/* Sonderfall: Heading → direkt anschließender Text-Lede. SpaceGrotesk
   hat ~0.3em intrinsischen Descender-Whitespace, der den nominalen
   Abstand zum Lede optisch aufbläht. Wir trimmen den margin-bottom
   nur in diesem Use-Case — getriggert über :has() auf den nachfolgenden
   step-lede, sodass Headings mit Container darunter unverändert bleiben. */
.card .step-title:has(+ .step-lede),
.card > h2:has(+ .step-lede) {
  margin-bottom: calc(var(--space-card) - 0.3em);
}
.card .step-lede {
  color: var(--muted-foreground);
  margin: 0 0 var(--space-card);
  font-size: var(--fs-body);
}
/* Top-Level-Hints (z. B. "Same-Day = Schnellstart..." unter den Method-
   Choices). Span-.hint innerhalb von <label> bleibt unberührt — die
   sind kein Block-Element und brauchen keinen vertikalen Margin. */
.card > p.hint,
.card > .hint {
  margin: var(--space-card) 0 0;
  color: var(--muted-foreground);
  font-size: var(--fs-tiny);
  line-height: 1.5;
}

/* ---------- Mode-Picker (Schnellstart vs. Experte) ---------- */

.mode-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: .8rem;
}
@media (min-width: 560px) {
  .mode-grid { grid-template-columns: 1fr 1fr; }
}
.mode-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  background: var(--background-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  cursor: pointer;
  font: inherit;
  color: var(--primary);
  transition: all .15s ease;
}
.mode-card .title {
  font-size: var(--fs-h4);
  font-weight: 700;
  margin-bottom: .35rem;
}
.mode-card p {
  margin: 0 0 .9rem;
  color: var(--muted-foreground);
  font-size: var(--fs-small);
  line-height: 1.45;
}
.mode-card .mode-cta {
  display: inline-flex;
  align-items: center;
  font-weight: 600;
  font-size: var(--fs-small);
  color: var(--secondary);
}

/* ---------- Auto-Summary auf Mengen-Step ---------- */

.auto-summary {
  background: var(--background-card-muted);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: .9rem 1rem 1rem;
  margin-bottom: 1.2rem;
}
.auto-summary.is-hidden { display: none; }
.summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: .25rem .5rem;
}
.summary-grid > div {
  display: flex; flex-direction: column;
}
.summary-grid .lbl {
  font-size: var(--fs-micro);
  text-transform: uppercase;
  color: var(--muted-foreground);
  font-weight: 500;
}
.summary-grid .val {
  font-weight: 600;
  font-size: var(--fs-small);
  color: var(--primary);
}
/* ---------- Wizard-Steps ---------- */

.step { display: none; }
.step.is-active { display: block; animation: fadeIn .25s ease; }
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* ---------- Choice-Cards (Stil / Methode / Reifevariante) ---------- */

.choice-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: .75rem;
}

/* Dynamische Spaltenverteilung ab Tablet-Breite:
     1 Kachel  → 100 %
     2 Kacheln → 2 × 50 %
     3 Kacheln → 3 × 33 % (Maximum)
     4+ Kacheln → 2 × 2 (50 %, wrappt automatisch in weitere Reihen)
   Funktioniert über :has() — moderner Browser-Support seit 2023. */
@media (min-width: 560px) {
  /* Default für alles ab 4 Kacheln (auch ohne :has() als Fallback) */
  .choice-grid { grid-template-columns: 1fr 1fr; }
  .choice-grid:has(> :nth-child(1):last-child) { grid-template-columns: 1fr; }
  .choice-grid:has(> :nth-child(2):last-child) { grid-template-columns: 1fr 1fr; }
  /* 3-Kachel-Grids bleiben auf schmalen Tablets gestackt — sonst zu eng. */
  .choice-grid:has(> :nth-child(3):last-child) { grid-template-columns: 1fr; }
  /* Fallback für ältere Klassen (cols-2 / cols-3) — falls noch im Markup. */
  .choice-grid.cols-2 { grid-template-columns: 1fr 1fr; }
  .choice-grid.cols-3 { grid-template-columns: 1fr; }
}

@media (min-width: 768px) {
  .choice-grid:has(> :nth-child(3):last-child) { grid-template-columns: 1fr 1fr 1fr; }
  .choice-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
}

.choice-card {
  position: relative;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  background: var(--background-card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  /* Allseitig identisches Padding — gleiches Maß wie .card und .field-Margins,
     damit Pill-Tags an der Card-Unterkante denselben Abstand zum Border haben
     wie alle anderen Inhalte in Containern. */
  padding: var(--space-card);
  transition: border-color .15s ease, background .15s ease;
}
.choice-card input[type="radio"] {
  position: absolute; opacity: 0; pointer-events: none;
}
.choice-card .radio-mark {
  position: absolute;
  top: var(--space-card); right: var(--space-card);
  width: 18px; height: 18px;
  border-radius: 50%;
  border: var(--border-width) solid var(--border);
  background: var(--background-card);
  transition: all .15s ease;
}
.choice-card.is-active {
  border-color: var(--primary);
}
.choice-card.is-active .radio-mark {
  border-color: var(--primary);
  background: radial-gradient(circle, var(--primary) 0 5px, transparent 5px 100%);
}

.choice-card .title {
    font-weight: 700;
    font-size: var(--fs-h4);
    line-height: 1.4rem;
    padding-right: 1.7rem;
    padding-bottom: 0.3rem;
}
.choice-card .subtitle {
  color: var(--muted-foreground);
  font-size: var(--fs-small);
  margin: 0;
}
.choice-card .desc {
  font-size: var(--fs-small);
  color: var(--primary);
  margin: .35rem 0 0;
  line-height: 1.45;
}
.choice-card .meta {
  display: flex; flex-wrap: wrap; gap: .3rem;
  /* Tags immer an die Unterkante der Card andocken, damit sie über alle
     Karten in einer Reihe auf gleicher Höhe sitzen. */
  margin-top: auto;
  padding-top: .55rem;
}
.choice-card .pill {
  font-size: var(--tag-font-size);
  font-weight: 500;
  padding: 0 var(--tag-padding-x);
  height: var(--tag-height);
  border-radius: var(--pill-radius);
  background: transparent;
  color: var(--primary);
  border: var(--border-width) solid var(--primary);
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
}
.choice-card.is-active .pill {
  background: var(--primary);
  color: var(--background-site);
}

.pill.pill-rec {
  background: var(--primary) !important;
  color: var(--background-site) !important;
  font-weight: 600;
  font-size: var(--tag-font-size);
  padding: 0 var(--tag-padding-x);
  height: var(--tag-height);
  display: inline-flex; align-items: center; justify-content: center; gap: .2rem;
}

.timing-detail {
  margin-top: var(--space-card);
  background: var(--background-card-muted);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: .9rem 1.1rem;
  font-size: var(--fs-small);
}
/* Geschmack | Bekömmlichkeit als zwei gleichbreite Spalten nebeneinander.
   Auf schmalen Viewports (< 560 px) stacken die Blöcke untereinander —
   damit der Text bei Mobile nicht in einen winzigen 50 %-Streifen
   gequetscht wird. */
.timing-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-card);
}
.timing-detail-grid p {
  margin: 0;
  color: var(--primary);
  line-height: 1.45;
}
@media (max-width: 559px) {
  .timing-detail-grid { grid-template-columns: 1fr; }
}

/* ---------- Form-Felder ---------- */

/* Field-Margins: oben + unten, damit Felder zu vorigen Containern
   (z. B. .timing-detail, .auto-summary) sauber Luft halten. Card-Padding
   übernimmt erst, wenn das Feld direkter erster/letzter Child der Card ist. */
.field { margin: var(--space-card) 0; }
.field:first-child { margin-top: 0; }
/* Letztes sichtbares .field: kein bottom-Margin. Greift auch wenn nach
   ihm noch beliebig viele .is-hidden Felder folgen. */
.field:not(.is-hidden):not(:has(~ .field:not(.is-hidden))) { margin-bottom: 0; }

/* Hinweis-Block am Ende einer Anleitungs-Phase (z. B. Flex-Stückgare).
   Visuell wie .info-box, aber mit kleinerem oberem Margin damit der
   Block direkt unter den Steps anschließt. */
.phase-hint {
  margin-top: var(--space-card);
}

/* Mehl-Splitting-UI im Mengen-Step (Schritt 4):
   Chip-Toggle (Single / Mix) optisch identisch zum Hefe-Toggle, plus
   ein bzw. zwei Select-Dropdowns. Auf Mobile stacken die Selects. */
.flour-mode-toggle {
  display: flex;
  align-items: center;
  gap: .7rem;
  flex-wrap: wrap;
  margin: .35rem 0 .65rem;
}
.flour-mode-label {
  font-size: var(--fs-small);
  color: var(--muted-foreground);
  font-weight: 500;
}
.field-label {
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline;
  font-weight: 600;
  margin-bottom: .25rem;
  column-gap: .5rem;
  row-gap: 0rem;
}
/* Wenn ein .help-Span auf eine zweite Zeile wrappt, braucht das Label
   mehr Luft zum folgenden Eingabe-Element — sonst klebt der Input direkt
   am Hilfstext. */
.field-label:has(> .help) { margin-bottom: 1rem; }
.field-label > .value-display { order: 1; }
.field-label > .help {
  flex-basis: 100%;
  order: 2;
  text-align: left;
  color: var(--muted-foreground);
  font-weight: 400;
  font-size: var(--fs-tiny);
}
.value-display {
  font-variant-numeric: tabular-nums;
  color: var(--primary);
  font-weight: 700;
  background: var(--background-card-muted);
  padding: .15rem .55rem;
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  border: var(--border-width) solid var(--primary);
}
.value-display.accent {
  background: var(--primary);
  color: var(--background-card);
  border: var(--border-width) solid var(--primary);
}
.field .hint {
  display: block;
  margin-top: .35rem;
  color: var(--muted-foreground);
  font-size: var(--fs-tiny);
}

/* Inline-Hinweis unter einem Slider, der per Schwellwert (is-visible) ein-
   und ausblendet. Bewusst KEIN display-Toggle — opacity + max-height
   animieren für einen sanften Übergang (z. B. Öl-Warnung ab 7 %). */
.slider-note {
  display: block;
  overflow: hidden;
  max-height: 0;
  margin-top: 0;
  opacity: 0;
  color: var(--muted-foreground);
  font-size: var(--fs-tiny);
  transition: max-height .3s ease, opacity .3s ease, margin-top .3s ease;
}
.slider-note.is-visible {
  /* Cap großzügig (6rem) — der längere Hydration-Hinweis bricht auf Mobile auf
     bis zu 4 Zeilen um; 4rem würde dort clippen. Für kurze Notes (Öl-Warnung)
     bleibt die Darstellung identisch, da max-height nur die Obergrenze ist. */
  max-height: 6rem;
  margin-top: .35rem;
  opacity: 1;
}

/* Placeholder einheitlich auf den globalen Muted-Text (--muted-foreground).
   Damit bleibt der Eingabe-Hint visuell konsistent mit Hint-Texten unter
   Slidern, Brand-Specs etc. */
input::placeholder,
textarea::placeholder {
  color: var(--muted-foreground);
  opacity: 1; /* Firefox setzt sonst zusätzlich Opacity 0.54 */
}

input[type="number"], select {
  font: inherit;
  font-size: var(--fs-small);
  padding: .4rem .85rem;
  border: var(--border-width) solid var(--border);
  background: var(--background-card);
  color: var(--primary);
  border-radius: var(--pill-radius);
  outline: none;
  -webkit-appearance: none;
  -moz-appearance: textfield;
  appearance: none;
  field-sizing: content;
  min-width: 5ch;
  max-width: 100%;
}
/* Spin-Buttons auf Number-Inputs verstecken (sind sonst optisch unruhig) */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* Selects bekommen einen eigenen Chevron rechts (das native Pfeil-Icon
   ist durch appearance: none weg). Die SVG-URL kommt aus --select-chevron
   und wird in theme.css pro Theme gesetzt — folgt damit dem aktiven Theme. */
select {
  padding-right: 2rem;
  background-image: var(--select-chevron);
  background-repeat: no-repeat;
  background-position: right .7rem center;
  background-size: .8rem;
  cursor: pointer;
}
input[type="number"]:focus, select:focus {
  outline: none;
  border-color: var(--primary);
}

/* Slider */
input[type="range"] {
  width: 100%;
  height: 10px;
  margin: 0;
  padding: 0;
  background: transparent;
  -webkit-appearance: none; appearance: none;
}
input[type="range"]::-webkit-slider-runnable-track {
  height: var(--border-width);
  background: var(--border);
  border-radius: 99px;
}
input[type="range"]::-moz-range-track {
  height: var(--border-width);
  background: var(--border);
  border-radius: 99px;
}
/* Slider-Thumbs auf Mobile (besonders iOS Safari) rendern trotz
   -webkit-appearance: none oft noch einen Default-Schatten/Halo. Explizites
   box-shadow: none ist Pflicht — sonst sieht der Thumb mobil "geprägt" aus
   während er auf Desktop flach wirkt. */
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 20px; height: 20px;
  margin-top: -9px;
  background: var(--background-card);
  border: var(--border-width) solid var(--border);
  border-radius: 50%;
  box-shadow: none;
  cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
  width: 22px; height: 22px;
  background: var(--background-card);
  border: var(--border-width) solid var(--border);
  border-radius: 50%;
  box-shadow: none;
  cursor: pointer;
}

/* Slider-Thumb-Overlay: ein echtes DOM-Element rendert das „!"-Glyph mit
   der Page-Webfont (SpaceGrotesk) — Background-SVG kann auf keine Webfont
   zugreifen. Position via CSS-Variable --thumb-pct, JS setzt den Wert
   anhand des Slider-Stands. Pointer-events: none, damit der Slider voll
   bedienbar bleibt. */
.slider-thumb-wrap {
  position: relative;
}
.slider-thumb-wrap .slider-thumb-glyph {
  position: absolute;
  top: 50%;
  /* JS schreibt --thumb-pct als Prozentwert (0..1). Wir interpolieren
     die Mitte des Thumbs zwischen halber Thumb-Breite und (Slider-Breite
     − halbe Thumb-Breite). */
  --thumb-half: 10px;
  left: calc(var(--thumb-half) + var(--thumb-pct, 0) * (100% - 2 * var(--thumb-half)));
  transform: translate(-50%, -50%);
  pointer-events: none;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 16px;
  line-height: 1;
  color: var(--primary);
}
.slider-thumb-wrap .slider-thumb-glyph.is-hidden { display: none; }

/* Info-Box innerhalb eines .field bekommt Card-Abstand zur Vor-Komponente
   (Slider/Hint), damit die Achtung-Box nicht direkt am Slider-Track klebt. */
.field > .info-box {
  margin-top: var(--space-card);
}
/* iOS Safari rendert manchmal auch einen Track-Shadow — sicherheitshalber
   auf beiden Track-Pseudos explizit ausschalten. */
input[type="range"]::-webkit-slider-runnable-track,
input[type="range"]::-moz-range-track {
  box-shadow: none;
}

/* Chips */
.chip-row {
  display: flex; flex-wrap: wrap; gap: .4rem;
}
.chip {
  font: inherit;
  font-size: var(--pill-font-size);
  font-weight: 500;
  padding: 0 var(--pill-padding-x);
  height: var(--pill-height);
  border-radius: var(--pill-radius);
  background: transparent;
  border: var(--border-width) solid var(--border);
  color: var(--primary);
  cursor: pointer;
  transition: all .12s ease;
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
}
.chip.is-active {
  background: var(--primary);
  color: var(--background-site);
}

/* Generischer Flex-Container für Eingabe-Zeilen mit gemischten Elementen
   (Chips, Inputs, Trenner). Vorher .ball-size-row — generalisiert für
   alle App-Bereiche, die so eine Zeile brauchen (Pizza-Teiglingsgröße,
   Focaccia-Backblech). */
.field-row {
  display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
  margin-top: 1rem;
}
/* Chips + Custom-Input sollen einzeln wrappen, nicht als Block. Sonst
   nimmt sich die Chip-Row auf Mobile die volle Breite und der Custom-
   Input wird in die nächste Zeile gedrängt. */
.field-row .chip-row {
  display: contents;
}
/* Inline-Trenner zwischen Inputs (z. B. „×" zwischen Länge und Breite) */
.field-row .sep {
  color: var(--muted-foreground);
  font-weight: 700;
}
/* Custom-Eingabe optisch wie ein Chip — gleiche Höhe, gleiche Form.
   Breite wächst dynamisch mit dem Inhalt (siehe field-sizing oben). */
.ball-size-row input[type="number"] {
  font-size: var(--pill-font-size);
  padding: 0 var(--pill-padding-x);
  height: var(--pill-height);
  line-height: 1;
  color: var(--primary);
}

/* Eingabefeld mit angehängter Einheit (z. B. „10 h", „230 g").
   Wrapper sieht aus wie ein einzelner Chip; das Input liegt darin und kennt
   keine eigene Border, der Wrapper trägt sie. */
.input-with-unit {
  display: inline-flex;
  align-items: stretch;          /* Input dehnt sich auf volle Pill-Höhe */
  height: var(--pill-height);
  border: var(--border-width) solid var(--border);
  border-radius: var(--pill-radius);
  background: var(--background-card);
  padding: 0 var(--pill-padding-x);
  gap: .25rem;
  font-size: var(--pill-font-size);
  line-height: 1;
  overflow: visible;             /* Cursor darf bis an die Pill-Innenseite */
}
.input-with-unit input[type="number"],
.input-with-unit input[type="text"] {
  border: none;
  background: transparent;
  /* volle Höhe statt height:auto, damit der Cursor nicht abgeschnitten wirkt */
  height: 100%;
  align-self: stretch;
  padding: 0;
  margin: 0;
  font-size: inherit;
  font-family: inherit;
  color: var(--primary);
  outline: none;
  /* Sinnvoller Default für Browser ohne field-sizing: weicht auf das HTML-
     size-Attribut aus (3 für Stunden, 5 für Gramm). field-sizing: content
     wird in modernen Browsern (Chrome 123+, Safari 18+) zusätzlich greifen. */
  width: auto;
  min-width: 0;
  max-width: 100%;
  /* explizit auf das size-Attribut hören – verhindert die Default-Breite
     von ~20 Zeichen auch in älteren Browsern. */
  flex: 0 0 auto;
}
/* Eingabe-Wrapper bekommt im Fokus die Primary-Border */
.input-with-unit:focus-within {
  border-color: var(--primary);
}
/* Unit zentriert mittig in der Pill ausrichten */
.input-with-unit .unit {
  display: inline-flex;
  align-items: center;
  color: var(--muted-foreground);
  font-weight: 500;
  pointer-events: none;
  white-space: nowrap;
}
/* Number-Inputs in modernen Browsern: dynamisches Wachstum */
@supports (field-sizing: content) {
  .input-with-unit input[type="number"],
  .input-with-unit input[type="text"] {
    field-sizing: content;
  }
}
.input-with-unit input:focus { box-shadow: none; }

/* ---------- Counter (+/- großes Display) ---------- */

.counter {
  display: flex; align-items: center; justify-content: center; gap: 0rem;
  padding: 0 0 .6rem;
}
/* Desktop: mehr Atmen nach oben — auf Mobile sitzt der Counter direkt
   unter dem Lede, darüber ist sowieso schon genug Whitespace. */
@media (min-width: 481px) {
  .counter { padding-top: 1.5rem; }
}
.counter button {
  width: 40px; height: 40px;
  border-radius: 50%;
  border: var(--border-width) solid var(--border);
  background: var(--background-card);
  color: var(--primary);
  font-size: var(--fs-body);
  font-weight: 400;
  cursor: pointer;
  transition: all .12s ease;
}
.counter button:disabled { opacity: 0.4; cursor: not-allowed; }
.counter .counter-value {
  font-size: var(--fs-h1);
  font-weight: 800;
  line-height: 1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
  min-width: 4ch;
  text-align: center;
}
.counter-caption {
  text-align: center;
  font-size: var(--fs-tiny);
  text-transform: uppercase;
  color: var(--muted-foreground);
}

/* ---------- Bedingte Sichtbarkeit ---------- */
.is-hidden { display: none !important; }

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

.wizard-nav {
  display: flex; gap: .5rem; justify-content: space-between;
  margin-top: 1rem;
  width: 100%;
}
/* Buttons: einheitliche kompakte Höhe (gleich wie .restart / .theme-btn).
   Nur 2 Höhen im System: kompakt (32px) und Card-Größe. */
.btn {
  font: inherit;
  font-weight: 600;
  font-size: var(--btn-font-size);
  padding: 0 var(--btn-padding-x);
  height: var(--btn-height);
  border-radius: var(--pill-radius);
  border: var(--border-width) solid transparent;
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
  display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
  white-space: nowrap;
  line-height: 1;
}
.btn-primary {
  background: var(--primary);
  color: var(--background-site);
  border-color: var(--primary);
}
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-secondary {
  background: var(--background-card);
  color: var(--primary);
  border-color: var(--border);
}
.btn-ghost {
  background: transparent; color: var(--muted-foreground);
  border-color: var(--border);
}

/* ----------------------------------------------------------------------
   GLOBALER HOVER-/FOCUS-STANDARD für alle interaktiven Elemente.
   Effekt: zur bestehenden 1 px-Border kommt eine ZWEITE Linie 4 px
   nach innen versetzt (Border – 4 px Gap – Inner Line). Realisiert via
   outline + negativem outline-offset:
     - outline-offset: -5px schiebt die Outline 5 px innerhalb der Border-
       Kante (wegen 1 px Outline-Width liegt die innere Linie damit auf
       5–6 px nach innen → exakte 4 px Lücke zur 1 px Border).
     - currentColor folgt der Text-/Theme-Farbe → dunkler Strich auf
       hellen Buttons, heller Strich auf dunklen CTAs.
     - Outline ignoriert das Box-Layout, daher kein Layout-Shift.
     - Outline folgt border-radius in allen evergreen Browsern, sieht
       also auch bei Pill-Buttons sauber rund aus.
     - Identisch für Maus-Hover und Tastatur-Focus → gute a11y-Sprache.
   Disabled-Buttons sind ausgenommen.
   ---------------------------------------------------------------------- */
.btn:not(:disabled):hover,
.btn:not(:disabled):focus-visible,
.chip:hover,
.chip:focus-visible,
.brand-row .restart:hover,
.brand-row .restart:focus-visible,
.mode-card:hover,
.mode-card:focus-visible,
.choice-card:hover,
.choice-card:focus-visible,
.counter button:hover,
.counter button:focus-visible {
  outline: var(--border-width) solid currentColor;
  outline-offset: -5px;
}

/* Sonderfall Theme-Switcher: der is-active-Zustand zeigt einen gefüllten
   Kreis um das SVG-Icon (background + border in --primary). Beim Hover
   soll derselbe Kreis-Look entstehen, nur als Outline statt Fill —
   d. h. die transparente Default-Border wird sichtbar. Wir verwenden
   bewusst NICHT den globalen Inner-Outline-Standard, weil dieser bei
   einem 32 × 32 px-Button proportional zu zentral wirkt und die Lücke
   zur Pille (theme-switch-padding 3 px) bricht. */
.theme-btn:hover,
.theme-btn:focus-visible {
  border-color: var(--primary);
}


.btn .arrow-r::after { content: '→'; margin-left: .25rem; }
.btn .arrow-l::before { content: '←'; margin-right: .25rem; }

/* ---------- Ergebnis ---------- */

.result-stats {
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  gap: .6rem;
  margin: 0 0 var(--space-card);
}
.result-stats .stat {
  background: var(--background-card-muted);
  border: var(--border-width) solid var(--primary);
  border-radius: var(--radius);
  padding: .8rem 1rem;
  /* Auf schmalen Viewports drücken vierstellige Zahlen (z. B. 2994 g
     Teig bei 12 Pizzen) das Grid sonst über die Card-Kante. min-width: 0
     erlaubt es dem Grid-Item, kleiner als seinen min-content zu schrumpfen
     — die Zahl skaliert dann via clamp() in .num runter. */
  min-width: 0;
  overflow: hidden;
}
/* Teig / Mehl / Wasser: nur die Zahl bekommt die kategoriale Akzentfarbe.
   Border bleibt in primary, theme-übergreifend einheitlich. */
.result-stats .stat:nth-child(1) .num { color: var(--accent-dough); }
.result-stats .stat:nth-child(2) .num { color: var(--accent-flour); }
.result-stats .stat:nth-child(3) .num { color: var(--accent-water); }

.result-stats .stat .num {
  /* Fluid-Schriftgröße: skaliert zwischen ~1.2rem auf engen Mobile-
     Viewports und 1.75rem auf Desktop. Verhindert das Überlaufen langer
     Zahlen, ohne Desktop-Lesbarkeit zu opfern. */
  font-size: clamp(1.2rem, 4.5vw, var(--fs-display));
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  display: block;
}
.result-stats .stat .lbl {
  font-size: var(--fs-micro);
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin-top: .25rem;
  white-space: nowrap;
}

/* Schmale Viewports: weniger Padding für die Stats-Karten, sonst nimmt
   das Padding selbst zu viel Platz ein und die Zahl klebt am Rand.
   Padding allseitig gleich, damit die Box optisch ausgewogen wirkt. */
@media (max-width: 480px) {
  .result-stats .stat { padding: .65rem; }
  .result-stats { gap: .4rem; }
}

.yeast-toggle {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  margin: 0 0 var(--space-card);
}
.yeast-toggle-label {
  font-size: var(--fs-small);
  color: var(--muted-foreground);
  font-weight: 500;
}
/* Inline-Erklär-Reihe direkt unter der Hefe-Zeile (siehe ui.js yeastInfoRow).
   Die Zelle selbst ist nur Wrapper — die Box-Optik trägt das innere
   .info-box (gemeinsamer Stil mit der Achtung-Box). Padding-Bottom auf
   der Wrapper-Zelle erzeugt den Abstand zur nachfolgenden tfoot-Zeile
   (Gesamt) — optisch wie zwischen normalen Tabellen-Zeilen. */
table.recipe tr.yeast-info-row > td {
  padding: 0 0 1.1rem;
  background: transparent;
  border-bottom: none;
}
/* ---------- Info-Box (Tipp & Warnung – einheitliches Pattern) ----------
   Eine gemeinsame Box-Optik für alle "Hinweis"-Container:
     - leicht abgesetzter Hintergrund (background-card-muted) — KEIN
       transparent, damit der Container vom Card-BG sichtbar abhebt
     - Border und Text in primary → folgt dem Theme automatisch
     - Caps-Label "TIPP" / "ACHTUNG" links oben als Header
     - Body-Text in primary, gleicher Rhythmus wie sonst
   Eingesetzt für: yeast-info-row in der Rezept-Tabelle, renderWarnings
   im Result-Step und der Timeline-Vergangenheits-Warnung. */
.info-box {
  background: var(--background-card-muted);
  color: var(--primary);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: .9rem 1.1rem;
  font-size: var(--fs-tiny);
  line-height: 1.55;
  text-align: left;
}
.info-box-title {
  margin: 0 0 .55rem;
  font-size: var(--fs-small);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
}
.info-box p { margin: 0 0 .55rem; }
.info-box p:last-child { margin-bottom: 0; }
.info-box strong { color: var(--primary); }
.info-box + .info-box { margin-top: .5rem; }

/* Trennlinie zwischen Hefe-Zeile und der yeast-info-row weg, damit die
   Box visuell an die Hefe-Reihe andockt. Browser ohne :has() bekommen
   weiter eine sichtbare Linie — akzeptabel, weil rein cosmetic. */
table.recipe tbody tr:has(+ tr.yeast-info-row) td {
  border-bottom: none;
}

table.recipe {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-small);
  margin: 0 0 .5rem;
  /* Fixed-Layout: Spalten werden NICHT mehr nach Inhalt skaliert. Damit
     bleibt die Position der Pills beim Hefe-Toggle (Frisch ↔ Trocken)
     stabil — der Wechsel "0,18 g" → "0,55 g" verschiebt sonst die ganze
     Spalte. Erste Spalte bekommt mehr Raum, weil "Hefe (trocken)" länger
     ist als die anderen Zutat-Labels. */
  table-layout: fixed;
}
table.recipe th, table.recipe td {
  padding: .55rem .5rem;
  /* ALLE Werte-Spalten rechtsbündig: dadurch laufen die rechten Pill-
     Kanten auf einer Linie und der Abstand zwischen allen Spalten ist
     optisch identisch — Vorteig→Hauptteig genau so groß wie
     Hauptteig→Gesamt. Die Label-Spalte (erste) wird unten explizit
     wieder linksbündig gesetzt. */
  text-align: right;
  border-bottom: var(--border-width) solid var(--border);
  vertical-align: middle;
}
/* Erste Spalte: kompakt, weil das längste Label jetzt nur noch
   "Olivenöl" ist (statt "Hefe (trocken)"). 24 % reichen — die übrigen
   Werte-Spalten gewinnen damit Platz für vierstellige Zahlen wie
   "1.177 g", die rechtsbündig sauber in die Pill passen müssen. */
table.recipe th:first-child {
  width: 24%;
}
table.recipe th:first-child, table.recipe td:first-child {
  text-align: left;
  font-weight: 500;
  padding-left: 0;          /* Label bis an die linke Tabellenkante */
}
table.recipe th:last-child, table.recipe td:last-child {
  padding-right: 0;         /* Gesamt-Pill bis an die rechte Tabellenkante */
}
table.recipe thead th {
  font-size: var(--fs-micro);
  color: var(--muted-foreground);
  text-transform: uppercase;
  border-bottom: var(--border-width) solid var(--border);
}
table.recipe tfoot td {
  font-weight: 700;
  border-top: var(--border-width) solid var(--border);
  border-bottom: none;
}
/* Letzte tbody-Zeile bei Tabellen OHNE tfoot (z. B. Sole-Tabelle):
   - keine Border-Bottom → sonst Doppellinie mit Card-Border darunter
   - padding-bottom: 0 → Pill→Card-Border-Abstand symmetrisch zum rechten
     Rand (td:last-child hat padding-right: 0, also rundum nur Card-Padding)
   :not(:has(tfoot)) schließt die Pizza-Rezept-Tabelle aus — dort liegt
   im tbody als letzte Reihe die yeast-info-row (TIPP-Block), die ihre
   eigenen 1.1rem padding-bottom braucht, damit sie nicht am Gesamt-Row
   klebt. */
table.recipe:not(:has(tfoot)) tbody tr:last-child td {
  border-bottom: 0;
  padding-bottom: 0;
}

/* Sole-Tabelle: nur 3 statische Labels, zweite Spalte hat nur eine Menge.
   Fixed-Layout mit 24%-Label-Spalte (gedacht für die Pizza-Rezept-Tabelle
   mit Vorteig/Hauptteig/Gesamt) würde "Wasser (lauwarm)" umbrechen, obwohl
   rechts viel Platz frei ist. Auto-Layout + width-Override + nowrap auf
   den Label-Cells erzwingen einzeilige Darstellung. */
table.recipe#sole-table { table-layout: auto; }
table.recipe#sole-table th:first-child { width: auto; }
table.recipe#sole-table td:first-child { white-space: nowrap; }

/* Mengen-Pills in der Rezept-Tabelle */
table.recipe .amount {
  display: inline-block;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  background: var(--primary);
  color: var(--background-card);
  padding: .15rem .5rem;
  border-radius: 6px;
  font-size: var(--fs-small);
  white-space: nowrap;
}

.flour-box {
  background: var(--background-card);
  color: var(--primary);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-card);
  margin: var(--space-card) 0 0;
}
.flour-box h3 { color: var(--muted-foreground); margin: 0 0 .55rem; font-size: var(--fs-small); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; }
.flour-box .w { font-size: var(--fs-h3); font-weight: 800; line-height: 1.1; color: var(--primary); }
.flour-box ul { margin: var(--space-card) 0 0; padding: 0; list-style: none; }
.flour-box ul li.brand-section-label {
  font-size: var(--fs-tiny);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted-foreground);
  font-weight: 700;
  margin: .55rem 0 .35rem;
}
.flour-box ul li.brand-section-label:first-child { margin-top: 0; }
.flour-box ul li.brand-section-label .brand-section-pct {
  margin-left: .4rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  opacity: .7;
}
.flour-box ul li.brand {
  background: var(--background-card-muted);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  padding: .55rem .75rem;
  margin-bottom: .35rem;
  font-size: var(--fs-small);
}
.flour-box .brand-name {
  font-weight: 700;
  font-size: var(--fs-body);
  color: var(--primary);
}
.flour-box .brand-specs {
  font-family: var(--font-mono);
  font-size: var(--fs-tiny);
  color: var(--muted-foreground);
  margin-top: .15rem;
}
.flour-box .brand-meta {
  font-size: var(--fs-tiny);
  color: var(--muted-foreground);
  margin-top: .1rem;
  font-style: italic;
}
.flour-box .note { font-size: var(--fs-tiny); color: var(--muted-foreground); margin-top: var(--space-card); line-height: 1.4; }

/* Anleitung – Phasen-Cards */
.instructions {
  display: flex;
  flex-direction: column;
  gap: var(--space-card);
}

.phase {
  background: var(--background-card-muted);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-card);
}

/* Phase-Header: Titel-Zeile mit nummeriertem Kreis. Padding-Bottom und
   Margin-Bottom sind beide auf --space-card gezogen, damit der Abstand
   Card-Top → Heading-Mitte = Heading-Bottom → Trennlinie und Trennlinie
   → erste Step-Zeile alle gleich groß sind. Gap matcht das Step-List-
   Text-Padding, damit Header-Title und Step-Texte exakt auf derselben
   Vertikale beginnen. */
.phase-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0 0 var(--space-card);
  padding-bottom: var(--space-card);
  border-bottom: var(--border-width) solid var(--border);
}

/* Größe für ALLE nummerierten Kreise (Phase-Header + Steps) gemeinsam.
   Ändert man diesen Wert, wachsen beide synchron. */
.phase, .phase-steps { --num-circle-size: 32px; }

.phase-num {
  flex-shrink: 0;
  box-sizing: border-box;
  width: var(--num-circle-size);
  height: var(--num-circle-size);
  min-width: var(--num-circle-size);
  min-height: var(--num-circle-size);
  border-radius: 50%;
  background: var(--background-site);
  color: var(--primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: var(--fs-body);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  border: var(--border-width) solid var(--primary);
  padding: 0;
}

.phase-title {
  margin: 0;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: var(--fs-body);
  line-height: 1.3;
  color: var(--primary);
}

.phase-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: phasestep;
}

.phase-steps li {
  position: relative;
  counter-increment: phasestep;
  /* padding-left = Kreis-Größe + 1rem (= phase-header gap), damit der
     Step-Text auf exakt derselben Vertikalen sitzt wie der Phase-Title. */
  padding: .15rem 0 .15rem calc(var(--num-circle-size) + 1rem);
  margin: 0 0 var(--space-card);
  font-size: var(--fs-small);
  line-height: 1.5;
  min-height: var(--num-circle-size);
}
.phase-steps li:last-child { margin-bottom: 0; }

/* Mengen-Hervorhebungen in Anleitung und Timeline (Mehl, Wasser, Hefe,
   Stunden, Temperaturen, Ratios) bekommen den echten Bold-Schnitt.
   Gilt für alle <strong> innerhalb #instructions und #timeline — sowohl
   in den nummerierten Step-Listen als auch in den begleitenden Info-Boxen
   (z. B. Coil-Folds-Hinweis, Backen im Backrohr). */
#instructions strong,
#timeline strong {
  font-family: 'SpaceGroteskBold', 'SpaceGrotesk';
}
.phase-steps li strong {
  color: var(--primary);
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.phase-steps li::before {
  content: counter(phasestep);
  position: absolute;
  left: 0;
  top: 0;
  box-sizing: border-box;
  width: var(--num-circle-size);
  height: var(--num-circle-size);
  border-radius: 50%;
  background: transparent;
  border: var(--border-width) solid var(--primary);
  color: var(--primary);
  font-weight: 600;
  font-size: var(--fs-body);
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
  padding: 0;
}
/* Hint-Block, der MITTEN in der Step-Liste eingefügt wird (z. B. Coil-
   Folds-Holding-Phase nach dem Anspring-Schritt). Nutzt die <li>-Tag
   für sauberes Inline-Layout, aber ohne Counter und ohne Step-Padding. */
.phase-steps li.phase-step-hint {
  counter-increment: none;
  padding: 0;
  margin: 0 0 var(--space-card);
  list-style: none;
  min-height: 0;
}
.phase-steps li.phase-step-hint::before { display: none; }

/* Print: Cards nicht trennen */
@media print {
  .phase { background: white; page-break-inside: avoid; border-color: #ccc; }
  .phase-num { background: black; color: white; }
  .phase-steps li::before { background: white; border-color: #999; color: black; }
}

/* Timeline */
.target-time-row {
  display: flex; gap: .6rem; align-items: center; flex-wrap: wrap;
  margin-bottom: 1rem;
}
.target-time-row label { font-weight: 600; font-size: var(--fs-small); }

.timeline {
  position: relative;
  margin: .25rem 0;
  padding-left: 1.5rem;
}
.timeline-event {
  position: relative;
  padding: .35rem 0 .65rem .15rem;
}

/* Punkt = Outline-Kreis in Primary, Hintergrund deckt die Linie hinter
   ihm ab, sodass der Strich optisch zwischen den Kreisen verläuft.
   box-sizing: border-box, damit die 1px-Border nicht die Außengröße
   verschiebt — Kreis-Mitte sitzt so exakt auf der Linien-Mittelachse.
   z-index sorgt dafür, dass der Kreis ÜBER der ::after-Linie liegt. */
.timeline-event::before {
  content: '';
  position: absolute;
  left: -1.5rem;
  top: .65rem;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--background-site);
  border: var(--border-width) solid var(--primary);
  box-sizing: border-box;
  z-index: 1;
}

/* Verbindungslinie zum nächsten Event. Beginnt am Kreis-Bottom, ragt
   genau bis zur Mitte des nächsten Kreises (= 100% Item-Höhe + .65rem
   + 5.5px vom Item-Top), wo der dortige Outline-Kreis sie abdeckt.
   Damit endet die sichtbare Linie optisch am Kreisrand — kein Überstand
   beim ersten Event oben (kein ::after davor) und kein Überstand beim
   letzten Event unten (display:none). */
.timeline-event::after {
  content: '';
  position: absolute;
  left: calc(-1.5rem + 5px);
  top: calc(.65rem + 11px);
  height: calc(100% - 5.5px);
  width: var(--border-width);
  background: var(--border);
}
.timeline-event:last-child::after {
  display: none;
}

/* Target-Event (= Backen): gefüllter Kreis in Secondary, damit der Ziel-
   Marker sich klar von den Outline-Kreisen der Vorbereitungs-Schritte
   abhebt. */
.timeline-event.is-target::before {
  background: var(--secondary);
  border-color: var(--secondary);
}
.timeline-event.is-past { opacity: .45; }
.timeline-event.is-past .time::after { content: ' · vergangen'; font-size: var(--fs-tiny); color: var(--destructive); }
.timeline-event .time {
  font-weight: 700;
  font-size: var(--fs-body);
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.timeline-event .label { font-weight: 600; margin-top: .05rem; font-size: var(--fs-small); }
.timeline-event .detail { color: var(--muted-foreground); font-size: var(--fs-small); line-height: 1.4; margin-top: .15rem; }

/* Action-Row auf Ergebnis-Seite */
.share-row {
  display: flex; gap: .5rem; flex-wrap: wrap; align-items: center;
  margin: var(--space-card) 0 0;
}
.copy-feedback {
  font-size: var(--fs-small);
  color: var(--primary);
  font-weight: 600;
}

/* Footer */
.app-footer {
  margin-top: 2rem;
  text-align: center;
  color: var(--muted-foreground);
  font-size: var(--fs-tiny);
}
.app-footer .footer-link {
  color: var(--primary);
  text-decoration: none;
  transition: opacity .15s ease;
}
.app-footer .footer-link:hover,
.app-footer .footer-link:focus-visible {
  opacity: .7;
  text-decoration: underline;
}
.app-footer .footer-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Warnings-Container hält Card-Rhythmus zur darüberliegenden Auswahl,
   aber nur wenn tatsächlich eine Box gerendert wurde — leerer Container
   soll keinen Phantom-Abstand erzeugen. */
#warnings:not(:empty) { margin-top: var(--space-card); }

/* ---------- Focaccia-spezifisch (alles andere nutzt Pizza-Klassen) ---------- */
/* Optional-Step in der Anleitung (z. B. Topping-Varianten): ungeordnete
   Liste mit Bullets statt durchnummerierter Steps. Restliche .phase-*
   Styles kommen aus dem Pizza-Anleitungs-CSS. */
.phase-intro {
  margin: 0 0 .65rem;
  color: var(--muted-foreground);
  font-size: var(--fs-small);
  line-height: 1.5;
}
.phase-options {
  list-style: disc;
  padding-left: 1.2rem;
  margin: 0;
}
.phase-options li { margin-bottom: .5rem; line-height: 1.5; }
.phase-options li:last-child { margin-bottom: 0; }

/* ---------- Print ---------- */
@media print {
  body { background: white; }
  .app { max-width: 100%; padding: 0; }
  .brand-row, .stepper, .step-label-row, .wizard-nav, .share-row, .target-time-row, .restart, .app-footer { display: none !important; }
  .step { display: block !important; page-break-inside: avoid; }
  .step:not(#step-result) { display: none !important; }
  .card { border: 1px solid #ccc; }
  .flour-box { background: white; color: black; border: 1px solid #999; }
  .timeline-event::before { background: white; border-color: black; }
  .timeline-event.is-target::before { background: black; border-color: black; }
  .info-box { background: white; border: 1px solid #999; color: black; }
  .info-box-title { color: black; }
}
